From 2374cb20cfe6d129e10b35a49be96bce273b97fb Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 21 Mar 2015 21:12:59 +0100 Subject: LICENSE 3.1: Cleanup whitespace and line wrapping (80) allowing comparison w/ LICENSE 3.2 --- LICENSE.txt | 367 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 187 insertions(+), 180 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index fcee98b..fa6abd1 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -35,142 +35,149 @@ not appear in the actual license. Full-length Legal Copy: -1. Subject to the terms and conditions of this License Agreement (the "License"), -Oculus VR, Inc. ("Oculus VR") hereby grants to you a perpetual, worldwide, -non-exclusive, no-charge, royalty-free, sublicenseable copyright license to use, -reproduce, redistribute (subject to restrictions below), modify, and improve the -software contained in this Oculus VR Rift Software Development Kit ("RIFT SDK"), -including, but not limited to, the samples, headers, LibOVR headers, and LibOVR -source. This license is subject to the following terms and conditions: - -1.1. This license includes the non-exclusive license and right to use (i) the RIFT -SDK to make applications, content, games and demos (collectively and generally -referred to as “Developer Content”) that run on the Oculus VR approved mobile hardware -and software products (“Oculus Approved Rift Products”) and which may incorporate -the RIFT SDK in whole or in part in binary or object code; and (ii) to use the -RIFT SDK to create derivative works of the RIFT SDK itself ("RIFT SDK Derivatives"), -whether in source, binary, or object form, in whole or in part, including third -party software unless otherwise noted. - -1.2. RIFT SDK Derivatives are further defined as source, binary or object code +1. Subject to the terms and conditions of this License Agreement (the +"License"), Oculus VR, Inc. ("Oculus VR") hereby grants to you a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, sublicenseable copyright +license to use, reproduce, redistribute (subject to restrictions below), modify, +and improve the software contained in this Oculus VR Rift Software Development +Kit ("RIFT SDK"), including, but not limited to, the samples, headers, LibOVR +headers, and LibOVR source. This license is subject to the following terms and +conditions: + +1.1. This license includes the non-exclusive license and right to use (i) the +RIFT SDK to make applications, content, games and demos (collectively and +generally referred to as "Developer Content") that run on the Oculus VR approved +mobile hardware and software products ("Oculus Approved Rift Products") and +which may incorporate the RIFT SDK in whole or in part in binary or object code; +and (ii) to use the RIFT SDK to create derivative works of the RIFT SDK itself +("RIFT SDK Derivatives"), whether in source, binary, or object form, in whole or +in part, including third party software unless otherwise noted. + +1.2. RIFT SDK Derivatives are further defined as source, binary or object code derived exclusively from the RIFT SDK by you; provided, however, that RIFT SDK -Derivatives do not include the Developer Content (engines, utilities, applications, -content, games or demos) which may be developed using the RIFT SDK. By way of example -a mobile application or game or demo that is developed using the RIFT SDK would not -be a RIFT SDK Derivative , nor would a utility or tool set in a pre-existing game -engine that is adapted to work with the RIFT SDK be a RIFT SDK Derivative. -By way of example, but not limitation, a RIFT SDK Derivative is or would be: either (i) -an adaptation of a utility or piece of code from the RIFT SDK to improve efficiency; -or (ii) an addition of code or improvement to the RIFT SDK that adds functionality. - -1.3 For the sake of clarification when you use the RIFT SDK (including RIFT SDK -Derivatives) in or with Developer Content, you retain all rights to your Developer -Content, and you have no obligations to share or license Developer Content (including -your source and object code) to Oculus VR or any third parties; provided, however, -Oculus VR retains all rights to the RIFT SDK and the RIFT SDK Derivatives that may -be incorporated into your Developer Content. - -1.4 You agree to and you will use the Flash Screen Warning and the Health and -Safety Warnings (collectively the “Oculus Warnings”) and the Oculus VR health and -safety protocols found in the Oculus Best Practices Guide (“Oculus H&S Protocols”), -and your use of the Oculus Warnings and the Oculus end user license agreement -(“Oculus EULA”) with your Developer Content as provided for in the Oculus Developer -Center, all of which can be found at the following link: +Derivatives do not include the Developer Content (engines, utilities, +applications, content, games or demos) which may be developed using the RIFT +SDK. By way of example a mobile application or game or demo that is developed +using the RIFT SDK would not be a RIFT SDK Derivative , nor would a utility or +tool set in a pre-existing game engine that is adapted to work with the RIFT SDK +be a RIFT SDK Derivative. By way of example, but not limitation, a RIFT SDK +Derivative is or would be: either (i) an adaptation of a utility or piece of +code from the RIFT SDK to improve efficiency; or (ii) an addition of code or +improvement to the RIFT SDK that adds functionality. + +1.3 For the sake of clarification when you use the RIFT SDK (including RIFT SDK +Derivatives) in or with Developer Content, you retain all rights to your +Developer Content, and you have no obligations to share or license Developer +Content (including your source and object code) to Oculus VR or any third +parties; provided, however, Oculus VR retains all rights to the RIFT SDK and the +RIFT SDK Derivatives that may be incorporated into your Developer Content. + +1.4 You agree to and you will use the Flash Screen Warning and the Health and +Safety Warnings (collectively the "Oculus Warnings") and the Oculus VR health +and safety protocols found in the Oculus Best Practices Guide ("Oculus H&S +Protocols"), and your use of the Oculus Warnings and the Oculus end user license +agreement ("Oculus EULA") with your Developer Content as provided for in the +Oculus Developer Center, all of which can be found at the following link: https://developer.oculusvr.com/?action=doc. -2. You, the recipient and user of the RIFT SDK, hereby agree and accept that that -Oculus VR shall own all right, title and interest to the intellectual property -rights, including, but limited to copyright, trademark and patent rights, to any -RIFT SDK Derivatives that you may create, and you hereby assign any and all such -rights to such RIFT SDK Derivatives to Oculus VR, subject to the following. +2. You, the recipient and user of the RIFT SDK, hereby agree and accept that +that Oculus VR shall own all right, title and interest to the intellectual +property rights, including, but limited to copyright, trademark and patent +rights, to any RIFT SDK Derivatives that you may create, and you hereby assign +any and all such rights to such RIFT SDK Derivatives to Oculus VR, subject to +the following. -2.1 We hereby grant to you the a fully paid up, no-charge, royalty-free, -world-wide, in perpetuity, non-exclusive right and license back to use these RIFT -SDK Derivatives solely in conjunction with the RIFT SDK (or any components of the -RIFT SDK) and/or Developer Content on Oculus Rift Products as set forth herein. +2.1 We hereby grant to you the a fully paid up, no-charge, royalty-free, +world-wide, in perpetuity, non-exclusive right and license back to use these +RIFT SDK Derivatives solely in conjunction with the RIFT SDK (or any components +of the RIFT SDK) and/or Developer Content on Oculus Rift Products as set forth +herein. -2.2 Furthermore, for the sake of clarification, Oculus VR and its assignees and +2.2 Furthermore, for the sake of clarification, Oculus VR and its assignees and licensees shall be free to use such RIFT SDK Derivatives without any approval from you and without compensation or attribution to you. -2.3 You also agree upon Oculus VR's request to provide the source and binary code -of any RIFT SDK Derivatives to Oculus VR. FAILURE TO COMPLY WITH THIS REQUEST -IS THE BASIS FOR AUTOMATIC TERMINATION OF THIS LICENSE BY OCULUS VR. +2.3 You also agree upon Oculus VR's request to provide the source and binary +code of any RIFT SDK Derivatives to Oculus VR. FAILURE TO COMPLY WITH THIS +REQUEST IS THE BASIS FOR AUTOMATIC TERMINATION OF THIS LICENSE BY OCULUS VR. -3. Subject to the terms and conditions of this License, your license to redistribute -and sublicense the RIFT SDK and RIFT SDK Derivatives is also expressly made -subject to the following conditions: +3. Subject to the terms and conditions of this License, your license to +redistribute and sublicense the RIFT SDK and RIFT SDK Derivatives is also +expressly made subject to the following conditions: 3.1. You may sublicense and redistribute the source, binary, or object code of -the RIFT SDK in whole or in part by itself for no charge or as part of a for charge -piece of Developer Content; provided, however, you may only license, sublicense -or redistribute the source, binary or object code of LibOVR in whole, and you may -not license, sublicense or redistribute any portion or element of LibOVR separately -or in part (in either source, binary or object form). If you license, sublicense -or redistribute RIFT SDK Derivatives in and of themselves (not as a part of a -piece of Developer Content) then you may only do that solely with and in conjunction -with either the RIFT SDK or LibOVR. The RIFT SDK (including, but not limited to -LibOVR), any RIFT SDK Derivatives, and any Developer Content may only be used -with Oculus Approved Rift Products and may not be used, licensed, or sublicensed -to interface with mobile software or hardware or other commercial headsets, -mobile tablets or phones that are not authorized and approved by Oculus VR; - -3.2. You must include with all such redistributed or sublicensed RIFT SDK -or RIFT SDK Derivatives code the following copyright notice: -"Copyright © 2014 Oculus VR, Inc. All rights reserved," and include the -list of conditions contained in this Section 3, including the full text of -the disclaimer in Section 3.6 below; +the RIFT SDK in whole or in part by itself for no charge or as part of a for +charge piece of Developer Content; provided, however, you may only license, +sublicense or redistribute the source, binary or object code of LibOVR in whole, +and you may not license, sublicense or redistribute any portion or element of +LibOVR separately or in part (in either source, binary or object form). If you +license, sublicense or redistribute RIFT SDK Derivatives in and of themselves +(not as a part of a piece of Developer Content) then you may only do that solely +with and in conjunction with either the RIFT SDK or LibOVR. The RIFT SDK +(including, but not limited to LibOVR), any RIFT SDK Derivatives, and any +Developer Content may only be used with Oculus Approved Rift Products and may +not be used, licensed, or sublicensed to interface with mobile software or +hardware or other commercial headsets, mobile tablets or phones that are not +authorized and approved by Oculus VR; + +3.2. You must include with all such redistributed or sublicensed RIFT SDK or +RIFT SDK Derivatives code the following copyright notice: "Copyright © 2014 +Oculus VR, Inc. All rights reserved," and include the list of conditions +contained in this Section 3, including the full text of the disclaimer in +Section 3.6 below; 3.3. Neither the name of Oculus VR, Inc. nor the names of Oculus VR, Inc.'s -contributors, licensors, employees, or contractors, may be used to endorse or promote -products derived from this RIFT SDK without specific prior written permission -of Oculus VR, Inc.; +contributors, licensors, employees, or contractors, may be used to endorse or +promote products derived from this RIFT SDK without specific prior written +permission of Oculus VR, Inc.; 3.4. You must give any other recipients of the RIFT SDK or any elements thereof, -including LibOVR or RIFT SDK Derivatives, a copy of this License as such recipients, -licensees or sublicensees may only use the RIFT SDK or any RIFT SDK Derivatives -or any elements thereof subject to the terms of this Licence and such recipients, -licensees or sublicensees agreement and acceptance of this License with Oculus VR -(which will convey all rights to the recipients’ or licensees’ or sublicensees’ -RIFT SDK Derivatives to Oculus VR), and you must cause any modified files to -carry prominent notices stating that you changed the files; +including LibOVR or RIFT SDK Derivatives, a copy of this License as such +recipients, licensees or sublicensees may only use the RIFT SDK or any RIFT SDK +Derivatives or any elements thereof subject to the terms of this Licence and +such recipients, licensees or sublicensees agreement and acceptance of this +License with Oculus VR (which will convey all rights to the recipients' or +licensees' or sublicensees' RIFT SDK Derivatives to Oculus VR), and you must +cause any modified files to carry prominent notices stating that you changed the +files; 3.5. If the RIFT SDK or a specific element thereof such as LibOVR includes a -"LICENSE" text file as part of its distribution (the “License Notice”), then -any RIFT SDK Derivatives that you distribute with the RIFT SDK in whole or in -part must include a readable copy of such attribution notices as are contained -within the applicable License Notice file (excluding those notices that do not -pertain to any part of the RIFT SDK Derivatives), in at least one of the following +"LICENSE" text file as part of its distribution (the "License Notice"), then any +RIFT SDK Derivatives that you distribute with the RIFT SDK in whole or in part +must include a readable copy of such attribution notices as are contained within +the applicable License Notice file (excluding those notices that do not pertain +to any part of the RIFT SDK Derivatives), in at least one of the following places: within a License Notice text file distributed as part of the RIFT SDK -Derivatives; within the source form or documentation, if provided along with -the RIFT SDK Derivatives; or, within a display generated by the RIFT SDK Derivatives, -if and wherever such third-party notices normally appear. You must also include -in the License Notice file for all RIFT SDK Derivatives a copy of all notices -(including any product liability or health and safety notices). The contents -of the License Notice file are for informational purposes only and do not modify -the License. You may add your own attribution notices within RIFT SDK Derivatives -that you distribute, alongside or as an addendum to the License Notice text from -the RIFT SDK or any part thereof, provided that such additional attribution notices -cannot be construed as modifying the License. - -3.6. THIS RIFT SDK AND ANY COMPONENT THEREOF IS PROVIDED BY OCULUS VR AND -ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OCULUS VR AS THE -COPYRIGHT OWNER OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS RIFT -SDK OR THE RIFT SDK DERIVATIVES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Derivatives; within the source form or documentation, if provided along with the +RIFT SDK Derivatives; or, within a display generated by the RIFT SDK +Derivatives, if and wherever such third-party notices normally appear. You must +also include in the License Notice file for all RIFT SDK Derivatives a copy of +all notices (including any product liability or health and safety notices). The +contents of the License Notice file are for informational purposes only and do +not modify the License. You may add your own attribution notices within RIFT SDK +Derivatives that you distribute, alongside or as an addendum to the License +Notice text from the RIFT SDK or any part thereof, provided that such additional +attribution notices cannot be construed as modifying the License. + +3.6. THIS RIFT SDK AND ANY COMPONENT THEREOF IS PROVIDED BY OCULUS VR AND ITS +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OCULUS VR AS THE COPYRIGHT +OWNER OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS RIFT SDK OR THE RIFT SDK DERIVATIVES, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4. This License does not grant permission to use the trade names, trademarks, service marks, or product names of Oculus VR, except as required for reasonable and customary use in describing the origin of the RIFT SDK, LibOVR, or any -element thereof, and reproducing the content of the License Notice file. -5. In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as +element thereof, and reproducing the content of the License Notice file. + +5. In no event and under no legal theory, whether in tort (including +negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall Oculus VR or any contributor be liable to you or your licensees or sublicensees for damages, including any direct, indirect, special, incidental, or consequential @@ -181,84 +188,84 @@ stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if you or such contributor has been advised of the possibility of such damages. -6. Your acceptance of the terms and conditions of this License in and of -itself and for all Developer Content created as of March 1, 2014, may be -evidenced by any of the following: your usage of the RIFT SDK or any element -thereof, acceptance of the click-through agreement, or opening the packaging -of the CD-ROM containing the RIFT SDK or any element thereof, including LibOVR. +6. Your acceptance of the terms and conditions of this License in and of itself +and for all Developer Content created as of March 1, 2014, may be evidenced by +any of the following: your usage of the RIFT SDK or any element thereof, +acceptance of the click-through agreement, or opening the packaging of the +CD-ROM containing the RIFT SDK or any element thereof, including LibOVR. + As this License is updated for future releases of the RIFT SDK and/or LibOVR, you agree to abide by and meet all requirements of future updates of this -License for those future RIFT SDK releases as evidenced by the same usage of -the RIFT SDK or any element thereof and the future updates of this License -will apply for that future Developer Content that may developed for or with -that future RIFT SDK or any element thereof (i.e., you cannot sidestep out -of the requirements of future updates of the License by developing against -an older release of the RIFT SDK or License). - -7. Oculus VR reserves the right to terminate this License and all your -rights hereunder in the event you materially breach this License and fail -to cure such breach within ten (10) business days after notice of breach -from Oculus VR. - -8. Furthermore, Oculus VR also reserves the right to cancel or terminate -this License for any of the following reasons upon notice to you, subject -to the appeal process set forth in Section 14 for a wrongful termination: - - a) Intellectual property infringement by you with Developer Content - or RIFT SDK Derivatives created by you that is used with or by the - RIFT SDK or any part thereof, or any of the RIFT SDK Derivatives; - - b) Developer Content that violates or infringes upon applicable law; - - c) Health and safety issues associated with your Developer Content; - - d) Failure to comply with or use properly the Oculus Warnings, - Oculus H&S Protocols, or Oculus EULA; - - e) Use of the RIFT SDK, RIFT SDK Derivatives or LibOVR with a - commercial product other than an Oculus Approved Product; and - - f) Failure to provide required notices or deliver source code - and/or binary of RIFT SDK Derivatives as set forth above. - +License for those future RIFT SDK releases as evidenced by the same usage of the +RIFT SDK or any element thereof and the future updates of this License will +apply for that future Developer Content that may developed for or with that +future RIFT SDK or any element thereof (i.e., you cannot sidestep out of the +requirements of future updates of the License by developing against an older +release of the RIFT SDK or License). + +7. Oculus VR reserves the right to terminate this License and all your rights +hereunder in the event you materially breach this License and fail to cure such +breach within ten (10) business days after notice of breach from Oculus VR. + +8. Furthermore, Oculus VR also reserves the right to cancel or terminate this +License for any of the following reasons upon notice to you, subject to the +appeal process set forth in Section 14 for a wrongful termination: + + a) Intellectual property infringement by you with Developer Content + or RIFT SDK Derivatives created by you that is used with or by the + RIFT SDK or any part thereof, or any of the RIFT SDK Derivatives; + + b) Developer Content that violates or infringes upon applicable law; + + c) Health and safety issues associated with your Developer Content; + + d) Failure to comply with or use properly the Oculus Warnings, + Oculus H&S Protocols, or Oculus EULA; + + e) Use of the RIFT SDK, RIFT SDK Derivatives or LibOVR with a + commercial product other than an Oculus Approved Product; and + + f) Failure to provide required notices or deliver source code + and/or binary of RIFT SDK Derivatives as set forth above. + If you believe that you have been wrongfully terminated under this Section 8 -with respect to material breach or with respect to these above conditions, -you have the right to appeal the termination of this License under Section 14. +with respect to material breach or with respect to these above conditions, you +have the right to appeal the termination of this License under Section 14. -9. This License may be amended by Oculus VR on a prospective basis, and your -usage of the License after such amendments or changes signifies your consent -to and acceptance of any such amendments or changes on a going forward basis. +9. This License may be amended by Oculus VR on a prospective basis, and your +usage of the License after such amendments or changes signifies your consent to +and acceptance of any such amendments or changes on a going forward basis. -10. In the event any provision of this License is determined to be invalid, +10. In the event any provision of this License is determined to be invalid, prohibited or unenforceable by a court or other body of competent jurisdiction, this License shall be construed as if such invalid, prohibited or unenforceable provision has been more narrowly drawn so as not to be invalid, prohibited or -unenforceable. +unenforceable. -11. You may not assign any rights or obligations under this License without -the advance written consent of Oculus VR, which may be withheld in its sole -discretion. Oculus VR may assign its rights or obligations under this License -in its sole discretion. +11. You may not assign any rights or obligations under this License without the +advance written consent of Oculus VR, which may be withheld in its sole +discretion. Oculus VR may assign its rights or obligations under this License in +its sole discretion. -12. Failure of either party at any time to enforce any of the provisions of -this License will not be construed as a waiver of such provisions or in any way +12. Failure of either party at any time to enforce any of the provisions of this +License will not be construed as a waiver of such provisions or in any way affect the validity of this License or parts thereof. -13. Your remedies under this License shall be limited to the right to collect +13. Your remedies under this License shall be limited to the right to collect money damages, if any, and you hereby waive your right to injunctive or other equitable relief. -14. This License shall be governed by the laws of the State of California, -without giving effect to choice of law principles. All disputes relating to -this License shall be resolved by binding non-appearance-based arbitration -before a neutral arbitrator in Orange County, California. If your License -has been terminated hereunder by Oculus, you may appeal your termination -through this arbitration process on an expedited basis with an arbitration -within thirty days of your giving Oculus VR notice of the appeal. The -arbitration shall be conducted in accordance with the rules and procedures -of JAMS then in effect, and the judgment of the arbitrator shall be final -and capable of entry in any court of competent jurisdiction. You agree -to submit to the personal jurisdiction of the courts located within Orange -County, California in connection with any entrance of an arbitrator’s judgment -or decision or any dispute with respect to the arbitration process or procedure -or Oculus VR’s exercise of its equitable rights or remedies. +14. This License shall be governed by the laws of the State of California, +without giving effect to choice of law principles. All disputes relating to this +License shall be resolved by binding non-appearance-based arbitration before a +neutral arbitrator in Orange County, California. If your License has been +terminated hereunder by Oculus, you may appeal your termination through this +arbitration process on an expedited basis with an arbitration within thirty days +of your giving Oculus VR notice of the appeal. The arbitration shall be +conducted in accordance with the rules and procedures of JAMS then in effect, +and the judgment of the arbitrator shall be final and capable of entry in any +court of competent jurisdiction. You agree to submit to the personal +jurisdiction of the courts located within Orange County, California in +connection with any entrance of an arbitrator's judgment or decision or any +dispute with respect to the arbitration process or procedure or Oculus VR's +exercise of its equitable rights or remedies. -- cgit v1.2.3 From 05bb4364bfd9930fb1902efec86446ef035ee07a Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 21 Mar 2015 18:25:33 +0100 Subject: Remove Remove Firmware - Not required for binding --- Firmware/RiftTrackerFirmware_v0.18rc.ovrf | Bin 51233 -> 0 bytes Firmware/readme.txt | 19 ------------------- 2 files changed, 19 deletions(-) delete mode 100644 Firmware/RiftTrackerFirmware_v0.18rc.ovrf delete mode 100644 Firmware/readme.txt diff --git a/Firmware/RiftTrackerFirmware_v0.18rc.ovrf b/Firmware/RiftTrackerFirmware_v0.18rc.ovrf deleted file mode 100644 index 090ce41..0000000 Binary files a/Firmware/RiftTrackerFirmware_v0.18rc.ovrf and /dev/null differ diff --git a/Firmware/readme.txt b/Firmware/readme.txt deleted file mode 100644 index 5a61029..0000000 --- a/Firmware/readme.txt +++ /dev/null @@ -1,19 +0,0 @@ -Firmware packages for Oculus products are stored in this folder. -Use the OculusConfigUtil to load them and update your products. - -Tracker DK Firmware Version History -=================================== - -0.18 - 2013-10-03 -* Resolve a calibration issue that could result in additional - drift in certain conditions. -* Resolve a calibration issue that resulted in additional drift - after fast motions. - -0.17 - 2013-04-24 -* Fix an issue where the Tracker can fail to initialize with - Logitech software running. - -0.16 - 2013-03-13 -* Release firmware for the Oculus Rift DK. - -- cgit v1.2.3 From e490c3c7f7bb5461cfa78a214827aa534fb43a3e Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 21 Mar 2015 21:19:34 +0100 Subject: Bump OculusVR RIFT SDK to 0.4.4 --- LICENSE.txt | 29 +- LibOVR/90-oculus.rules | 4 +- LibOVR/Include/OVR.h | 27 +- LibOVR/Include/OVRVersion.h | 33 - LibOVR/Include/OVR_Kernel.h | 42 + LibOVR/Include/OVR_Version.h | 35 + LibOVR/Makefile | 330 +- .../Mac/Xcode/LibOVR.xcodeproj/project.pbxproj | 490 +- LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj | 231 +- .../Projects/Win32/VS2010/LibOVR.vcxproj.filters | 447 +- LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj | 233 +- .../Projects/Win32/VS2012/LibOVR.vcxproj.filters | 413 +- LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj | 226 +- .../Projects/Win32/VS2013/LibOVR.vcxproj.filters | 405 +- LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp | 92 +- LibOVR/Src/CAPI/CAPI_DistortionRenderer.h | 83 +- LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp | 435 +- LibOVR/Src/CAPI/CAPI_FrameTimeManager.h | 123 +- LibOVR/Src/CAPI/CAPI_GlobalState.cpp | 142 - LibOVR/Src/CAPI/CAPI_GlobalState.h | 84 - LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp | 108 +- LibOVR/Src/CAPI/CAPI_HMDRenderState.h | 61 +- LibOVR/Src/CAPI/CAPI_HMDState.cpp | 1032 +-- LibOVR/Src/CAPI/CAPI_HMDState.h | 215 +- LibOVR/Src/CAPI/CAPI_HSWDisplay.cpp | 482 ++ LibOVR/Src/CAPI/CAPI_HSWDisplay.h | 249 + LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp | 316 + LibOVR/Src/CAPI/CAPI_LatencyStatistics.h | 178 + .../CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp | 6 +- .../Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h | 8 +- LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp | 35 + LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h | 41 + .../CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp | 6 +- .../Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h | 8 +- LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp | 35 + LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h | 41 + .../CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp | 1012 ++- .../Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h | 78 +- 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 | 151 +- LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h | 107 +- .../CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp | 279 - .../Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h | 139 - LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp | 254 - LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.csh | 389 + 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 | 135 + .../CAPI/D3D1X/Shaders/DistortionChroma_ps_refl.h | 9 + .../Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.h | 101 + .../Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.vsh | 53 + .../CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h | 9 + .../D3D1X/Shaders/DistortionTimewarpChroma_vs.h | 214 + .../D3D1X/Shaders/DistortionTimewarpChroma_vs.vsh | 66 + .../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.psh | 34 + 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.psh | 29 + 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.vsh | 31 + LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h | 9 + .../Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.h | 77 + .../CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.psh | 39 + .../D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h | 8 + .../Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.h | 82 + .../CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.vsh | 39 + .../D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h | 9 + LibOVR/Src/CAPI/D3D1X/Shaders/bin2header.exe | Bin 0 -> 612864 bytes .../CAPI/D3D1X/Shaders/genComputeShaderHeader.bat | 15 + .../CAPI/D3D1X/Shaders/genPixelShaderHeader.bat | 15 + .../CAPI/D3D1X/Shaders/genVertexShaderHeader.bat | 15 + .../Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp | 409 + .../Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h | 142 + LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp | 430 ++ LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h | 82 + LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp | 273 + 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 | 729 +- LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h | 92 +- LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h | 180 +- LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp | 500 ++ LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h | 77 + LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp | 427 +- LibOVR/Src/CAPI/GL/CAPI_GL_Util.h | 266 +- LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h | 84 - LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh | 12 - LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h | 1 - LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h | 106 - LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.vsh | 24 - LibOVR/Src/CAPI/Shaders/DistortionChroma_vs_refl.h | 9 - .../Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h | 219 - .../CAPI/Shaders/DistortionTimewarpChroma_vs.vsh | 40 - .../Shaders/DistortionTimewarpChroma_vs_refl.h | 11 - LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h | 169 - LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.vsh | 36 - .../Src/CAPI/Shaders/DistortionTimewarp_vs_refl.h | 11 - LibOVR/Src/CAPI/Shaders/Distortion_ps.h | 66 - LibOVR/Src/CAPI/Shaders/Distortion_ps.psh | 9 - LibOVR/Src/CAPI/Shaders/Distortion_ps_refl.h | 1 - LibOVR/Src/CAPI/Shaders/Distortion_vs.h | 84 - LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh | 14 - LibOVR/Src/CAPI/Shaders/Distortion_vs_refl.h | 9 - LibOVR/Src/CAPI/Shaders/ShaderReflector.exe | Bin 75776 -> 0 bytes LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h | 51 - LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.psh | 6 - LibOVR/Src/CAPI/Shaders/SimpleQuad_ps_refl.h | 8 - LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h | 64 - LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.vsh | 8 - LibOVR/Src/CAPI/Shaders/SimpleQuad_vs_refl.h | 9 - LibOVR/Src/CAPI/Shaders/bin2header.exe | Bin 612864 -> 0 bytes LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat | 15 - LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat | 15 - LibOVR/Src/CAPI/Textures/healthAndSafety.tga.h | 3363 +++++++++ LibOVR/Src/Displays/OVR_Display.cpp | 36 + LibOVR/Src/Displays/OVR_Display.h | 203 + LibOVR/Src/Displays/OVR_Linux_Display.cpp | 494 ++ LibOVR/Src/Displays/OVR_Linux_Display.h | 133 + LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp | 649 ++ LibOVR/Src/Displays/OVR_Linux_SDKWindow.h | 147 + LibOVR/Src/Displays/OVR_OSX_Display.cpp | 372 + LibOVR/Src/Displays/OVR_OSX_Display.h | 139 + 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 | 1323 ++++ LibOVR/Src/Displays/OVR_Win32_Display.h | 182 + LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h | 429 ++ LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp | 79 + LibOVR/Src/Displays/OVR_Win32_FocusReader.h | 81 + LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp | 974 +++ LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp | 234 + LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h | 79 + LibOVR/Src/Displays/OVR_Win32_ShimVersion.h | 47 + LibOVR/Src/Kernel/OVR_Alg.cpp | 10 +- LibOVR/Src/Kernel/OVR_Alg.h | 376 +- LibOVR/Src/Kernel/OVR_Allocator.cpp | 74 +- LibOVR/Src/Kernel/OVR_Allocator.h | 61 +- LibOVR/Src/Kernel/OVR_Array.h | 168 +- LibOVR/Src/Kernel/OVR_Atomic.cpp | 51 +- LibOVR/Src/Kernel/OVR_Atomic.h | 149 +- LibOVR/Src/Kernel/OVR_CRC32.cpp | 85 + LibOVR/Src/Kernel/OVR_CRC32.h | 45 + LibOVR/Src/Kernel/OVR_Color.h | 21 +- LibOVR/Src/Kernel/OVR_Compiler.h | 1524 ++++ LibOVR/Src/Kernel/OVR_ContainerAllocator.h | 84 +- 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 | 180 +- LibOVR/Src/Kernel/OVR_File.cpp | 51 +- LibOVR/Src/Kernel/OVR_File.h | 173 +- LibOVR/Src/Kernel/OVR_FileFILE.cpp | 88 +- LibOVR/Src/Kernel/OVR_Hash.h | 217 +- LibOVR/Src/Kernel/OVR_KeyCodes.h | 8 +- LibOVR/Src/Kernel/OVR_List.h | 12 +- LibOVR/Src/Kernel/OVR_Lockless.cpp | 18 +- LibOVR/Src/Kernel/OVR_Lockless.h | 38 +- LibOVR/Src/Kernel/OVR_Log.cpp | 316 +- LibOVR/Src/Kernel/OVR_Log.h | 53 +- LibOVR/Src/Kernel/OVR_Math.cpp | 49 +- LibOVR/Src/Kernel/OVR_Math.h | 601 +- LibOVR/Src/Kernel/OVR_Nullptr.h | 150 + LibOVR/Src/Kernel/OVR_Observer.h | 457 ++ LibOVR/Src/Kernel/OVR_RefCount.cpp | 6 +- LibOVR/Src/Kernel/OVR_RefCount.h | 7 +- LibOVR/Src/Kernel/OVR_SharedMemory.cpp | 691 ++ LibOVR/Src/Kernel/OVR_SharedMemory.h | 240 + LibOVR/Src/Kernel/OVR_Std.cpp | 187 +- LibOVR/Src/Kernel/OVR_Std.h | 266 +- LibOVR/Src/Kernel/OVR_String.cpp | 261 +- LibOVR/Src/Kernel/OVR_String.h | 185 +- LibOVR/Src/Kernel/OVR_StringHash.h | 6 +- LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp | 47 +- LibOVR/Src/Kernel/OVR_String_PathUtil.cpp | 14 +- LibOVR/Src/Kernel/OVR_SysFile.cpp | 28 +- LibOVR/Src/Kernel/OVR_SysFile.h | 12 +- LibOVR/Src/Kernel/OVR_System.cpp | 86 +- LibOVR/Src/Kernel/OVR_System.h | 112 +- LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp | 401 + LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h | 318 + LibOVR/Src/Kernel/OVR_Threads.h | 77 +- LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp | 211 +- LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp | 247 +- LibOVR/Src/Kernel/OVR_Timer.cpp | 492 +- LibOVR/Src/Kernel/OVR_Timer.h | 35 +- LibOVR/Src/Kernel/OVR_Types.h | 691 +- LibOVR/Src/Kernel/OVR_UTF8Util.cpp | 62 +- LibOVR/Src/Kernel/OVR_UTF8Util.h | 30 +- LibOVR/Src/Kernel/OVR_mach_exc_OSX.c | 2955 ++++++++ LibOVR/Src/Kernel/OVR_mach_exc_OSX.h | 277 + LibOVR/Src/Net/OVR_BitStream.cpp | 1151 +++ LibOVR/Src/Net/OVR_BitStream.h | 1744 +++++ LibOVR/Src/Net/OVR_MessageIDTypes.h | 39 + LibOVR/Src/Net/OVR_NetworkPlugin.cpp | 70 + LibOVR/Src/Net/OVR_NetworkPlugin.h | 60 + LibOVR/Src/Net/OVR_NetworkTypes.h | 42 + LibOVR/Src/Net/OVR_PacketizedTCPSocket.cpp | 215 + LibOVR/Src/Net/OVR_PacketizedTCPSocket.h | 87 + LibOVR/Src/Net/OVR_RPC1.cpp | 270 + LibOVR/Src/Net/OVR_RPC1.h | 105 + LibOVR/Src/Net/OVR_Session.cpp | 736 ++ LibOVR/Src/Net/OVR_Session.h | 513 ++ LibOVR/Src/Net/OVR_Socket.cpp | 94 + LibOVR/Src/Net/OVR_Socket.h | 242 + LibOVR/Src/Net/OVR_Unix_Socket.cpp | 600 ++ LibOVR/Src/Net/OVR_Unix_Socket.h | 152 + LibOVR/Src/Net/OVR_Win32_Socket.cpp | 608 ++ LibOVR/Src/Net/OVR_Win32_Socket.h | 151 + LibOVR/Src/OVR_CAPI.cpp | 974 ++- LibOVR/Src/OVR_CAPI.h | 1078 +-- LibOVR/Src/OVR_CAPI_D3D.h | 71 +- LibOVR/Src/OVR_CAPI_GL.h | 63 +- LibOVR/Src/OVR_CAPI_Keys.h | 56 + LibOVR/Src/OVR_Common_HMDDevice.cpp | 384 - LibOVR/Src/OVR_Device.h | 1135 --- LibOVR/Src/OVR_DeviceConstants.h | 142 - LibOVR/Src/OVR_DeviceHandle.cpp | 185 - LibOVR/Src/OVR_DeviceHandle.h | 108 - LibOVR/Src/OVR_DeviceImpl.cpp | 794 -- LibOVR/Src/OVR_DeviceImpl.h | 428 -- LibOVR/Src/OVR_DeviceMessages.h | 273 - LibOVR/Src/OVR_HIDDevice.h | 154 - LibOVR/Src/OVR_HIDDeviceBase.h | 51 - LibOVR/Src/OVR_HIDDeviceImpl.h | 201 - LibOVR/Src/OVR_JSON.cpp | 274 +- LibOVR/Src/OVR_JSON.h | 23 +- LibOVR/Src/OVR_LatencyTestImpl.cpp | 773 -- LibOVR/Src/OVR_LatencyTestImpl.h | 144 - LibOVR/Src/OVR_Linux_DeviceManager.cpp | 331 - LibOVR/Src/OVR_Linux_DeviceManager.h | 122 - LibOVR/Src/OVR_Linux_HIDDevice.cpp | 819 -- LibOVR/Src/OVR_Linux_HIDDevice.h | 135 - LibOVR/Src/OVR_Linux_HMDDevice.cpp | 291 - LibOVR/Src/OVR_Linux_HMDDevice.h | 154 - LibOVR/Src/OVR_Linux_SensorDevice.cpp | 57 - LibOVR/Src/OVR_OSX_DeviceManager.cpp | 360 - LibOVR/Src/OVR_OSX_DeviceManager.h | 128 - LibOVR/Src/OVR_OSX_HIDDevice.cpp | 924 --- LibOVR/Src/OVR_OSX_HIDDevice.h | 160 - LibOVR/Src/OVR_OSX_HMDDevice.cpp | 264 - LibOVR/Src/OVR_OSX_HMDDevice.h | 153 - LibOVR/Src/OVR_OSX_SensorDevice.cpp | 58 - LibOVR/Src/OVR_Profile.cpp | 448 +- LibOVR/Src/OVR_Profile.h | 129 +- LibOVR/Src/OVR_Recording.cpp | 38 - LibOVR/Src/OVR_Recording.h | 83 - LibOVR/Src/OVR_Sensor2Impl.cpp | 1124 --- LibOVR/Src/OVR_Sensor2Impl.h | 153 - LibOVR/Src/OVR_Sensor2ImplUtil.h | 676 -- LibOVR/Src/OVR_SensorCalibration.cpp | 354 - LibOVR/Src/OVR_SensorCalibration.h | 82 - LibOVR/Src/OVR_SensorFilter.cpp | 99 - LibOVR/Src/OVR_SensorFilter.h | 307 - LibOVR/Src/OVR_SensorFusion.cpp | 904 --- LibOVR/Src/OVR_SensorFusion.h | 582 -- LibOVR/Src/OVR_SensorFusionDebug.h | 82 - LibOVR/Src/OVR_SensorImpl.cpp | 1165 --- LibOVR/Src/OVR_SensorImpl.h | 316 - LibOVR/Src/OVR_SensorImpl_Common.cpp | 245 - LibOVR/Src/OVR_SensorImpl_Common.h | 150 - LibOVR/Src/OVR_SensorTimeFilter.cpp | 385 - LibOVR/Src/OVR_SensorTimeFilter.h | 226 - LibOVR/Src/OVR_SerialFormat.cpp | 451 ++ LibOVR/Src/OVR_SerialFormat.h | 128 + LibOVR/Src/OVR_Stereo.cpp | 329 +- LibOVR/Src/OVR_Stereo.h | 255 +- LibOVR/Src/OVR_ThreadCommandQueue.cpp | 380 - LibOVR/Src/OVR_ThreadCommandQueue.h | 319 - LibOVR/Src/OVR_Win32_DeviceManager.cpp | 434 -- LibOVR/Src/OVR_Win32_DeviceManager.h | 157 - LibOVR/Src/OVR_Win32_DeviceStatus.cpp | 367 - LibOVR/Src/OVR_Win32_DeviceStatus.h | 112 - LibOVR/Src/OVR_Win32_HIDDevice.cpp | 649 -- LibOVR/Src/OVR_Win32_HIDDevice.h | 205 - LibOVR/Src/OVR_Win32_HMDDevice.cpp | 363 - LibOVR/Src/OVR_Win32_HMDDevice.h | 153 - LibOVR/Src/OVR_Win32_SensorDevice.cpp | 60 - LibOVR/Src/OVR_Win32_SensorDevice.h | 35 - LibOVR/Src/Sensors/OVR_DeviceConstants.h | 184 + LibOVR/Src/Service/Service_NetClient.cpp | 882 +++ LibOVR/Src/Service/Service_NetClient.h | 149 + LibOVR/Src/Service/Service_NetSessionCommon.cpp | 343 + LibOVR/Src/Service/Service_NetSessionCommon.h | 142 + 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_ImageWindow.cpp | 265 +- LibOVR/Src/Util/Util_ImageWindow.h | 26 +- LibOVR/Src/Util/Util_Interface.cpp | 8 +- LibOVR/Src/Util/Util_Interface.h | 9 +- LibOVR/Src/Util/Util_LatencyTest.cpp | 570 -- LibOVR/Src/Util/Util_LatencyTest.h | 173 - LibOVR/Src/Util/Util_LatencyTest2.cpp | 191 - LibOVR/Src/Util/Util_LatencyTest2.h | 238 - LibOVR/Src/Util/Util_LatencyTest2Reader.cpp | 118 + LibOVR/Src/Util/Util_LatencyTest2Reader.h | 63 + LibOVR/Src/Util/Util_LatencyTest2State.h | 96 + LibOVR/Src/Util/Util_Render_Stereo.cpp | 446 +- LibOVR/Src/Util/Util_Render_Stereo.h | 64 +- 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 + 321 files changed, 66199 insertions(+), 28498 deletions(-) delete mode 100644 LibOVR/Include/OVRVersion.h create mode 100644 LibOVR/Include/OVR_Kernel.h create mode 100644 LibOVR/Include/OVR_Version.h delete mode 100644 LibOVR/Src/CAPI/CAPI_GlobalState.cpp delete mode 100644 LibOVR/Src/CAPI/CAPI_GlobalState.h create mode 100644 LibOVR/Src/CAPI/CAPI_HSWDisplay.cpp create mode 100644 LibOVR/Src/CAPI/CAPI_HSWDisplay.h create mode 100644 LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp create mode 100644 LibOVR/Src/CAPI/CAPI_LatencyStatistics.h create mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp create mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h create mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp create mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h create mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp create mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.csh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.psh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.vsh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.vsh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.vsh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.psh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.vsh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.psh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.vsh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.psh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.vsh create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/bin2header.exe create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/genComputeShaderHeader.bat create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/genPixelShaderHeader.bat create mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/genVertexShaderHeader.bat create mode 100644 LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp create mode 100644 LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h create mode 100644 LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp create mode 100644 LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h create mode 100644 LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp create mode 100644 LibOVR/Src/CAPI/GL/CAPI_GLE.cpp create mode 100644 LibOVR/Src/CAPI/GL/CAPI_GLE.h create mode 100644 LibOVR/Src/CAPI/GL/CAPI_GLE_GL.h create mode 100644 LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp create mode 100644 LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.vsh delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionChroma_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.vsh delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.vsh delete mode 100644 LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/Shaders/Distortion_ps.h delete mode 100644 LibOVR/Src/CAPI/Shaders/Distortion_ps.psh delete mode 100644 LibOVR/Src/CAPI/Shaders/Distortion_ps_refl.h delete mode 100644 LibOVR/Src/CAPI/Shaders/Distortion_vs.h delete mode 100644 LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh delete mode 100644 LibOVR/Src/CAPI/Shaders/Distortion_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/Shaders/ShaderReflector.exe delete mode 100644 LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h delete mode 100644 LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.psh delete mode 100644 LibOVR/Src/CAPI/Shaders/SimpleQuad_ps_refl.h delete mode 100644 LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h delete mode 100644 LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.vsh delete mode 100644 LibOVR/Src/CAPI/Shaders/SimpleQuad_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/Shaders/bin2header.exe delete mode 100644 LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat delete mode 100644 LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat create mode 100644 LibOVR/Src/CAPI/Textures/healthAndSafety.tga.h create mode 100644 LibOVR/Src/Displays/OVR_Display.cpp create mode 100644 LibOVR/Src/Displays/OVR_Display.h create mode 100644 LibOVR/Src/Displays/OVR_Linux_Display.cpp create mode 100644 LibOVR/Src/Displays/OVR_Linux_Display.h create mode 100644 LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp create mode 100644 LibOVR/Src/Displays/OVR_Linux_SDKWindow.h create mode 100644 LibOVR/Src/Displays/OVR_OSX_Display.cpp create mode 100644 LibOVR/Src/Displays/OVR_OSX_Display.h create mode 100644 LibOVR/Src/Displays/OVR_OSX_FocusObserver.h create mode 100644 LibOVR/Src/Displays/OVR_OSX_FocusObserver.mm create mode 100644 LibOVR/Src/Displays/OVR_OSX_FocusReader.h create mode 100644 LibOVR/Src/Displays/OVR_OSX_FocusReader.mm create mode 100644 LibOVR/Src/Displays/OVR_Win32_Display.cpp create mode 100644 LibOVR/Src/Displays/OVR_Win32_Display.h create mode 100644 LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h create mode 100644 LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp create mode 100644 LibOVR/Src/Displays/OVR_Win32_FocusReader.h create mode 100644 LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp create mode 100644 LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp create mode 100644 LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h create mode 100644 LibOVR/Src/Displays/OVR_Win32_ShimVersion.h create mode 100644 LibOVR/Src/Kernel/OVR_CRC32.cpp create mode 100644 LibOVR/Src/Kernel/OVR_CRC32.h create mode 100644 LibOVR/Src/Kernel/OVR_Compiler.h create mode 100644 LibOVR/Src/Kernel/OVR_DebugHelp.cpp create mode 100644 LibOVR/Src/Kernel/OVR_DebugHelp.h create mode 100644 LibOVR/Src/Kernel/OVR_Delegates.h create mode 100644 LibOVR/Src/Kernel/OVR_Nullptr.h create mode 100644 LibOVR/Src/Kernel/OVR_Observer.h create mode 100644 LibOVR/Src/Kernel/OVR_SharedMemory.cpp create mode 100644 LibOVR/Src/Kernel/OVR_SharedMemory.h create mode 100644 LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp create mode 100644 LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h create mode 100644 LibOVR/Src/Kernel/OVR_mach_exc_OSX.c create mode 100644 LibOVR/Src/Kernel/OVR_mach_exc_OSX.h create mode 100644 LibOVR/Src/Net/OVR_BitStream.cpp create mode 100644 LibOVR/Src/Net/OVR_BitStream.h create mode 100644 LibOVR/Src/Net/OVR_MessageIDTypes.h create mode 100644 LibOVR/Src/Net/OVR_NetworkPlugin.cpp create mode 100644 LibOVR/Src/Net/OVR_NetworkPlugin.h create mode 100644 LibOVR/Src/Net/OVR_NetworkTypes.h create mode 100644 LibOVR/Src/Net/OVR_PacketizedTCPSocket.cpp create mode 100644 LibOVR/Src/Net/OVR_PacketizedTCPSocket.h create mode 100644 LibOVR/Src/Net/OVR_RPC1.cpp create mode 100644 LibOVR/Src/Net/OVR_RPC1.h create mode 100644 LibOVR/Src/Net/OVR_Session.cpp create mode 100644 LibOVR/Src/Net/OVR_Session.h create mode 100644 LibOVR/Src/Net/OVR_Socket.cpp create mode 100644 LibOVR/Src/Net/OVR_Socket.h create mode 100644 LibOVR/Src/Net/OVR_Unix_Socket.cpp create mode 100644 LibOVR/Src/Net/OVR_Unix_Socket.h create mode 100644 LibOVR/Src/Net/OVR_Win32_Socket.cpp create mode 100644 LibOVR/Src/Net/OVR_Win32_Socket.h create mode 100644 LibOVR/Src/OVR_CAPI_Keys.h delete mode 100644 LibOVR/Src/OVR_Common_HMDDevice.cpp delete mode 100644 LibOVR/Src/OVR_Device.h delete mode 100644 LibOVR/Src/OVR_DeviceConstants.h delete mode 100644 LibOVR/Src/OVR_DeviceHandle.cpp delete mode 100644 LibOVR/Src/OVR_DeviceHandle.h delete mode 100644 LibOVR/Src/OVR_DeviceImpl.cpp delete mode 100644 LibOVR/Src/OVR_DeviceImpl.h delete mode 100644 LibOVR/Src/OVR_DeviceMessages.h delete mode 100644 LibOVR/Src/OVR_HIDDevice.h delete mode 100644 LibOVR/Src/OVR_HIDDeviceBase.h delete mode 100644 LibOVR/Src/OVR_HIDDeviceImpl.h delete mode 100644 LibOVR/Src/OVR_LatencyTestImpl.cpp delete mode 100644 LibOVR/Src/OVR_LatencyTestImpl.h delete mode 100644 LibOVR/Src/OVR_Linux_DeviceManager.cpp delete mode 100644 LibOVR/Src/OVR_Linux_DeviceManager.h delete mode 100644 LibOVR/Src/OVR_Linux_HIDDevice.cpp delete mode 100644 LibOVR/Src/OVR_Linux_HIDDevice.h delete mode 100644 LibOVR/Src/OVR_Linux_HMDDevice.cpp delete mode 100644 LibOVR/Src/OVR_Linux_HMDDevice.h delete mode 100644 LibOVR/Src/OVR_Linux_SensorDevice.cpp delete mode 100644 LibOVR/Src/OVR_OSX_DeviceManager.cpp delete mode 100644 LibOVR/Src/OVR_OSX_DeviceManager.h delete mode 100644 LibOVR/Src/OVR_OSX_HIDDevice.cpp delete mode 100644 LibOVR/Src/OVR_OSX_HIDDevice.h delete mode 100644 LibOVR/Src/OVR_OSX_HMDDevice.cpp delete mode 100644 LibOVR/Src/OVR_OSX_HMDDevice.h delete mode 100644 LibOVR/Src/OVR_OSX_SensorDevice.cpp delete mode 100644 LibOVR/Src/OVR_Recording.cpp delete mode 100644 LibOVR/Src/OVR_Recording.h delete mode 100644 LibOVR/Src/OVR_Sensor2Impl.cpp delete mode 100644 LibOVR/Src/OVR_Sensor2Impl.h delete mode 100644 LibOVR/Src/OVR_Sensor2ImplUtil.h delete mode 100644 LibOVR/Src/OVR_SensorCalibration.cpp delete mode 100644 LibOVR/Src/OVR_SensorCalibration.h delete mode 100644 LibOVR/Src/OVR_SensorFilter.cpp delete mode 100644 LibOVR/Src/OVR_SensorFilter.h delete mode 100644 LibOVR/Src/OVR_SensorFusion.cpp delete mode 100644 LibOVR/Src/OVR_SensorFusion.h delete mode 100644 LibOVR/Src/OVR_SensorFusionDebug.h delete mode 100644 LibOVR/Src/OVR_SensorImpl.cpp delete mode 100644 LibOVR/Src/OVR_SensorImpl.h delete mode 100644 LibOVR/Src/OVR_SensorImpl_Common.cpp delete mode 100644 LibOVR/Src/OVR_SensorImpl_Common.h delete mode 100644 LibOVR/Src/OVR_SensorTimeFilter.cpp delete mode 100644 LibOVR/Src/OVR_SensorTimeFilter.h create mode 100644 LibOVR/Src/OVR_SerialFormat.cpp create mode 100644 LibOVR/Src/OVR_SerialFormat.h delete mode 100644 LibOVR/Src/OVR_ThreadCommandQueue.cpp delete mode 100644 LibOVR/Src/OVR_ThreadCommandQueue.h delete mode 100644 LibOVR/Src/OVR_Win32_DeviceManager.cpp delete mode 100644 LibOVR/Src/OVR_Win32_DeviceManager.h delete mode 100644 LibOVR/Src/OVR_Win32_DeviceStatus.cpp delete mode 100644 LibOVR/Src/OVR_Win32_DeviceStatus.h delete mode 100644 LibOVR/Src/OVR_Win32_HIDDevice.cpp delete mode 100644 LibOVR/Src/OVR_Win32_HIDDevice.h delete mode 100644 LibOVR/Src/OVR_Win32_HMDDevice.cpp delete mode 100644 LibOVR/Src/OVR_Win32_HMDDevice.h delete mode 100644 LibOVR/Src/OVR_Win32_SensorDevice.cpp delete mode 100644 LibOVR/Src/OVR_Win32_SensorDevice.h create mode 100644 LibOVR/Src/Sensors/OVR_DeviceConstants.h create mode 100644 LibOVR/Src/Service/Service_NetClient.cpp create mode 100644 LibOVR/Src/Service/Service_NetClient.h create mode 100644 LibOVR/Src/Service/Service_NetSessionCommon.cpp create mode 100644 LibOVR/Src/Service/Service_NetSessionCommon.h create mode 100644 LibOVR/Src/Tracking/Tracking_PoseState.h create mode 100644 LibOVR/Src/Tracking/Tracking_SensorState.h create mode 100644 LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp create mode 100644 LibOVR/Src/Tracking/Tracking_SensorStateReader.h create mode 100644 LibOVR/Src/Util/GUIConsole.h delete mode 100644 LibOVR/Src/Util/Util_LatencyTest.cpp delete mode 100644 LibOVR/Src/Util/Util_LatencyTest.h delete mode 100644 LibOVR/Src/Util/Util_LatencyTest2.cpp delete mode 100644 LibOVR/Src/Util/Util_LatencyTest2.h create mode 100644 LibOVR/Src/Util/Util_LatencyTest2Reader.cpp create mode 100644 LibOVR/Src/Util/Util_LatencyTest2Reader.h create mode 100644 LibOVR/Src/Util/Util_LatencyTest2State.h create mode 100644 LibOVR/Src/Util/Util_SystemGUI.cpp create mode 100644 LibOVR/Src/Util/Util_SystemGUI.h create mode 100644 LibOVR/Src/Util/Util_SystemGUI_OSX.mm create mode 100644 LibOVR/Src/Util/Util_SystemInfo.cpp create mode 100644 LibOVR/Src/Util/Util_SystemInfo.h create mode 100644 LibOVR/Src/Util/Util_SystemInfo_OSX.mm diff --git a/LICENSE.txt b/LICENSE.txt index fa6abd1..21de967 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,10 +1,8 @@ -Oculus VR Rift SDK Software License +Oculus VR, LLC Software Development Kit License Agreement -Oculus VR, Inc. Software Development Kit License Agreement +Copyright © 2014 Oculus VR, LLC All rights reserved. -Copyright © 2014 Oculus VR, Inc. All rights reserved. - -The text of this may be found at: http://www.oculusvr.com/licenses/LICENSE-3.1 +The text of this may be found at: https://developer.oculus.com/licenses/license-3.2/ Human-Readable Summary*: @@ -16,7 +14,7 @@ form with your applications/software. With the Following Restrictions: You can only distribute or re-distribute the source code to LibOVR in -whole, not in part. +whole, not in part. Modifications to the Oculus VR Rift SDK in source or binary form must be shared with Oculus VR. @@ -36,7 +34,7 @@ not appear in the actual license. Full-length Legal Copy: 1. Subject to the terms and conditions of this License Agreement (the -"License"), Oculus VR, Inc. ("Oculus VR") hereby grants to you a perpetual, +"License"), Oculus VR, LLC ("Oculus VR") hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, royalty-free, sublicenseable copyright license to use, reproduce, redistribute (subject to restrictions below), modify, and improve the software contained in this Oculus VR Rift Software Development @@ -78,7 +76,7 @@ and safety protocols found in the Oculus Best Practices Guide ("Oculus H&S Protocols"), and your use of the Oculus Warnings and the Oculus end user license agreement ("Oculus EULA") with your Developer Content as provided for in the Oculus Developer Center, all of which can be found at the following link: -https://developer.oculusvr.com/?action=doc. +https://developer.oculus.com/documentation/. 2. You, the recipient and user of the RIFT SDK, hereby agree and accept that that Oculus VR shall own all right, title and interest to the intellectual @@ -122,19 +120,19 @@ authorized and approved by Oculus VR; 3.2. You must include with all such redistributed or sublicensed RIFT SDK or RIFT SDK Derivatives code the following copyright notice: "Copyright © 2014 -Oculus VR, Inc. All rights reserved," and include the list of conditions -contained in this Section 3, including the full text of the disclaimer in +Oculus VR, LLC. All rights reserved," and include the list of conditions +contained in this Section3, including the full text of the disclaimer in Section 3.6 below; -3.3. Neither the name of Oculus VR, Inc. nor the names of Oculus VR, Inc.'s +3.3. Neither the name of Oculus VR, LLC nor the names of Oculus VR, LLC's contributors, licensors, employees, or contractors, may be used to endorse or promote products derived from this RIFT SDK without specific prior written -permission of Oculus VR, Inc.; +permission of Oculus VR, LLC; 3.4. You must give any other recipients of the RIFT SDK or any elements thereof, including LibOVR or RIFT SDK Derivatives, a copy of this License as such recipients, licensees or sublicensees may only use the RIFT SDK or any RIFT SDK -Derivatives or any elements thereof subject to the terms of this Licence and +Derivatives or any elements thereof subject to the terms of this License and such recipients, licensees or sublicensees agreement and acceptance of this License with Oculus VR (which will convey all rights to the recipients' or licensees' or sublicensees' RIFT SDK Derivatives to Oculus VR), and you must @@ -148,7 +146,7 @@ must include a readable copy of such attribution notices as are contained within the applicable License Notice file (excluding those notices that do not pertain to any part of the RIFT SDK Derivatives), in at least one of the following places: within a License Notice text file distributed as part of the RIFT SDK -Derivatives; within the source form or documentation, if provided along with the +Derivatives; within the source form documentation, if provided along with the RIFT SDK Derivatives; or, within a display generated by the RIFT SDK Derivatives, if and wherever such third-party notices normally appear. You must also include in the License Notice file for all RIFT SDK Derivatives a copy of @@ -174,7 +172,8 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4. This License does not grant permission to use the trade names, trademarks, service marks, or product names of Oculus VR, except as required for reasonable and customary use in describing the origin of the RIFT SDK, LibOVR, or any -element thereof, and reproducing the content of the License Notice file. +element thereof, and reproducing the content of the License Notice file. Oculus +VR reserves all rights not expressly granted to you under this License. 5. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as diff --git a/LibOVR/90-oculus.rules b/LibOVR/90-oculus.rules index ada04c1..56bccdb 100644 --- a/LibOVR/90-oculus.rules +++ b/LibOVR/90-oculus.rules @@ -1,2 +1,2 @@ -# Oculus HID Sensor naming and permissioning -KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2833", MODE="0666" +# Oculus HID Sensor naming and permissioning +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2833", MODE="0666" diff --git a/LibOVR/Include/OVR.h b/LibOVR/Include/OVR.h index 6b5d416..b82e452 100644 --- a/LibOVR/Include/OVR.h +++ b/LibOVR/Include/OVR.h @@ -1,19 +1,19 @@ /************************************************************************************ Filename : OVR.h -Content : This contains references to all OVR-specific headers in Src folder. - Should be generated automatically based on PublicHeader tags. +Content : The main public interface to Oculus for C++ Developers. + Includes C API and helper classes. -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -26,22 +26,11 @@ limitations under the License. #ifndef OVR_h #define OVR_h +#include "OVR_Version.h" -#include "../Src/Kernel/OVR_Allocator.h" -#include "../Src/Kernel/OVR_Log.h" #include "../Src/Kernel/OVR_Math.h" -#include "../Src/Kernel/OVR_System.h" -#include "../Src/Kernel/OVR_Types.h" -#include "../Src/OVR_Device.h" -#include "../Src/OVR_DeviceConstants.h" -#include "../Src/OVR_DeviceHandle.h" -#include "../Src/OVR_DeviceMessages.h" -#include "../Src/OVR_SensorFusion.h" -#include "../Src/OVR_Stereo.h" -#include "../Src/OVR_Profile.h" -#include "../Src/Util/Util_LatencyTest.h" -#include "../Src/Util/Util_Render_Stereo.h" -#include "../Src/Util/Util_Interface.h" + +#include "../Src/OVR_CAPI.h" #endif diff --git a/LibOVR/Include/OVRVersion.h b/LibOVR/Include/OVRVersion.h deleted file mode 100644 index 14f83e6..0000000 --- a/LibOVR/Include/OVRVersion.h +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************************ - -Filename : OVRVersion.h -Content : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_VERSION_H -#define _OVR_VERSION_H - -#define OVR_MAJOR_VERSION 0 -#define OVR_MINOR_VERSION 3 -#define OVR_BUILD_VERSION 2 -#define OVR_VERSION_STRING "0.3.2" - -#endif diff --git a/LibOVR/Include/OVR_Kernel.h b/LibOVR/Include/OVR_Kernel.h new file mode 100644 index 0000000..1a8a903 --- /dev/null +++ b/LibOVR/Include/OVR_Kernel.h @@ -0,0 +1,42 @@ +/************************************************************************************ + +Filename : OVRKernel.h +Content : This contains references to all OVR Kernel headers in Src folder. + Should be generated automatically based on PublicHeader tags. + +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_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" + +#endif + diff --git a/LibOVR/Include/OVR_Version.h b/LibOVR/Include/OVR_Version.h new file mode 100644 index 0000000..2ba20bc --- /dev/null +++ b/LibOVR/Include/OVR_Version.h @@ -0,0 +1,35 @@ +/************************************************************************************ + +Filename : OVRVersion.h +Content : + +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_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 +#endif diff --git a/LibOVR/Makefile b/LibOVR/Makefile index f939cec..fba0a67 100644 --- a/LibOVR/Makefile +++ b/LibOVR/Makefile @@ -1,26 +1,26 @@ ############################################################################# # # Filename : Makefile -# Content : Makefile for building linux version of: libovr -# 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 +# Content : Makefile for building Linux version of: libovr +# Created : 2014 +# Authors : Simon Hallam, Peter Giokaris, Chris Taylor +# Copyright : Copyright 2014 OculusVR, Inc. All Rights Reserved +# Instruction : The g++ compiler and standard 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 version for the -# current architechture -# make clean delete intermediate release object files +# make builds the release version for the +# current architecture +# make clean delete intermediate release object files # and the library file # make DEBUG=1 builds the debug version for the current -# architechture -# make clean DEBUG=1 deletes intermediate debug object files +# architecture +# make clean DEBUG=1 deletes intermediate debug object files # and the library file # # Output : Relative to the directory this Makefile lives in, libraries # are built at the following locations depending upon the -# architechture of the system you are running: +# architecture of the system you are running: # # ./Lib/Linux/Debug/i386/libovr.a # ./Lib/Linux/Debug/x86_64/libovr.a @@ -29,6 +29,9 @@ # ############################################################################# +####### Include auxiliary makefiles in current directory +-include Makefile.*[^~] + ####### Detect system architecture SYSARCH = i386 @@ -39,18 +42,21 @@ endif ####### Compiler, tools and options CXX = g++ -LINK = ar rvs +LINK = DELETEFILE = rm -f ####### Detect debug or release -DEBUG = 0 +COMMONFLAGS = -Wall -Wextra -Werror -pipe -fPIC -msse2 + +DEBUG ?= 0 +CXXFLAGS ?= ifeq ($(DEBUG), 1) - CXXFLAGS = -pipe -fPIC -DDEBUG -DOVR_BUILD_DEBUG -g - RELEASETYPE = Debug + CXXFLAGS += $(COMMONFLAGS) -DDEBUG -DOVR_BUILD_DEBUG -g + RELEASETYPE ?= Debug else - CXXFLAGS = -pipe -fPIC -O2 - RELEASETYPE = Release + CXXFLAGS += $(COMMONFLAGS) -O2 -fno-strict-aliasing + RELEASETYPE ?= Release endif ####### Paths @@ -59,220 +65,92 @@ LIBOVRPATH = . 3RDPARTYPATH = ../3rdParty INCPATH = -I. -I.. -I$(LIBOVRPATH)/Include -I$(LIBOVRPATH)/Src OBJPATH = ./Obj/Linux/$(RELEASETYPE)/$(SYSARCH) -CXXBUILD = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $(OBJPATH)/ +PREFIX = /usr/local ####### Files -TARGET = ./Lib/Linux/$(RELEASETYPE)/$(SYSARCH)/libovr.a - -OBJECTS = $(OBJPATH)/OVR_CAPI.o \ - $(OBJPATH)/CAPI_DistortionRenderer.o \ - $(OBJPATH)/CAPI_GL_DistortionRenderer.o \ - $(OBJPATH)/CAPI_GL_Util.o \ - $(OBJPATH)/CAPI_FrameTimeManager.o \ - $(OBJPATH)/CAPI_GlobalState.o \ - $(OBJPATH)/CAPI_HMDRenderState.o \ - $(OBJPATH)/CAPI_HMDState.o \ - $(OBJPATH)/OVR_DeviceHandle.o \ - $(OBJPATH)/OVR_DeviceImpl.o \ - $(OBJPATH)/OVR_JSON.o \ - $(OBJPATH)/OVR_LatencyTestImpl.o \ - $(OBJPATH)/OVR_Profile.o \ - $(OBJPATH)/OVR_Linux_SensorDevice.o\ - $(OBJPATH)/OVR_SensorCalibration.o\ - $(OBJPATH)/OVR_SensorFilter.o\ - $(OBJPATH)/OVR_SensorFusion.o\ - $(OBJPATH)/OVR_SensorImpl.o \ - $(OBJPATH)/OVR_Sensor2Impl.o \ - $(OBJPATH)/OVR_SensorImpl_Common.o \ - $(OBJPATH)/OVR_SensorTimeFilter.o \ - $(OBJPATH)/OVR_Stereo.o \ - $(OBJPATH)/OVR_ThreadCommandQueue.o \ - $(OBJPATH)/OVR_Alg.o \ - $(OBJPATH)/OVR_Allocator.o \ - $(OBJPATH)/OVR_Atomic.o \ - $(OBJPATH)/OVR_File.o \ - $(OBJPATH)/OVR_FileFILE.o \ - $(OBJPATH)/OVR_Log.o \ - $(OBJPATH)/OVR_Math.o \ - $(OBJPATH)/OVR_Recording.o \ - $(OBJPATH)/OVR_RefCount.o \ - $(OBJPATH)/OVR_Std.o \ - $(OBJPATH)/OVR_String.o \ - $(OBJPATH)/OVR_String_FormatUtil.o \ - $(OBJPATH)/OVR_String_PathUtil.o \ - $(OBJPATH)/OVR_SysFile.o \ - $(OBJPATH)/OVR_System.o \ - $(OBJPATH)/OVR_Timer.o \ - $(OBJPATH)/OVR_UTF8Util.o \ - $(OBJPATH)/Util_LatencyTest.o \ - $(OBJPATH)/Util_LatencyTest2.o \ - $(OBJPATH)/Util_Render_Stereo.o \ - $(OBJPATH)/OVR_ThreadsPthread.o \ - $(OBJPATH)/OVR_Linux_HIDDevice.o \ - $(OBJPATH)/OVR_Linux_SensorDevice.o \ - $(OBJPATH)/OVR_Linux_DeviceManager.o \ - $(OBJPATH)/OVR_Linux_HMDDevice.o \ - $(OBJPATH)/edid.o +TARGET_DIR = ./Lib/Linux/$(RELEASETYPE)/$(SYSARCH) +STATIC_NAME = libovr.a +STATIC_TARGET = $(TARGET_DIR)/$(STATIC_NAME) +LIBOVR_INST_HDR = Src/OVR_CAPI.h Src/OVR_CAPI_Keys.h Src/OVR_CAPI_GL.h ####### Rules -all: $(TARGET) - -$(TARGET): $(OBJECTS) - $(LINK) $(TARGET) $(OBJECTS) - -$(OBJPATH)/OVR_CAPI.o: $(LIBOVRPATH)/Src/OVR_CAPI.cpp - $(CXXBUILD)OVR_CAPI.o $(LIBOVRPATH)/Src/OVR_CAPI.cpp - -$(OBJPATH)/CAPI_DistortionRenderer.o: $(LIBOVRPATH)/Src/CAPI/CAPI_DistortionRenderer.cpp - $(CXXBUILD)CAPI_DistortionRenderer.o $(LIBOVRPATH)/Src/CAPI/CAPI_DistortionRenderer.cpp - -$(OBJPATH)/CAPI_GL_DistortionRenderer.o: $(LIBOVRPATH)/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp - $(CXXBUILD)CAPI_GL_DistortionRenderer.o $(LIBOVRPATH)/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp - -$(OBJPATH)/CAPI_GL_Util.o: $(LIBOVRPATH)/Src/CAPI/GL/CAPI_GL_Util.cpp - $(CXXBUILD)CAPI_GL_Util.o $(LIBOVRPATH)/Src/CAPI/GL/CAPI_GL_Util.cpp - -$(OBJPATH)/CAPI_FrameTimeManager.o: $(LIBOVRPATH)/Src/CAPI/CAPI_FrameTimeManager.cpp - $(CXXBUILD)CAPI_FrameTimeManager.o $(LIBOVRPATH)/Src/CAPI/CAPI_FrameTimeManager.cpp - -$(OBJPATH)/CAPI_GlobalState.o: $(LIBOVRPATH)/Src/CAPI/CAPI_GlobalState.cpp - $(CXXBUILD)CAPI_GlobalState.o $(LIBOVRPATH)/Src/CAPI/CAPI_GlobalState.cpp - -$(OBJPATH)/CAPI_HMDRenderState.o: $(LIBOVRPATH)/Src/CAPI/CAPI_HMDRenderState.cpp - $(CXXBUILD)CAPI_HMDRenderState.o $(LIBOVRPATH)/Src/CAPI/CAPI_HMDRenderState.cpp - -$(OBJPATH)/CAPI_HMDState.o: $(LIBOVRPATH)/Src/CAPI/CAPI_HMDState.cpp - $(CXXBUILD)CAPI_HMDState.o $(LIBOVRPATH)/Src/CAPI/CAPI_HMDState.cpp - -$(OBJPATH)/OVR_DeviceHandle.o: $(LIBOVRPATH)/Src/OVR_DeviceHandle.cpp - $(CXXBUILD)OVR_DeviceHandle.o $(LIBOVRPATH)/Src/OVR_DeviceHandle.cpp - -$(OBJPATH)/OVR_DeviceImpl.o: $(LIBOVRPATH)/Src/OVR_DeviceImpl.cpp - $(CXXBUILD)OVR_DeviceImpl.o $(LIBOVRPATH)/Src/OVR_DeviceImpl.cpp - -$(OBJPATH)/OVR_JSON.o: $(LIBOVRPATH)/Src/OVR_JSON.cpp - $(CXXBUILD)OVR_JSON.o $(LIBOVRPATH)/Src/OVR_JSON.cpp - -$(OBJPATH)/OVR_LatencyTestImpl.o: $(LIBOVRPATH)/Src/OVR_LatencyTestImpl.cpp - $(CXXBUILD)OVR_LatencyTestImpl.o $(LIBOVRPATH)/Src/OVR_LatencyTestImpl.cpp - -$(OBJPATH)/OVR_Profile.o: $(LIBOVRPATH)/Src/OVR_Profile.cpp - $(CXXBUILD)OVR_Profile.o $(LIBOVRPATH)/Src/OVR_Profile.cpp - -$(OBJPATH)/OVR_SensorDevice.o: $(LIBOVRPATH)/Src/OVR_Linux_SensorDevice.cpp - $(CXXBUILD)OVR_Linux_SensorDevice.o $(LIBOVRPATH)/Src/OVR_Linux_SensorDevice.cpp - -$(OBJPATH)/OVR_SensorCalibration.o: $(LIBOVRPATH)/Src/OVR_SensorCalibration.cpp - $(CXXBUILD)OVR_SensorCalibration.o $(LIBOVRPATH)/Src/OVR_SensorCalibration.cpp - -$(OBJPATH)/OVR_SensorFilter.o: $(LIBOVRPATH)/Src/OVR_SensorFilter.cpp - $(CXXBUILD)OVR_SensorFilter.o $(LIBOVRPATH)/Src/OVR_SensorFilter.cpp - -$(OBJPATH)/OVR_SensorFusion.o: $(LIBOVRPATH)/Src/OVR_SensorFusion.cpp - $(CXXBUILD)OVR_SensorFusion.o $(LIBOVRPATH)/Src/OVR_SensorFusion.cpp - -$(OBJPATH)/OVR_SensorImpl.o: $(LIBOVRPATH)/Src/OVR_SensorImpl.cpp - $(CXXBUILD)OVR_SensorImpl.o $(LIBOVRPATH)/Src/OVR_SensorImpl.cpp - -$(OBJPATH)/OVR_Sensor2Impl.o: $(LIBOVRPATH)/Src/OVR_Sensor2Impl.cpp - $(CXXBUILD)OVR_Sensor2Impl.o $(LIBOVRPATH)/Src/OVR_Sensor2Impl.cpp - -$(OBJPATH)/OVR_SensorImpl_Common.o: $(LIBOVRPATH)/Src/OVR_SensorImpl_Common.cpp - $(CXXBUILD)OVR_SensorImpl_Common.o $(LIBOVRPATH)/Src/OVR_SensorImpl_Common.cpp - -$(OBJPATH)/OVR_SensorTimeFilter.o: $(LIBOVRPATH)/Src/OVR_SensorTimeFilter.cpp - $(CXXBUILD)OVR_SensorTimeFilter.o $(LIBOVRPATH)/Src/OVR_SensorTimeFilter.cpp - -$(OBJPATH)/OVR_Stereo.o: $(LIBOVRPATH)/Src/OVR_Stereo.cpp - $(CXXBUILD)OVR_Stereo.o $(LIBOVRPATH)/Src/OVR_Stereo.cpp - -$(OBJPATH)/OVR_ThreadCommandQueue.o: $(LIBOVRPATH)/Src/OVR_ThreadCommandQueue.cpp - $(CXXBUILD)OVR_ThreadCommandQueue.o $(LIBOVRPATH)/Src/OVR_ThreadCommandQueue.cpp - -$(OBJPATH)/OVR_Alg.o: $(LIBOVRPATH)/Src/Kernel/OVR_Alg.cpp - $(CXXBUILD)OVR_Alg.o $(LIBOVRPATH)/Src/Kernel/OVR_Alg.cpp - -$(OBJPATH)/OVR_Allocator.o: $(LIBOVRPATH)/Src/Kernel/OVR_Allocator.cpp - $(CXXBUILD)OVR_Allocator.o $(LIBOVRPATH)/Src/Kernel/OVR_Allocator.cpp - -$(OBJPATH)/OVR_Atomic.o: $(LIBOVRPATH)/Src/Kernel/OVR_Atomic.cpp - $(CXXBUILD)OVR_Atomic.o $(LIBOVRPATH)/Src/Kernel/OVR_Atomic.cpp - -$(OBJPATH)/OVR_File.o: $(LIBOVRPATH)/Src/Kernel/OVR_File.cpp - $(CXXBUILD)OVR_File.o $(LIBOVRPATH)/Src/Kernel/OVR_File.cpp - -$(OBJPATH)/OVR_FileFILE.o: $(LIBOVRPATH)/Src/Kernel/OVR_FileFILE.cpp - $(CXXBUILD)OVR_FileFILE.o $(LIBOVRPATH)/Src/Kernel/OVR_FileFILE.cpp - -$(OBJPATH)/OVR_Log.o: $(LIBOVRPATH)/Src/Kernel/OVR_Log.cpp - $(CXXBUILD)OVR_Log.o $(LIBOVRPATH)/Src/Kernel/OVR_Log.cpp - -$(OBJPATH)/OVR_Math.o: $(LIBOVRPATH)/Src/Kernel/OVR_Math.cpp - $(CXXBUILD)OVR_Math.o $(LIBOVRPATH)/Src/Kernel/OVR_Math.cpp - -$(OBJPATH)/OVR_Recording.o: $(LIBOVRPATH)/Src/OVR_Recording.cpp - $(CXXBUILD)OVR_Recording.o $(LIBOVRPATH)/Src/OVR_Recording.cpp - -$(OBJPATH)/OVR_RefCount.o: $(LIBOVRPATH)/Src/Kernel/OVR_RefCount.cpp - $(CXXBUILD)OVR_RefCount.o $(LIBOVRPATH)/Src/Kernel/OVR_RefCount.cpp - -$(OBJPATH)/OVR_Std.o: $(LIBOVRPATH)/Src/Kernel/OVR_Std.cpp - $(CXXBUILD)OVR_Std.o $(LIBOVRPATH)/Src/Kernel/OVR_Std.cpp - -$(OBJPATH)/OVR_String.o: $(LIBOVRPATH)/Src/Kernel/OVR_String.cpp - $(CXXBUILD)OVR_String.o $(LIBOVRPATH)/Src/Kernel/OVR_String.cpp - -$(OBJPATH)/OVR_String_FormatUtil.o: $(LIBOVRPATH)/Src/Kernel/OVR_String_FormatUtil.cpp - $(CXXBUILD)OVR_String_FormatUtil.o $(LIBOVRPATH)/Src/Kernel/OVR_String_FormatUtil.cpp - -$(OBJPATH)/OVR_String_PathUtil.o: $(LIBOVRPATH)/Src/Kernel/OVR_String_PathUtil.cpp - $(CXXBUILD)OVR_String_PathUtil.o $(LIBOVRPATH)/Src/Kernel/OVR_String_PathUtil.cpp - -$(OBJPATH)/OVR_SysFile.o: $(LIBOVRPATH)/Src/Kernel/OVR_SysFile.cpp - $(CXXBUILD)OVR_SysFile.o $(LIBOVRPATH)/Src/Kernel/OVR_SysFile.cpp - -$(OBJPATH)/OVR_System.o: $(LIBOVRPATH)/Src/Kernel/OVR_System.cpp - $(CXXBUILD)OVR_System.o $(LIBOVRPATH)/Src/Kernel/OVR_System.cpp - -$(OBJPATH)/OVR_Timer.o: $(LIBOVRPATH)/Src/Kernel/OVR_Timer.cpp - $(CXXBUILD)OVR_Timer.o $(LIBOVRPATH)/Src/Kernel/OVR_Timer.cpp - -$(OBJPATH)/OVR_UTF8Util.o: $(LIBOVRPATH)/Src/Kernel/OVR_UTF8Util.cpp - $(CXXBUILD)OVR_UTF8Util.o $(LIBOVRPATH)/Src/Kernel/OVR_UTF8Util.cpp - -$(OBJPATH)/Util_LatencyTest.o: $(LIBOVRPATH)/Src/Util/Util_LatencyTest.cpp - $(CXXBUILD)Util_LatencyTest.o $(LIBOVRPATH)/Src/Util/Util_LatencyTest.cpp - -$(OBJPATH)/Util_LatencyTest2.o: $(LIBOVRPATH)/Src/Util/Util_LatencyTest2.cpp - $(CXXBUILD)Util_LatencyTest2.o $(LIBOVRPATH)/Src/Util/Util_LatencyTest2.cpp - -$(OBJPATH)/Util_Render_Stereo.o: $(LIBOVRPATH)/Src/Util/Util_Render_Stereo.cpp - $(CXXBUILD)Util_Render_Stereo.o $(LIBOVRPATH)/Src/Util/Util_Render_Stereo.cpp - -$(OBJPATH)/OVR_ThreadsPthread.o: $(LIBOVRPATH)/Src/Kernel/OVR_ThreadsPthread.cpp - $(CXXBUILD)OVR_ThreadsPthread.o $(LIBOVRPATH)/Src/Kernel/OVR_ThreadsPthread.cpp - -$(OBJPATH)/OVR_Linux_HIDDevice.o: $(LIBOVRPATH)/Src/OVR_Linux_HIDDevice.cpp - $(CXXBUILD)OVR_Linux_HIDDevice.o $(LIBOVRPATH)/Src/OVR_Linux_HIDDevice.cpp - -$(OBJPATH)/OVR_Linux_SensorDevice.o: $(LIBOVRPATH)/Src/OVR_Linux_SensorDevice.cpp - $(CXXBUILD)OVR_Linux_SensorDevice.o $(LIBOVRPATH)/Src/OVR_Linux_SensorDevice.cpp - -$(OBJPATH)/OVR_Linux_DeviceManager.o: $(LIBOVRPATH)/Src/OVR_Linux_DeviceManager.cpp - $(CXXBUILD)OVR_Linux_DeviceManager.o $(LIBOVRPATH)/Src/OVR_Linux_DeviceManager.cpp - -$(OBJPATH)/OVR_Linux_HMDDevice.o: $(LIBOVRPATH)/Src/OVR_Linux_HMDDevice.cpp - $(CXXBUILD)OVR_Linux_HMDDevice.o $(LIBOVRPATH)/Src/OVR_Linux_HMDDevice.cpp - -$(OBJPATH)/tinyxml2.o: $(3RDPARTYPATH)/TinyXml/tinyxml2.cpp - $(CXXBUILD)tinyxml2.o $(3RDPARTYPATH)/TinyXml/tinyxml2.cpp - -$(OBJPATH)/edid.o: $(3RDPARTYPATH)/EDID/edid.cpp - $(CXXBUILD)edid.o $(3RDPARTYPATH)/EDID/edid.cpp +all: $(STATIC_TARGET) + +OTHER_SOURCE = $(3RDPARTYPATH)/EDID/edid.cpp \ + $(3RDPARTYPATH)/TinyXml/tinyxml2.cpp + +OTHER_OBJECTS = $(OTHER_SOURCE:.cpp=.o) + +LIBOVR_SOURCE = $(LIBOVRPATH)/Src/Net/OVR_BitStream.cpp \ + $(LIBOVRPATH)/Src/Net/OVR_Unix_Socket.cpp \ + $(LIBOVRPATH)/Src/Net/OVR_NetworkPlugin.cpp \ + $(LIBOVRPATH)/Src/Net/OVR_PacketizedTCPSocket.cpp \ + $(LIBOVRPATH)/Src/Net/OVR_RPC1.cpp \ + $(LIBOVRPATH)/Src/Net/OVR_Session.cpp \ + $(LIBOVRPATH)/Src/Net/OVR_Socket.cpp \ + $(LIBOVRPATH)/Src/Service/Service_NetClient.cpp \ + $(LIBOVRPATH)/Src/Service/Service_NetSessionCommon.cpp \ + $(LIBOVRPATH)/Src/Tracking/Tracking_SensorStateReader.cpp \ + $(LIBOVRPATH)/Src/Displays/OVR_Display.cpp \ + $(LIBOVRPATH)/Src/Displays/OVR_Linux_Display.cpp \ + $(LIBOVRPATH)/Src/Displays/OVR_Linux_SDKWindow.cpp \ + $(LIBOVRPATH)/Src/CAPI/CAPI_DistortionRenderer.cpp \ + $(LIBOVRPATH)/Src/CAPI/CAPI_HSWDisplay.cpp \ + $(LIBOVRPATH)/Src/CAPI/CAPI_FrameTimeManager.cpp \ + $(LIBOVRPATH)/Src/CAPI/CAPI_HMDRenderState.cpp \ + $(LIBOVRPATH)/Src/CAPI/CAPI_HMDState.cpp \ + $(LIBOVRPATH)/Src/CAPI/CAPI_LatencyStatistics.cpp \ + $(LIBOVRPATH)/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp \ + $(LIBOVRPATH)/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp \ + $(LIBOVRPATH)/Src/CAPI/GL/CAPI_GL_Util.cpp \ + $(LIBOVRPATH)/Src/CAPI/GL/CAPI_GLE.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_Alg.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_Allocator.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_Atomic.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_CRC32.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_DebugHelp.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_File.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_FileFILE.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_Lockless.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_Log.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_Math.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_RefCount.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_SharedMemory.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_Std.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_String.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_String_FormatUtil.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_String_PathUtil.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_SysFile.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_System.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_ThreadsPthread.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_ThreadCommandQueue.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_Timer.cpp \ + $(LIBOVRPATH)/Src/Kernel/OVR_UTF8Util.cpp \ + $(LIBOVRPATH)/Src/Util/Util_Interface.cpp \ + $(LIBOVRPATH)/Src/Util/Util_LatencyTest2Reader.cpp \ + $(LIBOVRPATH)/Src/Util/Util_Render_Stereo.cpp \ + $(LIBOVRPATH)/Src/Util/Util_SystemInfo.cpp \ + $(LIBOVRPATH)/Src/Util/Util_SystemGUI.cpp \ + $(LIBOVRPATH)/Src/OVR_CAPI.cpp \ + $(LIBOVRPATH)/Src/OVR_SerialFormat.cpp \ + $(LIBOVRPATH)/Src/OVR_JSON.cpp \ + $(LIBOVRPATH)/Src/OVR_Profile.cpp \ + $(LIBOVRPATH)/Src/OVR_Stereo.cpp + +LIBOVR_OBJECTS = $(patsubst $(LIBOVRPATH)%.cpp,$(OBJPATH)%.o,$(LIBOVR_SOURCE)) + +OBJECTS = $(OTHER_OBJECTS) $(LIBOVR_OBJECTS) + +$(OBJPATH)/%.o: %.cpp + @mkdir -p $(dir $@) + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +$(STATIC_TARGET): $(OBJECTS) + @mkdir -p $(@D) + ar rvs $(STATIC_TARGET) $(OBJECTS) clean: -$(DELETEFILE) $(OBJECTS) - -$(DELETEFILE) $(TARGET) - + -$(DELETEFILE) $(STATIC_TARGET) diff --git a/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.pbxproj b/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.pbxproj index 485af04..7a406be 100644 --- a/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.pbxproj +++ b/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.pbxproj @@ -7,7 +7,66 @@ objects = { /* Begin PBXBuildFile section */ - E8754F81190F1B71005FD401 /* OVR_Recording.h in Headers */ = {isa = PBXBuildFile; fileRef = E8754F7F190F1B71005FD401 /* OVR_Recording.h */; }; + 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 */; }; @@ -56,60 +115,17 @@ 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 */; }; - E8AA410F1907224700D5F144 /* Util_LatencyTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41031907224700D5F144 /* Util_LatencyTest.cpp */; }; - E8AA41101907224700D5F144 /* Util_LatencyTest.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41041907224700D5F144 /* Util_LatencyTest.h */; }; - E8AA41111907224700D5F144 /* Util_LatencyTest2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41051907224700D5F144 /* Util_LatencyTest2.cpp */; }; - E8AA41121907224700D5F144 /* Util_LatencyTest2.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41061907224700D5F144 /* Util_LatencyTest2.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 */; }; - E8AA4169190722BB00D5F144 /* OVR_Device.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4121190722BB00D5F144 /* OVR_Device.h */; }; - E8AA416A190722BB00D5F144 /* OVR_DeviceConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4122190722BB00D5F144 /* OVR_DeviceConstants.h */; }; - E8AA416B190722BB00D5F144 /* OVR_DeviceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4123190722BB00D5F144 /* OVR_DeviceHandle.cpp */; }; - E8AA416C190722BB00D5F144 /* OVR_DeviceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4124190722BB00D5F144 /* OVR_DeviceHandle.h */; }; - E8AA416D190722BB00D5F144 /* OVR_DeviceImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4125190722BB00D5F144 /* OVR_DeviceImpl.cpp */; }; - E8AA416E190722BB00D5F144 /* OVR_DeviceImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4126190722BB00D5F144 /* OVR_DeviceImpl.h */; }; - E8AA416F190722BB00D5F144 /* OVR_DeviceMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4127190722BB00D5F144 /* OVR_DeviceMessages.h */; }; - E8AA4170190722BB00D5F144 /* OVR_HIDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4128190722BB00D5F144 /* OVR_HIDDevice.h */; }; - E8AA4171190722BB00D5F144 /* OVR_HIDDeviceBase.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4129190722BB00D5F144 /* OVR_HIDDeviceBase.h */; }; - E8AA4172190722BB00D5F144 /* OVR_HIDDeviceImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA412A190722BB00D5F144 /* OVR_HIDDeviceImpl.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 */; }; - E8AA4175190722BB00D5F144 /* OVR_LatencyTestImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA412D190722BB00D5F144 /* OVR_LatencyTestImpl.cpp */; }; - E8AA4176190722BB00D5F144 /* OVR_LatencyTestImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA412E190722BB00D5F144 /* OVR_LatencyTestImpl.h */; }; - E8AA417E190722BB00D5F144 /* OVR_OSX_DeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4136190722BB00D5F144 /* OVR_OSX_DeviceManager.cpp */; }; - E8AA417F190722BB00D5F144 /* OVR_OSX_DeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4137190722BB00D5F144 /* OVR_OSX_DeviceManager.h */; }; - E8AA4180190722BB00D5F144 /* OVR_OSX_HIDDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4138190722BB00D5F144 /* OVR_OSX_HIDDevice.cpp */; }; - E8AA4181190722BB00D5F144 /* OVR_OSX_HIDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4139190722BB00D5F144 /* OVR_OSX_HIDDevice.h */; }; - E8AA4182190722BB00D5F144 /* OVR_OSX_HMDDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA413A190722BB00D5F144 /* OVR_OSX_HMDDevice.cpp */; }; - E8AA4183190722BB00D5F144 /* OVR_OSX_HMDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA413B190722BB00D5F144 /* OVR_OSX_HMDDevice.h */; }; - E8AA4184190722BB00D5F144 /* OVR_OSX_SensorDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA413C190722BB00D5F144 /* OVR_OSX_SensorDevice.cpp */; }; 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 */; }; - E8AA4187190722BB00D5F144 /* OVR_Sensor2Impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA413F190722BB00D5F144 /* OVR_Sensor2Impl.cpp */; }; - E8AA4188190722BB00D5F144 /* OVR_Sensor2Impl.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4140190722BB00D5F144 /* OVR_Sensor2Impl.h */; }; - E8AA4189190722BB00D5F144 /* OVR_Sensor2ImplUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4141190722BB00D5F144 /* OVR_Sensor2ImplUtil.h */; }; - E8AA418A190722BB00D5F144 /* OVR_SensorCalibration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4142190722BB00D5F144 /* OVR_SensorCalibration.cpp */; }; - E8AA418B190722BB00D5F144 /* OVR_SensorCalibration.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4143190722BB00D5F144 /* OVR_SensorCalibration.h */; }; - E8AA418C190722BB00D5F144 /* OVR_SensorFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4144190722BB00D5F144 /* OVR_SensorFilter.cpp */; }; - E8AA418D190722BB00D5F144 /* OVR_SensorFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4145190722BB00D5F144 /* OVR_SensorFilter.h */; }; - E8AA418E190722BB00D5F144 /* OVR_SensorFusion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4146190722BB00D5F144 /* OVR_SensorFusion.cpp */; }; - E8AA418F190722BB00D5F144 /* OVR_SensorFusion.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4147190722BB00D5F144 /* OVR_SensorFusion.h */; }; - E8AA4190190722BB00D5F144 /* OVR_SensorFusionDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4148190722BB00D5F144 /* OVR_SensorFusionDebug.h */; }; - E8AA4191190722BB00D5F144 /* OVR_SensorImpl_Common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4149190722BB00D5F144 /* OVR_SensorImpl_Common.cpp */; }; - E8AA4192190722BB00D5F144 /* OVR_SensorImpl_Common.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA414A190722BB00D5F144 /* OVR_SensorImpl_Common.h */; }; - E8AA4193190722BB00D5F144 /* OVR_SensorImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA414B190722BB00D5F144 /* OVR_SensorImpl.cpp */; }; - E8AA4194190722BB00D5F144 /* OVR_SensorImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA414C190722BB00D5F144 /* OVR_SensorImpl.h */; }; - E8AA4195190722BB00D5F144 /* OVR_SensorTimeFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA414D190722BB00D5F144 /* OVR_SensorTimeFilter.cpp */; }; - E8AA4196190722BB00D5F144 /* OVR_SensorTimeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA414E190722BB00D5F144 /* OVR_SensorTimeFilter.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 */; }; - E8AA4199190722BB00D5F144 /* OVR_ThreadCommandQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA4151190722BB00D5F144 /* OVR_ThreadCommandQueue.cpp */; }; - E8AA419A190722BB00D5F144 /* OVR_ThreadCommandQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4152190722BB00D5F144 /* OVR_ThreadCommandQueue.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 */; }; - E8AA41E5190724E600D5F144 /* CAPI_GlobalState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41BD190724E600D5F144 /* CAPI_GlobalState.cpp */; }; - E8AA41E6190724E600D5F144 /* CAPI_GlobalState.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41BE190724E600D5F144 /* CAPI_GlobalState.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 */; }; @@ -118,12 +134,72 @@ 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 */; }; - E8F1F13E1921911D000EC969 /* OVR_Recording.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8F1F13D1921911D000EC969 /* OVR_Recording.cpp */; }; + 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; }; - E8754F7F190F1B71005FD401 /* OVR_Recording.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Recording.h; path = ../../../Src/OVR_Recording.h; sourceTree = ""; }; + 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 = ""; }; @@ -172,60 +248,17 @@ 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 = ""; }; - E8AA41031907224700D5F144 /* Util_LatencyTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_LatencyTest.cpp; sourceTree = ""; }; - E8AA41041907224700D5F144 /* Util_LatencyTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_LatencyTest.h; sourceTree = ""; }; - E8AA41051907224700D5F144 /* Util_LatencyTest2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_LatencyTest2.cpp; sourceTree = ""; }; - E8AA41061907224700D5F144 /* Util_LatencyTest2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_LatencyTest2.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 = ""; }; - E8AA4121190722BB00D5F144 /* OVR_Device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Device.h; path = ../../../Src/OVR_Device.h; sourceTree = ""; }; - E8AA4122190722BB00D5F144 /* OVR_DeviceConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_DeviceConstants.h; path = ../../../Src/OVR_DeviceConstants.h; sourceTree = ""; }; - E8AA4123190722BB00D5F144 /* OVR_DeviceHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_DeviceHandle.cpp; path = ../../../Src/OVR_DeviceHandle.cpp; sourceTree = ""; }; - E8AA4124190722BB00D5F144 /* OVR_DeviceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_DeviceHandle.h; path = ../../../Src/OVR_DeviceHandle.h; sourceTree = ""; }; - E8AA4125190722BB00D5F144 /* OVR_DeviceImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_DeviceImpl.cpp; path = ../../../Src/OVR_DeviceImpl.cpp; sourceTree = ""; }; - E8AA4126190722BB00D5F144 /* OVR_DeviceImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_DeviceImpl.h; path = ../../../Src/OVR_DeviceImpl.h; sourceTree = ""; }; - E8AA4127190722BB00D5F144 /* OVR_DeviceMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_DeviceMessages.h; path = ../../../Src/OVR_DeviceMessages.h; sourceTree = ""; }; - E8AA4128190722BB00D5F144 /* OVR_HIDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_HIDDevice.h; path = ../../../Src/OVR_HIDDevice.h; sourceTree = ""; }; - E8AA4129190722BB00D5F144 /* OVR_HIDDeviceBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_HIDDeviceBase.h; path = ../../../Src/OVR_HIDDeviceBase.h; sourceTree = ""; }; - E8AA412A190722BB00D5F144 /* OVR_HIDDeviceImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_HIDDeviceImpl.h; path = ../../../Src/OVR_HIDDeviceImpl.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 = ""; }; - E8AA412D190722BB00D5F144 /* OVR_LatencyTestImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_LatencyTestImpl.cpp; path = ../../../Src/OVR_LatencyTestImpl.cpp; sourceTree = ""; }; - E8AA412E190722BB00D5F144 /* OVR_LatencyTestImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_LatencyTestImpl.h; path = ../../../Src/OVR_LatencyTestImpl.h; sourceTree = ""; }; - E8AA4136190722BB00D5F144 /* OVR_OSX_DeviceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_OSX_DeviceManager.cpp; path = ../../../Src/OVR_OSX_DeviceManager.cpp; sourceTree = ""; }; - E8AA4137190722BB00D5F144 /* OVR_OSX_DeviceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_OSX_DeviceManager.h; path = ../../../Src/OVR_OSX_DeviceManager.h; sourceTree = ""; }; - E8AA4138190722BB00D5F144 /* OVR_OSX_HIDDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_OSX_HIDDevice.cpp; path = ../../../Src/OVR_OSX_HIDDevice.cpp; sourceTree = ""; }; - E8AA4139190722BB00D5F144 /* OVR_OSX_HIDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_OSX_HIDDevice.h; path = ../../../Src/OVR_OSX_HIDDevice.h; sourceTree = ""; }; - E8AA413A190722BB00D5F144 /* OVR_OSX_HMDDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_OSX_HMDDevice.cpp; path = ../../../Src/OVR_OSX_HMDDevice.cpp; sourceTree = ""; }; - E8AA413B190722BB00D5F144 /* OVR_OSX_HMDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_OSX_HMDDevice.h; path = ../../../Src/OVR_OSX_HMDDevice.h; sourceTree = ""; }; - E8AA413C190722BB00D5F144 /* OVR_OSX_SensorDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_OSX_SensorDevice.cpp; path = ../../../Src/OVR_OSX_SensorDevice.cpp; 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 = ""; }; - E8AA413F190722BB00D5F144 /* OVR_Sensor2Impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Sensor2Impl.cpp; path = ../../../Src/OVR_Sensor2Impl.cpp; sourceTree = ""; }; - E8AA4140190722BB00D5F144 /* OVR_Sensor2Impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Sensor2Impl.h; path = ../../../Src/OVR_Sensor2Impl.h; sourceTree = ""; }; - E8AA4141190722BB00D5F144 /* OVR_Sensor2ImplUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Sensor2ImplUtil.h; path = ../../../Src/OVR_Sensor2ImplUtil.h; sourceTree = ""; }; - E8AA4142190722BB00D5F144 /* OVR_SensorCalibration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SensorCalibration.cpp; path = ../../../Src/OVR_SensorCalibration.cpp; sourceTree = ""; }; - E8AA4143190722BB00D5F144 /* OVR_SensorCalibration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SensorCalibration.h; path = ../../../Src/OVR_SensorCalibration.h; sourceTree = ""; }; - E8AA4144190722BB00D5F144 /* OVR_SensorFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SensorFilter.cpp; path = ../../../Src/OVR_SensorFilter.cpp; sourceTree = ""; }; - E8AA4145190722BB00D5F144 /* OVR_SensorFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SensorFilter.h; path = ../../../Src/OVR_SensorFilter.h; sourceTree = ""; }; - E8AA4146190722BB00D5F144 /* OVR_SensorFusion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SensorFusion.cpp; path = ../../../Src/OVR_SensorFusion.cpp; sourceTree = ""; }; - E8AA4147190722BB00D5F144 /* OVR_SensorFusion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SensorFusion.h; path = ../../../Src/OVR_SensorFusion.h; sourceTree = ""; }; - E8AA4148190722BB00D5F144 /* OVR_SensorFusionDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SensorFusionDebug.h; path = ../../../Src/OVR_SensorFusionDebug.h; sourceTree = ""; }; - E8AA4149190722BB00D5F144 /* OVR_SensorImpl_Common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SensorImpl_Common.cpp; path = ../../../Src/OVR_SensorImpl_Common.cpp; sourceTree = ""; }; - E8AA414A190722BB00D5F144 /* OVR_SensorImpl_Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SensorImpl_Common.h; path = ../../../Src/OVR_SensorImpl_Common.h; sourceTree = ""; }; - E8AA414B190722BB00D5F144 /* OVR_SensorImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SensorImpl.cpp; path = ../../../Src/OVR_SensorImpl.cpp; sourceTree = ""; }; - E8AA414C190722BB00D5F144 /* OVR_SensorImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SensorImpl.h; path = ../../../Src/OVR_SensorImpl.h; sourceTree = ""; }; - E8AA414D190722BB00D5F144 /* OVR_SensorTimeFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SensorTimeFilter.cpp; path = ../../../Src/OVR_SensorTimeFilter.cpp; sourceTree = ""; }; - E8AA414E190722BB00D5F144 /* OVR_SensorTimeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SensorTimeFilter.h; path = ../../../Src/OVR_SensorTimeFilter.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 = ""; }; - E8AA4151190722BB00D5F144 /* OVR_ThreadCommandQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_ThreadCommandQueue.cpp; path = ../../../Src/OVR_ThreadCommandQueue.cpp; sourceTree = ""; }; - E8AA4152190722BB00D5F144 /* OVR_ThreadCommandQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_ThreadCommandQueue.h; path = ../../../Src/OVR_ThreadCommandQueue.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 = ""; }; - E8AA41BD190724E600D5F144 /* CAPI_GlobalState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_GlobalState.cpp; sourceTree = ""; }; - E8AA41BE190724E600D5F144 /* CAPI_GlobalState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_GlobalState.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 = ""; }; @@ -234,7 +267,8 @@ 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 = ""; }; - E8F1F13D1921911D000EC969 /* OVR_Recording.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Recording.cpp; path = ../../../Src/OVR_Recording.cpp; 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 */ @@ -251,57 +285,26 @@ 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 */, - E8AA4121190722BB00D5F144 /* OVR_Device.h */, - E8AA4122190722BB00D5F144 /* OVR_DeviceConstants.h */, - E8AA4123190722BB00D5F144 /* OVR_DeviceHandle.cpp */, - E8AA4124190722BB00D5F144 /* OVR_DeviceHandle.h */, - E8AA4125190722BB00D5F144 /* OVR_DeviceImpl.cpp */, - E8AA4126190722BB00D5F144 /* OVR_DeviceImpl.h */, - E8AA4127190722BB00D5F144 /* OVR_DeviceMessages.h */, - E8AA4128190722BB00D5F144 /* OVR_HIDDevice.h */, - E8AA4129190722BB00D5F144 /* OVR_HIDDeviceBase.h */, - E8AA412A190722BB00D5F144 /* OVR_HIDDeviceImpl.h */, + 8864E8FC19D5289700ACEEC1 /* OVR_CAPI_Keys.h */, + E85F262A1954204900AA807B /* OVR_SerialFormat.cpp */, + E85F262B1954204900AA807B /* OVR_SerialFormat.h */, E8AA412B190722BB00D5F144 /* OVR_JSON.cpp */, E8AA412C190722BB00D5F144 /* OVR_JSON.h */, - E8AA412D190722BB00D5F144 /* OVR_LatencyTestImpl.cpp */, - E8AA412E190722BB00D5F144 /* OVR_LatencyTestImpl.h */, - E8AA4136190722BB00D5F144 /* OVR_OSX_DeviceManager.cpp */, - E8AA4137190722BB00D5F144 /* OVR_OSX_DeviceManager.h */, - E8AA4138190722BB00D5F144 /* OVR_OSX_HIDDevice.cpp */, - E8AA4139190722BB00D5F144 /* OVR_OSX_HIDDevice.h */, - E8AA413A190722BB00D5F144 /* OVR_OSX_HMDDevice.cpp */, - E8AA413B190722BB00D5F144 /* OVR_OSX_HMDDevice.h */, - E8AA413C190722BB00D5F144 /* OVR_OSX_SensorDevice.cpp */, E8AA413D190722BB00D5F144 /* OVR_Profile.cpp */, E8AA413E190722BB00D5F144 /* OVR_Profile.h */, - E8F1F13D1921911D000EC969 /* OVR_Recording.cpp */, - E8754F7F190F1B71005FD401 /* OVR_Recording.h */, - E8AA413F190722BB00D5F144 /* OVR_Sensor2Impl.cpp */, - E8AA4140190722BB00D5F144 /* OVR_Sensor2Impl.h */, - E8AA4141190722BB00D5F144 /* OVR_Sensor2ImplUtil.h */, - E8AA4142190722BB00D5F144 /* OVR_SensorCalibration.cpp */, - E8AA4143190722BB00D5F144 /* OVR_SensorCalibration.h */, - E8AA4144190722BB00D5F144 /* OVR_SensorFilter.cpp */, - E8AA4145190722BB00D5F144 /* OVR_SensorFilter.h */, - E8AA4146190722BB00D5F144 /* OVR_SensorFusion.cpp */, - E8AA4147190722BB00D5F144 /* OVR_SensorFusion.h */, - E8AA4148190722BB00D5F144 /* OVR_SensorFusionDebug.h */, - E8AA4149190722BB00D5F144 /* OVR_SensorImpl_Common.cpp */, - E8AA414A190722BB00D5F144 /* OVR_SensorImpl_Common.h */, - E8AA414B190722BB00D5F144 /* OVR_SensorImpl.cpp */, - E8AA414C190722BB00D5F144 /* OVR_SensorImpl.h */, - E8AA414D190722BB00D5F144 /* OVR_SensorTimeFilter.cpp */, - E8AA414E190722BB00D5F144 /* OVR_SensorTimeFilter.h */, E8AA414F190722BB00D5F144 /* OVR_Stereo.cpp */, E8AA4150190722BB00D5F144 /* OVR_Stereo.h */, - E8AA4151190722BB00D5F144 /* OVR_ThreadCommandQueue.cpp */, - E8AA4152190722BB00D5F144 /* OVR_ThreadCommandQueue.h */, E82D4CD41906FE640070CB3F /* Products */, ); sourceTree = ""; @@ -314,9 +317,85 @@ 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 */, @@ -367,12 +446,17 @@ 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 */, - E8AA41031907224700D5F144 /* Util_LatencyTest.cpp */, - E8AA41041907224700D5F144 /* Util_LatencyTest.h */, - E8AA41051907224700D5F144 /* Util_LatencyTest2.cpp */, - E8AA41061907224700D5F144 /* Util_LatencyTest2.h */, E8AA41071907224700D5F144 /* Util_Render_Stereo.cpp */, E8AA41081907224700D5F144 /* Util_Render_Stereo.h */, ); @@ -383,12 +467,19 @@ 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 */, - E8AA41BD190724E600D5F144 /* CAPI_GlobalState.cpp */, - E8AA41BE190724E600D5F144 /* CAPI_GlobalState.h */, + E8094D0D196FAE8800937940 /* CAPI_HSWDisplay.cpp */, + E8094D0E196FAE8800937940 /* CAPI_HSWDisplay.h */, E8AA41BF190724E600D5F144 /* CAPI_HMDRenderState.cpp */, E8AA41C0190724E600D5F144 /* CAPI_HMDRenderState.h */, E8AA41C1190724E600D5F144 /* CAPI_HMDState.cpp */, @@ -418,66 +509,76 @@ 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 */, - E8AA41101907224700D5F144 /* Util_LatencyTest.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 */, - E8AA416F190722BB00D5F144 /* OVR_DeviceMessages.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 */, - E8AA418B190722BB00D5F144 /* OVR_SensorCalibration.h in Headers */, E886FEA0190737FA00D5DB45 /* OVR_CAPI.h in Headers */, - E8AA417F190722BB00D5F144 /* OVR_OSX_DeviceManager.h in Headers */, - E8AA4170190722BB00D5F144 /* OVR_HIDDevice.h in Headers */, - E8AA419A190722BB00D5F144 /* OVR_ThreadCommandQueue.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 */, - E8AA418D190722BB00D5F144 /* OVR_SensorFilter.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 */, - E8754F81190F1B71005FD401 /* OVR_Recording.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 */, - E8AA41E6190724E600D5F144 /* CAPI_GlobalState.h in Headers */, - E8AA416E190722BB00D5F144 /* OVR_DeviceImpl.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 */, - E8AA4194190722BB00D5F144 /* OVR_SensorImpl.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 */, - E8AA4172190722BB00D5F144 /* OVR_HIDDeviceImpl.h in Headers */, - E8AA416C190722BB00D5F144 /* OVR_DeviceHandle.h in Headers */, - E8AA4196190722BB00D5F144 /* OVR_SensorTimeFilter.h in Headers */, - E8AA418F190722BB00D5F144 /* OVR_SensorFusion.h in Headers */, - E8AA4181190722BB00D5F144 /* OVR_OSX_HIDDevice.h in Headers */, E8AA4174190722BB00D5F144 /* OVR_JSON.h in Headers */, - E8AA4183190722BB00D5F144 /* OVR_OSX_HMDDevice.h in Headers */, - E8AA4171190722BB00D5F144 /* OVR_HIDDeviceBase.h in Headers */, - E8AA4190190722BB00D5F144 /* OVR_SensorFusionDebug.h in Headers */, - E8AA4176190722BB00D5F144 /* OVR_LatencyTestImpl.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 */, - E8AA4189190722BB00D5F144 /* OVR_Sensor2ImplUtil.h in Headers */, + E87DF4AC196A2161005E383C /* Service_NetClient.h in Headers */, + E87DF49D196A20E9005E383C /* OVR_Socket.h in Headers */, E8AA40EC1907221900D5F144 /* OVR_String.h in Headers */, - E8AA4169190722BB00D5F144 /* OVR_Device.h in Headers */, E8AA4186190722BB00D5F144 /* OVR_Profile.h in Headers */, - E8AA4188190722BB00D5F144 /* OVR_Sensor2Impl.h in Headers */, E8AA40EA1907221900D5F144 /* OVR_Std.h in Headers */, - E8AA41121907224700D5F144 /* Util_LatencyTest2.h in Headers */, + E87DF499196A20E9005E383C /* OVR_RPC1.h in Headers */, E8AA40E81907221900D5F144 /* OVR_RefCount.h in Headers */, E8AA40DA1907221900D5F144 /* OVR_Deque.h in Headers */, - E8AA416A190722BB00D5F144 /* OVR_DeviceConstants.h in Headers */, E8AA40FB1907221900D5F144 /* OVR_UTF8Util.h in Headers */, - E8AA4192190722BB00D5F144 /* OVR_SensorImpl_Common.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 */, ); @@ -534,55 +635,62 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E8AA4175190722BB00D5F144 /* OVR_LatencyTestImpl.cpp in Sources */, E8AA41E3190724E600D5F144 /* CAPI_FrameTimeManager.cpp in Sources */, - E8AA4199190722BB00D5F144 /* OVR_ThreadCommandQueue.cpp in Sources */, - E8AA417E190722BB00D5F144 /* OVR_OSX_DeviceManager.cpp in Sources */, E8AA41131907224700D5F144 /* Util_Render_Stereo.cpp in Sources */, - E8AA4182190722BB00D5F144 /* OVR_OSX_HMDDevice.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 */, - E8F1F13E1921911D000EC969 /* OVR_Recording.cpp in Sources */, - E8AA41111907224700D5F144 /* Util_LatencyTest2.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 */, - E8AA4193190722BB00D5F144 /* OVR_SensorImpl.cpp in Sources */, E8AA41F6190724E600D5F144 /* CAPI_GL_DistortionRenderer.cpp in Sources */, E8AA40DD1907221900D5F144 /* OVR_FileFILE.cpp in Sources */, - E8AA410F1907224700D5F144 /* Util_LatencyTest.cpp in Sources */, E8AA40E51907221900D5F144 /* OVR_Math.cpp in Sources */, - E8AA4180190722BB00D5F144 /* OVR_OSX_HIDDevice.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 */, - E8AA416B190722BB00D5F144 /* OVR_DeviceHandle.cpp in Sources */, - E8AA418C190722BB00D5F144 /* OVR_SensorFilter.cpp in Sources */, + E87DF490196A20E9005E383C /* OVR_BitStream.cpp in Sources */, E886FE9F190737FA00D5DB45 /* OVR_CAPI.cpp in Sources */, E8AA40E71907221900D5F144 /* OVR_RefCount.cpp in Sources */, - E8AA416D190722BB00D5F144 /* OVR_DeviceImpl.cpp in Sources */, - E8AA41E5190724E600D5F144 /* CAPI_GlobalState.cpp in Sources */, - E8AA418A190722BB00D5F144 /* OVR_SensorCalibration.cpp in Sources */, - E8AA418E190722BB00D5F144 /* OVR_SensorFusion.cpp in Sources */, - E8AA4184190722BB00D5F144 /* OVR_OSX_SensorDevice.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 */, - E8AA4187190722BB00D5F144 /* OVR_Sensor2Impl.cpp in Sources */, E8AA41F8190724E600D5F144 /* CAPI_GL_Util.cpp in Sources */, - E8AA4191190722BB00D5F144 /* OVR_SensorImpl_Common.cpp in Sources */, E8AA40EE1907221900D5F144 /* OVR_String_PathUtil.cpp in Sources */, - E8AA4195190722BB00D5F144 /* OVR_SensorTimeFilter.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; }; @@ -671,19 +779,19 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; + 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.7; - OBJROOT = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; + MACOSX_DEPLOYMENT_TARGET = 10.8; + OBJROOT = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = libovr; - SYMROOT = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; + SYMROOT = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; }; name = Debug; }; @@ -691,16 +799,16 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; + 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 = YES; - MACOSX_DEPLOYMENT_TARGET = 10.7; - OBJROOT = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; + 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/Xcode/$(CONFIGURATION)"; + SYMROOT = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; }; name = Release; }; diff --git a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj index 37b304b..00d8a1b 100644 --- a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj +++ b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj @@ -21,22 +21,40 @@ - + + + + - + + + + + + + + + + + + + + + + @@ -44,8 +62,9 @@ - + + @@ -55,50 +74,46 @@ + + + + + + + + - - - - - - - - + - - - - - - - - - - - + - - - - - - + + + + + + - - + + + + - + + + + true true @@ -111,19 +126,29 @@ true true - - + + + + + + + + + + + + @@ -133,123 +158,151 @@ + + + + + + + - - - - - - - - - - - + - - - - - - + + + - - + + + - + Document - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - + Document - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - - - Document call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(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)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - + Document - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" %(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)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(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 - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" %(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)" - %(RelativeDir)%(Filename).h - + Document - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(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 - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" diff --git a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters index 6fd4b16..f4f3648 100644 --- a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters +++ b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters @@ -1,40 +1,50 @@  - - - - - - - - - - - - - - - - - - - - + Util - + + CAPI + + + CAPI + + + CAPI + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI + + Util - - Kernel + + Util - - Kernel + + CAPI\GL - - Kernel + + CAPI\GL + + + + + Kernel @@ -53,6 +63,9 @@ Kernel + + Kernel + Kernel @@ -80,105 +93,148 @@ Kernel - - CAPI + + Kernel - - CAPI + + Kernel - - CAPI + + Kernel - - CAPI + + Kernel - - CAPI\D3D1X + + Net - - CAPI\D3D1X + + Net - - CAPI\D3D1X + + Net - - CAPI\D3D1X + + Net - - + + Net + + + Net + + + Net + + + Tracking + + + Displays + + + Displays + + + Displays + + + Service + + + Service + + + Displays + + + Util + + CAPI - + CAPI\D3D1X - + CAPI\D3D1X - - Util + + CAPI\GL - - Util + + CAPI - + Util - - CAPI\GL + + CAPI\D3D9 - + + CAPI\D3D9 + + + CAPI\D3D9 + + + Kernel + + + Util + + CAPI\GL - - - - - - - - - - - - - - - - - - - - - - - - - - Util - - Util + + CAPI - - Kernel + + CAPI - - Kernel + + CAPI - - Kernel + + CAPI\D3D1X - - Kernel + + CAPI\D3D1X - - Kernel + + CAPI\D3D1X - + + CAPI\D3D1X + + + CAPI + + + Util + + + Util + + + CAPI\GL + + + CAPI\GL + + + + + + + + + Kernel @@ -205,9 +261,15 @@ Kernel + + Kernel + Kernel + + Kernel + Kernel @@ -235,56 +297,132 @@ Kernel - - - CAPI + + Kernel - - CAPI + + Kernel - - CAPI + + Kernel - - CAPI + + Kernel - - CAPI\D3D1X + + Kernel - - CAPI\D3D1X + + 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\D3D1X + + CAPI\D3D9 - - Util + + CAPI\D3D9 - + + CAPI\GL + + + Kernel + + Util - + CAPI\GL - + CAPI\GL - - @@ -299,37 +437,64 @@ {0ee0029b-0b10-4ad6-a10c-7bf4ccefdf54} - - {191043aa-7805-44f0-a0a4-02799289365c} - {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\Shaders + + CAPI\D3D1X\Shaders + + + CAPI\D3D1X\Shaders + + + CAPI\D3D1X\Shaders + + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\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 index 0e8505c..94bee8c 100644 --- a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj +++ b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj @@ -21,22 +21,40 @@ - + + + + - + + + + + + + + + + + + + + + + @@ -44,61 +62,59 @@ - + + + + + + + + + + + - - - - - - - - + - - - - - - - - - - - + - - - - - - + + + + + + - - + + + + - + + + + true true @@ -111,145 +127,184 @@ true true - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + - - - - - - + + + - - + + + - + Document - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - + Document - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - - - Document call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(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)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - + Document - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" %(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)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(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 - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" %(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)" - %(RelativeDir)%(Filename).h - + Document - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(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 - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" diff --git a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters index 54d430d..5bf7077 100644 --- a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters +++ b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters @@ -1,31 +1,50 @@  - - - - - - - - - - - - - - - - - - - - + Util - + + CAPI + + + CAPI + + + CAPI + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI + + Util + + Util + + + CAPI\GL + + + CAPI\GL + + + + + + Kernel @@ -35,6 +54,9 @@ Kernel + + Kernel + Kernel @@ -53,6 +75,9 @@ Kernel + + Kernel + Kernel @@ -80,89 +105,138 @@ Kernel - - CAPI + + Displays - - CAPI + + Displays - - CAPI + + Displays - - CAPI + + Net - - CAPI\D3D1X + + Net - - CAPI\D3D1X + + Net - - CAPI\D3D1X + + Net - - CAPI\D3D1X + + Net - - + + Net + + + Net + + + Service + + + Service + + + Tracking + + + Displays + + + Util + + + Kernel + + CAPI - + CAPI\D3D1X - + CAPI\D3D1X - - Util + + CAPI\GL + + + CAPI - + Util - + + CAPI\D3D9 + + + CAPI\D3D9 + + + CAPI\D3D9 + + Util - - CAPI\GL + + Util - + CAPI\GL - - - - - - - - - - - - - - - - - - - - - - - - - - Util - + + CAPI + + + CAPI + + + CAPI + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI\D3D1X + + + CAPI + + + Util + + Util + + CAPI\GL + + + CAPI\GL + + + + + + + + Kernel @@ -178,9 +252,18 @@ Kernel + + Kernel + Kernel + + Kernel + + + Kernel + Kernel @@ -205,9 +288,15 @@ Kernel + + Kernel + Kernel + + Kernel + Kernel @@ -235,56 +324,111 @@ Kernel - - - CAPI + + Displays - - CAPI + + Displays - - CAPI + + Displays - - CAPI + + Displays - - CAPI\D3D1X + + Net - - CAPI\D3D1X + + 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\D3D1X + + CAPI\D3D9 - + + CAPI\D3D9 + + + CAPI\GL + + Util - + Util - + CAPI\GL - + CAPI\GL - - @@ -299,37 +443,64 @@ {0ee0029b-0b10-4ad6-a10c-7bf4ccefdf54} - - {191043aa-7805-44f0-a0a4-02799289365c} - {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\Shaders + + CAPI\D3D1X\Shaders + + + CAPI\D3D1X\Shaders + + + CAPI\D3D1X\Shaders + + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\Shaders + + CAPI\D3D1X\Shaders - - CAPI\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 index ada929d..6a271d4 100644 --- a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj +++ b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj @@ -21,22 +21,41 @@ - + + + + - + + + + + + + + + + + + + + + + + @@ -44,61 +63,59 @@ - + + + + + + + + + + + - - - - - - - - + - - - - - - - - - - - + - - - - - - + + + + + + - - + + + + - + + + + true true @@ -111,144 +128,183 @@ true true - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + - - - - - - + + + - - + + + - + Document - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - + Document - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h + 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)" - %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h - + Document - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(RelativeDir)%(Filename).h call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - + Document - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" %(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)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" %(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 - - - 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)" + + + + + 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 @@ -350,6 +406,7 @@ true MultiThreadedDebug ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) + false Windows @@ -373,6 +430,7 @@ MultiThreadedDebug ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) false + false Windows diff --git a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters index 3216bbf..5b873a2 100644 --- a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters +++ b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters @@ -1,38 +1,12 @@  - - - - - - - - - - - - - - - - - - - - CAPI\D3D1X CAPI\D3D1X - - CAPI\D3D1X - - - CAPI\D3D1X - CAPI\D3D1X @@ -45,15 +19,32 @@ CAPI - - CAPI - CAPI CAPI + + Util + + + Util + + + Util + + + CAPI\GL + + + CAPI\GL + + + + + + Kernel @@ -63,6 +54,9 @@ Kernel + + Kernel + Kernel @@ -81,6 +75,9 @@ Kernel + + Kernel + Kernel @@ -108,67 +105,98 @@ Kernel - - Util + + Net - - Util + + Net - - Util + + Net - - Util + + 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 @@ -181,15 +209,34 @@ CAPI - - CAPI - CAPI CAPI + + Util + + + Util + + + Util + + + CAPI\GL + + + CAPI\GL + + + + + + + + Kernel @@ -205,9 +252,18 @@ Kernel + + Kernel + Kernel + + Kernel + + + Kernel + Kernel @@ -232,9 +288,15 @@ Kernel + + Kernel + Kernel + + Kernel + Kernel @@ -262,63 +324,119 @@ Kernel - - Util + + 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 - - - - - - CAPI\Shaders - - - CAPI\Shaders - - - CAPI\Shaders - - - CAPI\Shaders - - - CAPI\Shaders - - - CAPI\Shaders - - - CAPI\Shaders - - - CAPI\Shaders - {42ff86e1-b618-4432-99ce-e6b92c7460eb} - - {a65a3889-6d00-4a76-acfe-6db1249f104d} - {77e1d16e-00a1-4130-8ee6-f81d1e850859} @@ -331,5 +449,64 @@ {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/Src/CAPI/CAPI_DistortionRenderer.cpp b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp index 613d8fb..78e49e7 100644 --- a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp @@ -5,16 +5,16 @@ Content : Combines all of the rendering state associated with the HMD Created : February 2, 2014 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -38,7 +38,7 @@ limitations under the License. #undef OVR_D3D_VERSION #define OVR_D3D_VERSION 9 -#include "D3D1X/CAPI_D3D9_DistortionRenderer.h" +#include "D3D9/CAPI_D3D9_DistortionRenderer.h" #undef OVR_D3D_VERSION #endif @@ -68,6 +68,90 @@ DistortionRenderer::CreateFunc DistortionRenderer::APICreateRegistry[ovrRenderAP #endif }; +void DistortionRenderer::SetLatencyTestColor(unsigned char* color) +{ + if(color) + { + LatencyTestDrawColor[0] = color[0]; + LatencyTestDrawColor[1] = color[1]; + LatencyTestDrawColor[2] = color[2]; + } + + LatencyTestActive = color != NULL; +} + +void DistortionRenderer::SetLatencyTest2Color(unsigned char* color) +{ + if(color) + { + LatencyTest2DrawColor[0] = color[0]; + LatencyTest2DrawColor[1] = color[1]; + LatencyTest2DrawColor[2] = color[2]; + } + + LatencyTest2Active = color != NULL; +} + +void DistortionRenderer::GetOverdriveScales(float& outRiseScale, float& outFallScale) +{ + outRiseScale = 0.1f; + outFallScale = 0.05f; // falling issues are hardly visible +} + +double DistortionRenderer::WaitTillTime(double absTime) +{ + double initialTime = ovr_GetTimeInSeconds(); + if (initialTime >= absTime) + return 0.0; + + double newTime = initialTime; + + while (newTime < absTime) + { +// TODO: Needs further testing before enabling it on all Windows configs +#if 0 //def OVR_OS_WIN32 + double remainingWaitTime = absTime - newTime; + + // don't yield if <2ms + if(remainingWaitTime > 0.002) + { + // round down wait time to closest 1 ms + int roundedWaitTime = (remainingWaitTime * 1000); + + waitableTimerInterval.QuadPart = -10000LL; // 10000 * 100 ns = 1 ms + waitableTimerInterval.QuadPart *= roundedWaitTime; + + SetWaitableTimer(timer, &waitableTimerInterval, 0, NULL, NULL, TRUE); + DWORD waitResult = WaitForSingleObject(timer, roundedWaitTime + 3); // give 3 ms extra time + OVR_UNUSED(waitResult); + +#ifdef OVR_BUILD_DEBUG + double sleptTime = ovr_GetTimeInSeconds() - newTime; + // Make sure we didn't sleep too long and it is reliable, otherwise we might miss v-sync causing a stutter + if (sleptTime > (roundedWaitTime + 2) * 0.001) + { + OVR_DEBUG_LOG_TEXT( + ("[DistortionRenderer::WaitTillTime] Sleep interval too long: %f\n", sleptTime)); + } + else + { + OVR_ASSERT(WAIT_OBJECT_0 == waitResult); + } +#endif + } + else +#endif + { + for (int j = 0; j < 5; j++) + OVR_PROCESSOR_PAUSE(); + } + + newTime = ovr_GetTimeInSeconds(); + } + + // How long we waited + return newTime - initialTime; +} }} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h index a256bc6..0c93387 100644 --- a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h @@ -5,16 +5,16 @@ Content : Abstract interface for platform-specific rendering of distortion Created : February 2, 2014 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -30,6 +30,7 @@ limitations under the License. #include "CAPI_HMDRenderState.h" #include "CAPI_FrameTimeManager.h" +typedef void (*PostDistortionCallback)(void* pRenderContext); namespace OVR { namespace CAPI { @@ -48,35 +49,52 @@ public: DistortionRenderer(ovrRenderAPIType api, ovrHmd hmd, FrameTimeManager& timeManager, - const HMDRenderState& renderState) - : RenderAPI(api), HMD(hmd), TimeManager(timeManager), RState(renderState) - { } + 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() - { } + { + } // 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, - unsigned distortionCaps) = 0; + virtual bool Initialize(const ovrRenderAPIConfig* apiConfig) = 0; // 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, ovrTexture* eyeTexture) = 0; + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture) = 0; // Finish the frame, optionally swapping buffers. // Many implementations may actually apply the distortion here. - virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, - unsigned char* latencyTester2DrawColor) = 0; + virtual void EndFrame(bool swapBuffers) = 0; + void RegisterPostDistortionCallback(PostDistortionCallback postDistortionCallback) + { + RegisteredPostDistortionCallback = postDistortionCallback; + } + // Stores the current graphics pipeline state so it can be restored later. - void SaveGraphicsState() { if (!(RState.EnabledHmdCaps & ovrHmdCap_NoRestore)) GfxState->Save(); } + void SaveGraphicsState() { if (GfxState && !(RState.DistortionCaps & ovrDistortionCap_NoRestore)) GfxState->Save(); } // Restores the saved graphics pipeline state. - void RestoreGraphicsState() { if (!(RState.EnabledHmdCaps & ovrHmdCap_NoRestore)) GfxState->Restore(); } + void RestoreGraphicsState() { if (GfxState && !(RState.DistortionCaps & ovrDistortionCap_NoRestore)) GfxState->Restore(); } // *** Creation Factory logic @@ -89,8 +107,40 @@ public: static CreateFunc APICreateRegistry[ovrRenderAPI_Count]; -protected: + // Color is expected to be 3 byte RGB + void SetLatencyTestColor(unsigned char* color); + void SetLatencyTest2Color(unsigned char* color); +protected: + // 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? + static const int NumOverdriveTextures = 2; + int LastUsedOverdriveTextureIndex; + + bool LatencyTestActive; + unsigned char LatencyTestDrawColor[3]; + bool LatencyTest2Active; + unsigned char LatencyTest2DrawColor[3]; + + bool IsOverdriveActive() + { + // 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); + } + + void GetOverdriveScales(float& outRiseScale, float& outFallScale); + + double WaitTillTime(double absTime); + +#ifdef OVR_OS_WIN32 + HANDLE timer; + LARGE_INTEGER waitableTimerInterval; +#endif + class GraphicsState : public RefCountBase { public: @@ -108,11 +158,10 @@ protected: FrameTimeManager& TimeManager; const HMDRenderState& RState; Ptr GfxState; + PostDistortionCallback RegisteredPostDistortionCallback; }; }} // namespace OVR::CAPI #endif // OVR_CAPI_DistortionRenderer_h - - diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp index 3e776c3..8f44063 100644 --- a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp +++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp @@ -5,16 +5,16 @@ 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. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -26,6 +26,7 @@ limitations under the License. #include "CAPI_FrameTimeManager.h" +#include "../Kernel/OVR_Log.h" namespace OVR { namespace CAPI { @@ -39,15 +40,19 @@ FrameLatencyTracker::FrameLatencyTracker() Reset(); } + void FrameLatencyTracker::Reset() { TrackerEnabled = true; WaitMode = SampleWait_Zeroes; - FrameIndex = 0; MatchCount = 0; + memset(FrameEndTimes, 0, sizeof(FrameEndTimes)); + FrameIndex = 0; + //FrameDeltas RenderLatencySeconds = 0.0; TimewarpLatencySeconds = 0.0; - + LatencyRecordTime = 0.0; + FrameDeltas.Clear(); } @@ -162,10 +167,18 @@ void FrameLatencyTracker::MatchRecord(const Util::FrameTimeRecordSet &r) if (deltaSeconds > 0.0) { FrameDeltas.AddTimeDelta(deltaSeconds); - LatencyRecordTime = scanoutFrame.TimeSeconds; - RenderLatencySeconds = scanoutFrame.TimeSeconds - renderFrame.RenderIMUTimeSeconds; - TimewarpLatencySeconds = (renderFrame.TimewarpIMUTimeSeconds == 0.0) ? 0.0 : - (scanoutFrame.TimeSeconds - renderFrame.TimewarpIMUTimeSeconds); + + // 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; @@ -189,36 +202,64 @@ void FrameLatencyTracker::MatchRecord(const Util::FrameTimeRecordSet &r) } } +bool FrameLatencyTracker::IsLatencyTimingAvailable() +{ + return ovr_GetTimeInSeconds() < (LatencyRecordTime + 2.0); +} -void FrameLatencyTracker::GetLatencyTimings(float latencies[3]) +void FrameLatencyTracker::GetLatencyTimings(float& latencyRender, float& latencyTimewarp, float& latencyPostPresent) { - if (ovr_GetTimeInSeconds() > (LatencyRecordTime + 2.0)) + if (!IsLatencyTimingAvailable()) { - latencies[0] = 0.0f; - latencies[1] = 0.0f; - latencies[2] = 0.0f; + latencyRender = 0.0f; + latencyTimewarp = 0.0f; + latencyPostPresent = 0.0f; } else { - latencies[0] = (float)RenderLatencySeconds; - latencies[1] = (float)TimewarpLatencySeconds; - latencies[2] = (float)FrameDeltas.GetMedianTimeDelta(); + latencyRender = (float)RenderLatencySeconds; + latencyTimewarp = (float)TimewarpLatencySeconds; + latencyPostPresent = (float)FrameDeltas.GetMedianTimeDelta(); } } - - -//------------------------------------------------------------------------------------- -FrameTimeManager::FrameTimeManager(bool vsyncEnabled) - : VsyncEnabled(vsyncEnabled), DynamicPrediction(true), SdkRender(false), - FrameTiming() -{ - RenderIMUTimeSeconds = 0.0; - TimewarpIMUTimeSeconds = 0.0; - - // HACK: SyncToScanoutDelay observed close to 1 frame in video cards. - // Overwritten by dynamic latency measurement on DK2. - VSyncToScanoutDelay = 0.013f; + +//------------------------------------------------------------------------------------- +// ***** 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; } @@ -242,11 +283,15 @@ void FrameTimeManager::ResetFrameTiming(unsigned frameIndex, 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; @@ -293,7 +338,7 @@ double FrameTimeManager::calcScreenDelay() const else if ( DynamicPrediction && (ScreenLatencyTracker.FrameDeltas.GetCount() > 3) && (measuredVSyncToScanout = ScreenLatencyTracker.FrameDeltas.GetMedianTimeDelta(), - (measuredVSyncToScanout > 0.0001) && (measuredVSyncToScanout < 0.06)) ) + (measuredVSyncToScanout > -0.0001) && (measuredVSyncToScanout < 0.06)) ) { screenDelay += measuredVSyncToScanout; } @@ -305,8 +350,7 @@ double FrameTimeManager::calcScreenDelay() const return screenDelay; } - -double FrameTimeManager::calcTimewarpWaitDelta() const +double FrameTimeManager::calcTimewarpWaitDelta() const { // If timewarp timing hasn't been calculated, we should wait. if (!VsyncEnabled) @@ -316,15 +360,34 @@ double FrameTimeManager::calcTimewarpWaitDelta() const { if (NeedDistortionTimeMeasurement()) return 0.0; - return -(DistortionRenderTimes.GetMedianTimeDelta() + 0.002); + 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.003; -} + 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, @@ -407,6 +470,9 @@ 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(); @@ -425,6 +491,16 @@ void FrameTimeManager::EndFrame() 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(); } @@ -433,15 +509,13 @@ void FrameTimeManager::EndFrame() 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 (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, @@ -454,42 +528,62 @@ FrameTimeManager::Timing FrameTimeManager::GetFrameTiming(unsigned frameIndex) double thisFrameTime = frameTiming.NextFrameTime + double(frameDelta-1) * frameTiming.Inputs.FrameDelta; // Don't run away too far into the future beyond rendering. - OVR_ASSERT(frameDelta < 6); + 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) +double FrameTimeManager::GetEyePredictionTime(ovrEyeType eye, unsigned int frameIndex) { if (VsyncEnabled) { - return FrameTiming.EyeRenderTimes[eye]; + 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; } -Transformf FrameTimeManager::GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye) +ovrTrackingState FrameTimeManager::GetEyePredictionTracking(ovrHmd hmd, ovrEyeType eye, unsigned int frameIndex) { - double eyeRenderTime = GetEyePredictionTime(eye); - ovrSensorState eyeState = ovrHmd_GetSensorState(hmd, eyeRenderTime); + 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; +} -// EyeRenderPoses[eye] = eyeState.Predicted.Pose; +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) - RenderIMUTimeSeconds = eyeState.Recorded.TimeInSeconds; + { + // TODO: Figure out why this are not as accurate as ovr_GetTimeInSeconds() + //RenderIMUTimeSeconds = eyeState.RawSensorData.TimeInSeconds; + RenderIMUTimeSeconds = ovr_GetTimeInSeconds(); + } - return eyeState.Predicted.Pose; + return eyeState.HeadPose.ThePose; } - void FrameTimeManager::GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2]) { if (VsyncEnabled) @@ -511,7 +605,8 @@ void FrameTimeManager::GetTimewarpPredictions(ovrEyeType eye, double timewarpSta void FrameTimeManager::GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eyeId, - ovrPosef renderPose, ovrMatrix4f twmOut[2]) + ovrPosef renderPose, ovrMatrix4f twmOut[2], + double debugTimingOffsetInSeconds) { if (!hmd) { @@ -520,17 +615,29 @@ void FrameTimeManager::GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eyeId, 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; + - ovrSensorState startState = ovrHmd_GetSensorState(hmd, timewarpStartEnd[0]); - ovrSensorState endState = ovrHmd_GetSensorState(hmd, timewarpStartEnd[1]); + //HMDState* p = (HMDState*)hmd; + ovrTrackingState startState = ovrHmd_GetTrackingState(hmd, timewarpStartEnd[0]); + ovrTrackingState endState = ovrHmd_GetTrackingState(hmd, timewarpStartEnd[1]); if (TimewarpIMUTimeSeconds == 0.0) - TimewarpIMUTimeSeconds = startState.Recorded.TimeInSeconds; + { + // TODO: Figure out why this are not as accurate as ovr_GetTimeInSeconds() + //TimewarpIMUTimeSeconds = startState.RawSensorData.TimeInSeconds; + TimewarpIMUTimeSeconds = ovr_GetTimeInSeconds(); + } - Quatf quatFromStart = startState.Predicted.Pose.Orientation; - Quatf quatFromEnd = endState.Predicted.Pose.Orientation; + Quatf quatFromStart = startState.HeadPose.ThePose.Orientation; + Quatf quatFromEnd = endState.HeadPose.ThePose.Orientation; Quatf quatFromEye = renderPose.Orientation; //EyeRenderPoses[eyeId].Orientation; - quatFromEye.Invert(); + quatFromEye.Invert(); // because we need the view matrix, not the camera matrix Quatf timewarpStartQuat = quatFromEye * quatFromStart; Quatf timewarpEndQuat = quatFromEye * quatFromEnd; @@ -578,7 +685,7 @@ bool FrameTimeManager::NeedDistortionTimeMeasurement() const { if (!VsyncEnabled) return false; - return DistortionRenderTimes.GetCount() < 10; + return DistortionRenderTimes.GetCount() < DistortionRenderTimes.Capacity; } @@ -586,6 +693,9 @@ void FrameTimeManager::AddDistortionTimeMeasurement(double distortionTimeSecond { 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) @@ -597,11 +707,11 @@ void FrameTimeManager::AddDistortionTimeMeasurement(double distortionTimeSecond void FrameTimeManager::UpdateFrameLatencyTrackingAfterEndFrame( - unsigned char frameLatencyTestColor, + unsigned char frameLatencyTestColor[3], const Util::FrameTimeRecordSet& rs) { // FrameTiming.NextFrameTime in this context (after EndFrame) is the end frame time. - ScreenLatencyTracker.SaveDrawColor(frameLatencyTestColor, + ScreenLatencyTracker.SaveDrawColor(frameLatencyTestColor[0], FrameTiming.NextFrameTime, RenderIMUTimeSeconds, TimewarpIMUTimeSeconds); @@ -618,6 +728,118 @@ void FrameTimeManager::UpdateFrameLatencyTrackingAfterEndFrame( } +//----------------------------------------------------------------------------------- +//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 @@ -634,40 +856,89 @@ void TimeDeltaCollector::AddTimeDelta(double timeSeconds) Count--; } TimeBufferSeconds[Count++] = timeSeconds; + + ReCalcMedian = true; } -double TimeDeltaCollector::GetMedianTimeDelta() const +// KevinJ: Better median function +double CalculateListMedianRecursive(const double inputList[TimeDeltaCollector::Capacity], int inputListLength, int lessThanSum, int greaterThanSum) { - double SortedList[Capacity]; - bool used[Capacity]; - - memset(used, 0, sizeof(used)); - SortedList[0] = 0.0; // In case Count was 0... + 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; - // Probably the slowest way to find median... - for (int i=0; i LocklessTiming; - + LocklessUpdater LocklessTiming; // IMU Read timings double RenderIMUTimeSeconds; @@ -260,5 +325,3 @@ private: }} // namespace OVR::CAPI #endif // OVR_CAPI_FrameTimeManager_h - - diff --git a/LibOVR/Src/CAPI/CAPI_GlobalState.cpp b/LibOVR/Src/CAPI/CAPI_GlobalState.cpp deleted file mode 100644 index 2ed1794..0000000 --- a/LibOVR/Src/CAPI/CAPI_GlobalState.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_GlobalState.cpp -Content : Maintains global state of the CAPI -Created : January 24, 2014 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_GlobalState.h" - -namespace OVR { namespace CAPI { - - -//------------------------------------------------------------------------------------- -// Open Questions / Notes - -// 2. Detect HMDs. -// Challenge: If we do everything through polling, it would imply we want all the devices -// initialized. However, there may be multiple rifts, extra sensors, etc, -// which shouldn't be allocated. -// - -// How do you reset orientation Quaternion? -// Can you change IPD? - - - -//------------------------------------------------------------------------------------- -// ***** OVRGlobalState - -// Global instance -GlobalState* GlobalState::pInstance = 0; - - -GlobalState::GlobalState() -{ - pManager = *DeviceManager::Create(); - // Handle the DeviceManager's messages - pManager->AddMessageHandler( this ); - EnumerateDevices(); - - // PhoneSensors::Init(); -} - -GlobalState::~GlobalState() -{ - RemoveHandlerFromDevices(); - OVR_ASSERT(HMDs.IsEmpty()); -} - -int GlobalState::EnumerateDevices() -{ - // Need to use separate lock for device enumeration, as pManager->GetHandlerLock() - // would produce deadlocks here. - Lock::Locker lock(&EnumerationLock); - - EnumeratedDevices.Clear(); - - DeviceEnumerator e = pManager->EnumerateDevices(); - while(e.IsAvailable()) - { - EnumeratedDevices.PushBack(DeviceHandle(e)); - e.Next(); - } - - return (int)EnumeratedDevices.GetSize(); -} - - -HMDDevice* GlobalState::CreateDevice(int index) -{ - Lock::Locker lock(&EnumerationLock); - - if (index >= (int)EnumeratedDevices.GetSize()) - return 0; - return EnumeratedDevices[index].CreateDeviceTyped(); -} - - -void GlobalState::AddHMD(HMDState* hmd) -{ - Lock::Locker lock(pManager->GetHandlerLock()); - HMDs.PushBack(hmd); -} -void GlobalState::RemoveHMD(HMDState* hmd) -{ - Lock::Locker lock(pManager->GetHandlerLock()); - hmd->RemoveNode(); -} - -void GlobalState::NotifyHMDs_AddDevice(DeviceType deviceType) -{ - Lock::Locker lock(pManager->GetHandlerLock()); - for(HMDState* hmd = HMDs.GetFirst(); !HMDs.IsNull(hmd); hmd = hmd->pNext) - hmd->NotifyAddDevice(deviceType); -} - -void GlobalState::OnMessage(const Message& msg) -{ - if (msg.Type == Message_DeviceAdded || msg.Type == Message_DeviceRemoved) - { - if (msg.pDevice == pManager) - { - const MessageDeviceStatus& statusMsg = - static_cast(msg); - - if (msg.Type == Message_DeviceAdded) - { - //LogText("OnMessage DeviceAdded.\n"); - - // We may have added a sensor/other device; notify any HMDs that might - // need it to check for it later. - NotifyHMDs_AddDevice(statusMsg.Handle.GetType()); - } - else - { - //LogText("OnMessage DeviceRemoved.\n"); - } - } - } -} - - -}} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_GlobalState.h b/LibOVR/Src/CAPI/CAPI_GlobalState.h deleted file mode 100644 index 54ab8cc..0000000 --- a/LibOVR/Src/CAPI/CAPI_GlobalState.h +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_GlobalState.h -Content : Maintains global state of the CAPI -Created : January 24, 2013 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_GlobalState_h -#define OVR_CAPI_GlobalState_h - -#include "../OVR_CAPI.h" -#include "../OVR_Device.h" -#include "../Kernel/OVR_Timer.h" -#include "../Kernel/OVR_Math.h" - -#include "CAPI_HMDState.h" - -namespace OVR { namespace CAPI { - -//------------------------------------------------------------------------------------- -// ***** OVRGlobalState - -// Global DeviceManager state - singleton instance of this is created -// by ovr_Initialize(). -class GlobalState : public MessageHandler, public NewOverrideBase -{ -public: - GlobalState(); - ~GlobalState(); - - static GlobalState *pInstance; - - int EnumerateDevices(); - HMDDevice* CreateDevice(int index); - - // MessageHandler implementation - void OnMessage(const Message& msg); - - // Helpers used to keep track of HMDs and notify them of sensor changes. - void AddHMD(HMDState* hmd); - void RemoveHMD(HMDState* hmd); - void NotifyHMDs_AddDevice(DeviceType deviceType); - - const char* GetLastError() - { - return 0; - } - - DeviceManager* GetManager() { return pManager; } - -protected: - - Ptr pManager; - Lock EnumerationLock; - Array EnumeratedDevices; - - // Currently created hmds; protected by Manager lock. - List HMDs; -}; - -}} // namespace OVR::CAPI - -#endif - - diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp index 00bdea2..6630607 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp +++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp @@ -5,16 +5,16 @@ Content : Combines all of the rendering state associated with the HMD Created : February 2, 2014 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -32,58 +32,61 @@ namespace OVR { namespace CAPI { //------------------------------------------------------------------------------------- // ***** HMDRenderState - -HMDRenderState::HMDRenderState(ovrHmd hmd, Profile* userProfile, const OVR::HMDInfo& hmdInfo) - : HMD(hmd), HMDInfo(hmdInfo) -{ - RenderInfo = GenerateHmdRenderInfoFromHmdInfo( HMDInfo, userProfile ); - - Distortion[0] = CalculateDistortionRenderDesc(StereoEye_Left, RenderInfo, 0); - Distortion[1] = CalculateDistortionRenderDesc(StereoEye_Right, RenderInfo, 0); - - ClearColor[0] = ClearColor[1] = ClearColor[2] = ClearColor[3] =0.0f; - - EnabledHmdCaps = 0; -} - -HMDRenderState::~HMDRenderState() -{ -} - -ovrHmdDesc HMDRenderState::GetDesc() +ovrHmdDesc HMDRenderState::GetDesc() const { ovrHmdDesc d; memset(&d, 0, sizeof(d)); d.Type = ovrHmd_Other; - d.ProductName = HMDInfo.ProductName; - d.Manufacturer = HMDInfo.Manufacturer; - d.Resolution.w = HMDInfo.ResolutionInPixels.w; - d.Resolution.h = HMDInfo.ResolutionInPixels.h; - d.WindowsPos.x = HMDInfo.DesktopX; - d.WindowsPos.y = HMDInfo.DesktopY; - d.DisplayDeviceName = HMDInfo.DisplayDeviceName; - d.DisplayId = HMDInfo.DisplayId; + 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; + d.WindowsPos.y = OurHMDInfo.DesktopY; + d.DisplayDeviceName = OurHMDInfo.DisplayDeviceName; + d.DisplayId = OurHMDInfo.DisplayId; + d.VendorId = (short)OurHMDInfo.VendorId; + d.ProductId = (short)OurHMDInfo.ProductId; + d.FirmwareMajor = (short)OurHMDInfo.FirmwareMajor; + d.FirmwareMinor = (short)OurHMDInfo.FirmwareMinor; + d.CameraFrustumFarZInMeters = OurHMDInfo.CameraFrustumFarZInMeters; + d.CameraFrustumHFovInRadians = OurHMDInfo.CameraFrustumHFovInRadians; + d.CameraFrustumNearZInMeters = OurHMDInfo.CameraFrustumNearZInMeters; + d.CameraFrustumVFovInRadians = OurHMDInfo.CameraFrustumVFovInRadians; + + OVR_strcpy(d.SerialNumber, sizeof(d.SerialNumber), OurHMDInfo.PrintedSerial.ToCStr()); d.HmdCaps = ovrHmdCap_Present | ovrHmdCap_NoVSync; - d.SensorCaps = ovrSensorCap_YawCorrection | ovrSensorCap_Orientation; - d.DistortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette; + d.TrackingCaps = ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Orientation; + d.DistortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp | + ovrDistortionCap_Vignette | ovrDistortionCap_SRGB | + ovrDistortionCap_FlipInput | ovrDistortionCap_ProfileNoTimewarpSpinWaits | + ovrDistortionCap_HqDistortion | ovrDistortionCap_LinuxDevFullscreen; - if (strstr(HMDInfo.ProductName, "DK1")) +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + // TODO: this gets enabled for everything, but is only applicable for DX11+ + d.DistortionCaps |= ovrDistortionCap_ComputeShader; +#endif + + if( OurHMDInfo.InCompatibilityMode ) + d.HmdCaps |= ovrHmdCap_ExtendDesktop; + + if (strstr(OurHMDInfo.ProductName, "DK1")) { d.Type = ovrHmd_DK1; } - else if (strstr(HMDInfo.ProductName, "DK2")) + else if (strstr(OurHMDInfo.ProductName, "DK2")) { d.Type = ovrHmd_DK2; - d.HmdCaps |= ovrHmdCap_LowPersistence | - ovrHmdCap_LatencyTest | ovrHmdCap_DynamicPrediction; - d.SensorCaps |= ovrSensorCap_Position; + d.HmdCaps |= ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction; + d.TrackingCaps |= ovrTrackingCap_Position; + d.DistortionCaps |= ovrDistortionCap_Overdrive; } - DistortionRenderDesc& leftDistortion = Distortion[0]; - DistortionRenderDesc& rightDistortion = Distortion[1]; + const DistortionRenderDesc& leftDistortion = Distortion[0]; + const DistortionRenderDesc& rightDistortion = Distortion[1]; // The suggested FOV (assuming eye rotation) d.DefaultEyeFov[0] = CalculateFovFromHmdInfo(StereoEye_Left, leftDistortion, RenderInfo, OVR_DEFAULT_EXTRA_EYE_ROTATION); @@ -92,8 +95,8 @@ ovrHmdDesc HMDRenderState::GetDesc() // FOV extended across the entire screen d.MaxEyeFov[0] = GetPhysicalScreenFov(StereoEye_Left, leftDistortion); d.MaxEyeFov[1] = GetPhysicalScreenFov(StereoEye_Right, rightDistortion); - - if (HMDInfo.Shutter.Type == HmdShutter_RollingRightToLeft) + + if (OurHMDInfo.Shutter.Type == HmdShutter_RollingRightToLeft) { d.EyeRenderOrder[0] = ovrEye_Right; d.EyeRenderOrder[1] = ovrEye_Left; @@ -104,40 +107,37 @@ ovrHmdDesc HMDRenderState::GetDesc() d.EyeRenderOrder[1] = ovrEye_Right; } + // MA: Taking this out on purpose. + // 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; + return d; } -ovrSizei HMDRenderState::GetFOVTextureSize(int eye, ovrFovPort fov, float pixelsPerDisplayPixel) +ovrSizei HMDRenderState::GetFOVTextureSize(int eye, ovrFovPort fov, float pixelsPerDisplayPixel) const { OVR_ASSERT((unsigned)eye < 2); StereoEye seye = (eye == ovrEye_Left) ? StereoEye_Left : StereoEye_Right; return CalculateIdealPixelSize(seye, Distortion[eye], fov, pixelsPerDisplayPixel); } -ovrEyeRenderDesc HMDRenderState::calcRenderDesc(ovrEyeType eyeType, const ovrFovPort& fov) +ovrEyeRenderDesc HMDRenderState::CalcRenderDesc(ovrEyeType eyeType, const ovrFovPort& fov) const { - HmdRenderInfo& hmdri = RenderInfo; + const HmdRenderInfo& hmdri = RenderInfo; StereoEye eye = (eyeType == ovrEye_Left) ? StereoEye_Left : StereoEye_Right; ovrEyeRenderDesc e0; e0.Eye = eyeType; e0.Fov = fov; - e0.ViewAdjust = CalculateEyeVirtualCameraOffset(hmdri, eye, false); + e0.HmdToEyeViewOffset = CalculateEyeVirtualCameraOffset(hmdri, eye, false); e0.DistortedViewport = GetFramebufferViewport(eye, hmdri); e0.PixelsPerTanAngleAtCenter = Distortion[0].PixelsPerTanAngleAtCenter; return e0; } - -void HMDRenderState::setupRenderDesc( ovrEyeRenderDesc eyeRenderDescOut[2], - const ovrFovPort eyeFovIn[2] ) -{ - eyeRenderDescOut[0] = EyeRenderDesc[0] = calcRenderDesc(ovrEye_Left, eyeFovIn[0]); - eyeRenderDescOut[1] = EyeRenderDesc[1] = calcRenderDesc(ovrEye_Right, eyeFovIn[1]); -} - - }} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.h b/LibOVR/Src/CAPI/CAPI_HMDRenderState.h index a4e8d21..05c4e1b 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDRenderState.h +++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.h @@ -5,16 +5,16 @@ Content : Combines all of the rendering state associated with the HMD Created : February 2, 2014 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -30,64 +30,45 @@ limitations under the License. #include "../OVR_CAPI.h" #include "../Kernel/OVR_Math.h" #include "../Util/Util_Render_Stereo.h" - +#include "../Service/Service_NetSessionCommon.h" namespace OVR { namespace CAPI { using namespace OVR::Util::Render; + //------------------------------------------------------------------------------------- // ***** HMDRenderState // Combines all of the rendering setup information about one HMD. - -class HMDRenderState : public NewOverrideBase +// This structure only ever exists inside HMDState, but this +// declaration is in a separate file to reduce #include dependencies. +// All actual lifetime and update control is done by the surrounding HMDState. +struct HMDRenderState { - // Quiet assignment compiler warning. - void operator = (const HMDRenderState&) { } -public: - - HMDRenderState(ovrHmd hmd, Profile* userProfile, const OVR::HMDInfo& hmdInfo); - virtual ~HMDRenderState(); - - - // *** Rendering Setup + // Utility query functions. + ovrHmdDesc GetDesc() const; + ovrSizei GetFOVTextureSize(int eye, ovrFovPort fov, float pixelsPerDisplayPixel) const; + ovrEyeRenderDesc CalcRenderDesc(ovrEyeType eyeType, const ovrFovPort& fov) const; - // Delegated access APIs - ovrHmdDesc GetDesc(); - ovrSizei GetFOVTextureSize(int eye, ovrFovPort fov, float pixelsPerDisplayPixel); + HMDInfo OurHMDInfo; - ovrEyeRenderDesc calcRenderDesc(ovrEyeType eyeType, const ovrFovPort& fov); - - void setupRenderDesc(ovrEyeRenderDesc eyeRenderDescOut[2], - const ovrFovPort eyeFovIn[2]); -public: - - // HMDInfo shouldn't change, as its string pointers are passed out. - ovrHmd HMD; - const OVR::HMDInfo& HMDInfo; - - //const char* pLastError; - - HmdRenderInfo RenderInfo; - DistortionRenderDesc Distortion[2]; - ovrEyeRenderDesc EyeRenderDesc[2]; + HmdRenderInfo RenderInfo; + DistortionRenderDesc Distortion[2]; + ovrEyeRenderDesc EyeRenderDesc[2]; // Clear color used for distortion - float ClearColor[4]; + float ClearColor[4]; // Pose at which last time the eye was rendered, as submitted by EndEyeRender. - ovrPosef EyeRenderPoses[2]; + ovrPosef EyeRenderPoses[2]; // Capabilities passed to Configure. - unsigned EnabledHmdCaps; - unsigned DistortionCaps; + unsigned EnabledHmdCaps; + unsigned DistortionCaps; // enum ovrDistortionCaps }; }} // namespace OVR::CAPI - #endif // OVR_CAPI_HMDState_h - - diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.cpp b/LibOVR/Src/CAPI/CAPI_HMDState.cpp index fd98225..6ea9958 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDState.cpp +++ b/LibOVR/Src/CAPI/CAPI_HMDState.cpp @@ -5,16 +5,16 @@ Content : State associated with a single HMD Created : January 24, 2014 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -25,495 +25,484 @@ limitations under the License. ************************************************************************************/ #include "CAPI_HMDState.h" -#include "CAPI_GlobalState.h" #include "../OVR_Profile.h" +#include "../Service/Service_NetClient.h" +#ifdef OVR_OS_WIN32 +#include "../Displays/OVR_Win32_ShimFunctions.h" +#endif + namespace OVR { namespace CAPI { + +// Accessed via HMDState::GetHMDStateList() +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) : + 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(HMDDevice* device) - : pHMD(device), HMDInfoW(device), HMDInfo(HMDInfoW.h), - EnabledHmdCaps(0), HmdCapsAppliedToSensor(0), - SensorStarted(0), SensorCreated(0), SensorCaps(0), - AddSensorCount(0), AddLatencyTestCount(0), AddLatencyTestDisplayCount(0), - RenderState(getThis(), pHMD->GetProfile(), HMDInfoW.h), - LastFrameTimeSeconds(0.0f), LastGetFrameTimeSeconds(0.0), - LatencyTestActive(false), - LatencyTest2Active(false) +HMDState::HMDState(const OVR::HMDInfo& hmdInfo, Profile* profile) : + pProfile(profile), + pHmdDesc(0), + pWindow(0), + pClient(0), + NetId(InvalidVirtualHmdId), + 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) { - pLastError = 0; - GlobalState::pInstance->AddHMD(this); - - // Should be in renderer? - TimeManager.Init(RenderState.RenderInfo); + sharedInit(profile); + hmdStateList.PushBack(this); +} - EyeRenderActive[0] = false; - EyeRenderActive[1] = false; +HMDState::~HMDState() +{ + hmdStateList.Remove(this); - LatencyTestDrawColor[0] = 0; - LatencyTestDrawColor[1] = 0; - LatencyTestDrawColor[2] = 0; + if (pClient) + { + pClient->Hmd_Release(NetId); + pClient = 0; + } - OVR_CAPI_VISION_CODE( pPoseTracker = 0; ) + ConfigureRendering(0,0,0,0); - RenderingConfigured = false; - BeginFrameCalled = false; - BeginFrameThreadId = 0; - BeginFrameTimingCalled = false; + if (pHmdDesc) + { + OVR_FREE(pHmdDesc); + pHmdDesc = NULL; + } } -HMDState::HMDState(ovrHmdType hmdType) - : pHMD(0), HMDInfoW(hmdType), HMDInfo(HMDInfoW.h), - EnabledHmdCaps(0), - SensorStarted(0), SensorCreated(0), SensorCaps(0), - AddSensorCount(0), AddLatencyTestCount(0), AddLatencyTestDisplayCount(0), - RenderState(getThis(), 0, HMDInfoW.h), // No profile. - LastFrameTimeSeconds(0.0), LastGetFrameTimeSeconds(0.0) +void HMDState::sharedInit(Profile* profile) { // TBD: We should probably be looking up the default profile for the given - // device type + user. - + // device type + user if profile == 0. pLastError = 0; - GlobalState::pInstance->AddHMD(this); - // Should be in renderer? - TimeManager.Init(RenderState.RenderInfo); + RenderState.OurHMDInfo = OurHMDInfo; + + UpdateRenderProfile(profile); - EyeRenderActive[0] = false; - EyeRenderActive[1] = false; + OVR_ASSERT(!pHmdDesc); + pHmdDesc = (ovrHmdDesc*)OVR_ALLOC(sizeof(ovrHmdDesc)); + *pHmdDesc = RenderState.GetDesc(); + pHmdDesc->Handle = this; - OVR_CAPI_VISION_CODE( pPoseTracker = 0; ) + RenderState.ClearColor[0] = 0.0f; + RenderState.ClearColor[1] = 0.0f; + RenderState.ClearColor[2] = 0.0f; + RenderState.ClearColor[3] = 0.0f; + + RenderState.EnabledHmdCaps = 0; + + TimeManager.Init(RenderState.RenderInfo); + + /* + LatencyTestDrawColor[0] = 0; + LatencyTestDrawColor[1] = 0; + LatencyTestDrawColor[2] = 0; + */ RenderingConfigured = false; BeginFrameCalled = false; BeginFrameThreadId = 0; BeginFrameTimingCalled = false; -} - -HMDState::~HMDState() -{ - OVR_ASSERT(GlobalState::pInstance); - - StopSensor(); - ConfigureRendering(0,0,0,0); - - OVR_CAPI_VISION_CODE( OVR_ASSERT(pPoseTracker == 0); ) - - GlobalState::pInstance->RemoveHMD(this); + // 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)); + } } - - -//------------------------------------------------------------------------------------- -// *** Sensor - -bool HMDState::StartSensor(unsigned supportedCaps, unsigned requiredCaps) +static Vector3f GetNeckModelFromProfile(Profile* profile) { - Lock::Locker lockScope(&DevicesLock); + OVR_ASSERT(profile); - bool crystalCoveOrBetter = (HMDInfo.HmdType == HmdType_CrystalCoveProto) || - (HMDInfo.HmdType == HmdType_DK2); - bool sensorCreatedJustNow = false; + float neckeye[2] = { OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, OVR_DEFAULT_NECK_TO_EYE_VERTICAL }; + profile->GetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, neckeye, 2); - // TBD: In case of sensor not being immediately available, it would be good to check - // yaw config availability to match it with ovrHmdCap_YawCorrection requirement. - // + // Make sure these are vaguely sensible values. + //OVR_ASSERT((neckeye[0] > 0.05f) && (neckeye[0] < 0.5f)); + //OVR_ASSERT((neckeye[1] > 0.05f) && (neckeye[1] < 0.5f)); - if (!crystalCoveOrBetter) - { - if (requiredCaps & ovrSensorCap_Position) - { - pLastError = "ovrSensorCap_Position not supported on this HMD."; - return false; - } - } + // Named for clarity + float NeckToEyeHorizontal = neckeye[0]; + float NeckToEyeVertical = neckeye[1]; - supportedCaps |= requiredCaps; + // Store the neck model + return Vector3f(0.0, NeckToEyeVertical, -NeckToEyeHorizontal); +} - if (pHMD && !pSensor) - { - // Zero AddSensorCount before creation, in case it fails (or succeeds but then - // immediately gets disconnected) followed by another Add notification. - AddSensorCount = 0; - pSensor = *pHMD->GetSensor(); - sensorCreatedJustNow= true; +static float GetCenterPupilDepthFromRenderInfo(HmdRenderInfo* hmdRenderInfo) +{ + OVR_ASSERT(hmdRenderInfo); + + // Find the distance from the center of the screen to the "center eye" + // This center eye is used by systems like rendering & audio to represent the player, + // and they will handle the offsets needed from there to each actual eye. + + // HACK HACK HACK + // We know for DK1 the screen->lens surface distance is roughly 0.049f, and that the faceplate->lens is 0.02357f. + // We're going to assume(!!!!) that all HMDs have the same screen->faceplate distance. + // Crystal Cove was measured to be roughly 0.025 screen->faceplate which agrees with this assumption. + // TODO: do this properly! Update: Measured this at 0.02733 with a CC prototype, CES era (PT7), on 2/19/14 -Steve + float screenCenterToMidplate = 0.02733f; + float centerEyeRelief = hmdRenderInfo->GetEyeCenter().ReliefInMeters; + float CenterPupilDepth = screenCenterToMidplate + hmdRenderInfo->LensSurfaceToMidplateInMeters + centerEyeRelief; + + return CenterPupilDepth; +} - if (pSensor) +void HMDState::UpdateRenderProfile(Profile* profile) +{ + // Apply the given profile to generate a render context + RenderState.RenderInfo = GenerateHmdRenderInfoFromHmdInfo(RenderState.OurHMDInfo, profile); + RenderState.Distortion[0] = CalculateDistortionRenderDesc(StereoEye_Left, RenderState.RenderInfo, 0); + RenderState.Distortion[1] = CalculateDistortionRenderDesc(StereoEye_Right, RenderState.RenderInfo, 0); + + if (pClient) + { + // Center pupil depth + float centerPupilDepth = GetCenterPupilDepthFromRenderInfo(&RenderState.RenderInfo); + pClient->SetNumberValue(GetNetId(), "CenterPupilDepth", centerPupilDepth); + + // Neck model + Vector3f neckModel = GetNeckModelFromProfile(profile); + double neckModelArray[3] = { + neckModel.x, + neckModel.y, + neckModel.z + }; + pClient->SetNumberValues(GetNetId(), "NeckModelVector3f", neckModelArray, 3); + + double camerastate[7]; + if (profile->GetDoubleValues(OVR_KEY_CAMERA_POSITION, camerastate, 7) == 0) { - pSensor->SetReportRate(500); - SFusion.AttachToSensor(pSensor); - applyProfileToSensorFusion(); + //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 } else - { - if (requiredCaps & ovrSensorCap_Orientation) - { - pLastError = "Failed to create sensor."; - return false; - } - } + + TheSensorStateReader.setCenteredFromWorld(OVR::Posed::FromArray(camerastate)); } - if ((requiredCaps & ovrSensorCap_YawCorrection) && !pSensor->IsMagCalibrated()) - { - pLastError = "ovrHmdCap_YawCorrection not available."; - if (sensorCreatedJustNow) - { - SFusion.AttachToSensor(0); - SFusion.Reset(); - pSensor.Clear(); - } - return false; - } - - SFusion.SetYawCorrectionEnabled((supportedCaps & ovrSensorCap_YawCorrection) != 0); +} - if (pSensor && sensorCreatedJustNow) +HMDState* HMDState::CreateHMDState(NetClient* client, const HMDNetworkInfo& netInfo) +{ + // HMDState works through a handle to service HMD.... + HMDInfo hinfo; + if (!client->Hmd_GetHmdInfo(netInfo.NetId, &hinfo)) { - LogText("Sensor created.\n"); - SensorCreated = true; + OVR_DEBUG_LOG(("[HMDState] Unable to get HMD info")); + return NULL; } - updateDK2FeaturesTiedToSensor(sensorCreatedJustNow); - +#ifdef OVR_OS_WIN32 + OVR_DEBUG_LOG(("Setting up display shim")); -#ifdef OVR_CAPI_VISIONSUPPORT + // Initialize the display shim before reporting the display to the user code + // so that this will happen before the D3D display object is created. + Win32::DisplayShim::GetInstance().Update(&hinfo.ShimInfo); +#endif - if (crystalCoveOrBetter && (supportedCaps & ovrSensorCap_Position)) - { - if (!pPoseTracker) - { - pPoseTracker = new Vision::PoseTracker(SFusion); - if (pPoseTracker) - { - pPoseTracker->AssociateHMD(pSensor); - LogText("Sensor Pose tracker created.\n"); - } - } + Ptr pDefaultProfile = *ProfileManager::GetInstance()->GetDefaultUserProfile(&hinfo); + OVR_DEBUG_LOG(("Using profile %s", pDefaultProfile->GetValue(OVR_KEY_USER))); - // TBD: How do we verify that position tracking is actually available - // i.e. camera is plugged in? - } - else if (pPoseTracker) + HMDState* hmds = new HMDState(netInfo, hinfo, pDefaultProfile, client); + + if (!hmds->SharedStateReader.Open(netInfo.SharedMemoryName.ToCStr())) { - // TBD: Internals not thread safe - must fix!! - delete pPoseTracker; - pPoseTracker = 0; - LogText("Sensor Pose tracker destroyed.\n"); + delete hmds; + return NULL; } -#endif // OVR_CAPI_VISIONSUPPORT - - SensorCaps = supportedCaps; - SensorStarted = true; + hmds->TheSensorStateReader.SetUpdater(hmds->SharedStateReader.Get()); + hmds->TheLatencyTestStateReader.SetUpdater(hmds->SharedStateReader.Get()); - return true; + return hmds; } - -// Stops sensor sampling, shutting down internal resources. -void HMDState::StopSensor() +HMDState* HMDState::CreateHMDState(ovrHmdType hmdType) { - Lock::Locker lockScope(&DevicesLock); + HmdTypeEnum t = HmdType_None; + if (hmdType == ovrHmd_DK1) + t = HmdType_DK1; + else if (hmdType == ovrHmd_DK2) + t = HmdType_DK2; - if (SensorStarted) - { -#ifdef OVR_CAPI_VISIONSUPPORT - if (pPoseTracker) - { - // TBD: Internals not thread safe - must fix!! - delete pPoseTracker; - pPoseTracker = 0; - LogText("Sensor Pose tracker destroyed.\n"); - } -#endif // OVR_CAPI_VISION_CODE - - SFusion.AttachToSensor(0); - SFusion.Reset(); - pSensor.Clear(); - HmdCapsAppliedToSensor = 0; - AddSensorCount = 0; - SensorCaps = 0; - SensorCreated = false; - SensorStarted = false; - - LogText("StopSensor succeeded.\n"); - } + // FIXME: This does not actually grab the right user.. + Ptr pDefaultProfile = *ProfileManager::GetInstance()->GetDefaultProfile(t); + + return new HMDState(CreateDebugHMDInfo(t), pDefaultProfile); } + -// Resets sensor orientation. -void HMDState::ResetSensor() +const OVR::List& HMDState::GetHMDStateList() { - SFusion.Reset(); + return hmdStateList; } -// Returns prediction for time. -ovrSensorState HMDState::PredictedSensorState(double absTime) -{ - SensorState ss; +//------------------------------------------------------------------------------------- +// *** Sensor + +bool HMDState::ConfigureTracking(unsigned supportedCaps, unsigned requiredCaps) +{ + return pClient ? pClient->Hmd_ConfigureTracking(NetId, supportedCaps, requiredCaps) : true; +} - // We are trying to keep this path lockless unless we are notified of new device - // creation while not having a sensor yet. It's ok to check SensorCreated volatile - // flag here, since GetSensorStateAtTime() is internally lockless and safe. +void HMDState::ResetTracking() +{ + if (pClient) pClient->Hmd_ResetTracking(NetId); +} - if (SensorCreated || checkCreateSensor()) - { - ss = SFusion.GetSensorStateAtTime(absTime); +// Re-center the orientation. +void HMDState::RecenterPose() +{ + TheSensorStateReader.RecenterPose(); +} - if (!(ss.StatusFlags & ovrStatus_OrientationTracked)) - { - Lock::Locker lockScope(&DevicesLock); +// Returns prediction for time. +ovrTrackingState HMDState::PredictedTrackingState(double absTime) +{ + Tracking::TrackingState ss; + TheSensorStateReader.GetSensorStateAtTime(absTime, ss); -#ifdef OVR_CAPI_VISIONSUPPORT - if (pPoseTracker) - { - // TBD: Internals not thread safe - must fix!! - delete pPoseTracker; - pPoseTracker = 0; - LogText("Sensor Pose tracker destroyed.\n"); - } -#endif // OVR_CAPI_VISION_CODE - // Not needed yet; SFusion.AttachToSensor(0); - // This seems to reset orientation anyway... - pSensor.Clear(); - SensorCreated = false; - HmdCapsAppliedToSensor = 0; - } - } - else + // Zero out the status flags + if (!pClient || !pClient->IsConnected(false, false)) { - // SensorState() defaults to 0s. - // ss.Pose.Orientation = Quatf(); - // .. - - // John: - // We still want valid times so frames will get a delta-time - // and allow operation with a joypad when the sensor isn't - // connected. - ss.Recorded.TimeInSeconds = absTime; - ss.Predicted.TimeInSeconds = absTime; + ss.StatusFlags = 0; } - ss.StatusFlags |= ovrStatus_HmdConnected; return ss; } - -bool HMDState::checkCreateSensor() +void HMDState::SetEnabledHmdCaps(unsigned hmdCaps) { - if (!(SensorStarted && !SensorCreated && AddSensorCount)) - return false; + if (OurHMDInfo.HmdType < HmdType_DK2) + { + // disable low persistence and pentile. + hmdCaps &= ~ovrHmdCap_LowPersistence; + hmdCaps &= ~ovrHmdCap_DirectPentile; - Lock::Locker lockScope(&DevicesLock); + // disable dynamic prediction using the internal latency tester + hmdCaps &= ~ovrHmdCap_DynamicPrediction; + } - // Re-check condition once in the lock, in case the state changed. - if (SensorStarted && !SensorCreated && AddSensorCount) - { - if (pHMD) + if (OurHMDInfo.HmdType >= HmdType_DK2) + { + if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_DynamicPrediction) { - AddSensorCount = 0; - pSensor = *pHMD->GetSensor(); + // DynamicPrediction change + TimeManager.ResetFrameTiming(TimeManager.GetFrameTiming().FrameIndex, + (hmdCaps & ovrHmdCap_DynamicPrediction) ? true : false, + RenderingConfigured); } + } - if (pSensor) - { - pSensor->SetReportRate(500); - SFusion.AttachToSensor(pSensor); - SFusion.SetYawCorrectionEnabled((SensorCaps & ovrSensorCap_YawCorrection) != 0); - applyProfileToSensorFusion(); - -#ifdef OVR_CAPI_VISIONSUPPORT - if (SensorCaps & ovrSensorCap_Position) - { - pPoseTracker = new Vision::PoseTracker(SFusion); - if (pPoseTracker) - { - pPoseTracker->AssociateHMD(pSensor); - } - LogText("Sensor Pose tracker created.\n"); - } -#endif // OVR_CAPI_VISION_CODE - - LogText("Sensor created.\n"); + // Pentile unsupported on everything right now. + hmdCaps &= ~ovrHmdCap_DirectPentile; + + if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_NoVSync) + { + TimeManager.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true); + } - SensorCreated = true; - return true; + if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_NoMirrorToWindow) + { +#ifdef OVR_OS_WIN32 + Win32::DisplayShim::GetInstance().UseMirroring = (hmdCaps & ovrHmdCap_NoMirrorToWindow) ? + false : true; + if (pWindow) + { // Force window repaint so that stale mirrored image doesn't persist. + ::InvalidateRect((HWND)pWindow, 0, true); } +#endif } - return SensorCreated; -} + // TBD: Should this include be only the rendering flags? Otherwise, bits that failed + // modification in Hmd_SetEnabledCaps may mis-match... + EnabledHmdCaps = hmdCaps & ovrHmdCap_Writable_Mask; + RenderState.EnabledHmdCaps = EnabledHmdCaps; -bool HMDState::GetSensorDesc(ovrSensorDesc* descOut) -{ - Lock::Locker lockScope(&DevicesLock); - - if (SensorCreated) - { - OVR_ASSERT(pSensor); - OVR::SensorInfo si; - pSensor->GetDeviceInfo(&si); - descOut->VendorId = si.VendorId; - descOut->ProductId = si.ProductId; - OVR_ASSERT(si.SerialNumber.GetSize() <= sizeof(descOut->SerialNumber)); - OVR_strcpy(descOut->SerialNumber, sizeof(descOut->SerialNumber), si.SerialNumber.ToCStr()); - return true; - } - return false; -} + // If any of the modifiable service caps changed, call on the service. + unsigned prevServiceCaps = EnabledServiceHmdCaps & ovrHmdCap_Writable_Mask; + unsigned newServiceCaps = hmdCaps & ovrHmdCap_Writable_Mask & ovrHmdCap_Service_Mask; -void HMDState::applyProfileToSensorFusion() -{ - if (!pHMD) - return; - Profile* profile = pHMD->GetProfile(); - if (!profile) - { - OVR_ASSERT(false); - return; + if (prevServiceCaps ^ newServiceCaps) + { + EnabledServiceHmdCaps = pClient ? pClient->Hmd_SetEnabledCaps(NetId, newServiceCaps) + : newServiceCaps; } - SFusion.SetUserHeadDimensions ( *profile, RenderState.RenderInfo ); } -void HMDState::updateLowPersistenceMode(bool lowPersistence) const -{ - OVR_ASSERT(pSensor); - DisplayReport dr; - - if (pSensor.GetPtr()) - { - pSensor->GetDisplayReport(&dr); - dr.Persistence = (UInt16) (dr.TotalRows * (lowPersistence ? 0.18f : 1.0f)); - dr.Brightness = lowPersistence ? 255 : 0; +unsigned HMDState::SetEnabledHmdCaps() +{ + unsigned serviceCaps = pClient ? pClient->Hmd_GetEnabledCaps(NetId) : + EnabledServiceHmdCaps; - pSensor->SetDisplayReport(dr); - } + return serviceCaps & ((~ovrHmdCap_Service_Mask) | EnabledHmdCaps); } -void HMDState::updateLatencyTestForHmd(bool latencyTesting) -{ - if (pSensor.GetPtr()) - { - DisplayReport dr; - pSensor->GetDisplayReport(&dr); - dr.ReadPixel = latencyTesting; +//------------------------------------------------------------------------------------- +// ***** Property Access - pSensor->SetDisplayReport(dr); - } +// FIXME: Remove the EGetBoolValue stuff and do it with a "Server:" prefix, so we do not +// need to keep a white-list of keys. This is also way cool because it allows us to add +// new settings keys from outside CAPI that can modify internal server data. - if (latencyTesting) +bool HMDState::getBoolValue(const char* propertyName, bool defaultVal) +{ + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetBoolValue, propertyName)) { - LatencyUtil2.SetSensorDevice(pSensor.GetPtr()); + return NetClient::GetInstance()->GetBoolValue(GetNetId(), propertyName, defaultVal); } - else + else if (pProfile) { - LatencyUtil2.SetSensorDevice(NULL); + return pProfile->GetBoolValue(propertyName, defaultVal); } + return defaultVal; } - -void HMDState::updateDK2FeaturesTiedToSensor(bool sensorCreatedJustNow) +bool HMDState::setBoolValue(const char* propertyName, bool value) { - Lock::Locker lockScope(&DevicesLock); + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetBoolValue, propertyName)) + { + return NetClient::GetInstance()->SetBoolValue(GetNetId(), propertyName, value); + } - if (!SensorCreated || (HMDInfo.HmdType != HmdType_DK2)) - return; + return false; +} - // Only send display reports if state changed or sensor initializing first time. - if (sensorCreatedJustNow || - ((HmdCapsAppliedToSensor ^ EnabledHmdCaps) & ovrHmdCap_LowPersistence)) +int HMDState::getIntValue(const char* propertyName, int defaultVal) +{ + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetIntValue, propertyName)) { - updateLowPersistenceMode((EnabledHmdCaps & ovrHmdCap_LowPersistence) ? true : false); + return NetClient::GetInstance()->GetIntValue(GetNetId(), propertyName, defaultVal); } - - if (sensorCreatedJustNow || ((HmdCapsAppliedToSensor ^ EnabledHmdCaps) & ovrHmdCap_LatencyTest)) + else if (pProfile) { - updateLatencyTestForHmd((EnabledHmdCaps & ovrHmdCap_LatencyTest) != 0); + return pProfile->GetIntValue(propertyName, defaultVal); } - - HmdCapsAppliedToSensor = EnabledHmdCaps & (ovrHmdCap_LowPersistence|ovrHmdCap_LatencyTest); + return defaultVal; } +bool HMDState::setIntValue(const char* propertyName, int value) +{ + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetIntValue, propertyName)) + { + return NetClient::GetInstance()->SetIntValue(GetNetId(), propertyName, value); + } + return false; +} -void HMDState::SetEnabledHmdCaps(unsigned hmdCaps) +float HMDState::getFloatValue(const char* propertyName, float defaultVal) { - - if (HMDInfo.HmdType == HmdType_DK2) + if (OVR_strcmp(propertyName, "LensSeparation") == 0) { - if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_DynamicPrediction) - { - // DynamicPrediction change - TimeManager.ResetFrameTiming(TimeManager.GetFrameTiming().FrameIndex, - (hmdCaps & ovrHmdCap_DynamicPrediction) ? true : false, - RenderingConfigured); - } + return OurHMDInfo.LensSeparationInMeters; } - - if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_NoVSync) + else if (OVR_strcmp(propertyName, "VsyncToNextVsync") == 0) { - TimeManager.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true); + return OurHMDInfo.Shutter.VsyncToNextVsync; + } + else if (OVR_strcmp(propertyName, "PixelPersistence") == 0) + { + return OurHMDInfo.Shutter.PixelPersistence; + } + else if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetNumberValue, propertyName)) + { + return (float)NetClient::GetInstance()->GetNumberValue(GetNetId(), propertyName, defaultVal); + } + else if (pProfile) + { + return pProfile->GetFloatValue(propertyName, defaultVal); } - - EnabledHmdCaps = hmdCaps & ovrHmdCap_Writable_Mask; - RenderState.EnabledHmdCaps = EnabledHmdCaps; - - // Unfortunately, LowPersistance and other flags are tied to sensor. - // This flag will apply the state of sensor is created; otherwise this will be delayed - // till StartSensor. - // Such behavior is less then ideal, but should be resolved with the service model. - - updateDK2FeaturesTiedToSensor(false); + return defaultVal; } - -//------------------------------------------------------------------------------------- -// ***** Property Access - -// TBD: This all needs to be cleaned up and organized into namespaces. - -float HMDState::getFloatValue(const char* propertyName, float defaultVal) +bool HMDState::setFloatValue(const char* propertyName, float value) { - if (OVR_strcmp(propertyName, "LensSeparation") == 0) - { - return HMDInfo.LensSeparationInMeters; - } - else if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0) - { - return SFusion.GetCenterPupilDepth(); - } - else if (pHMD) + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetNumberValue, propertyName)) { - Profile* p = pHMD->GetProfile(); - if (p) - { - return p->GetFloatValue(propertyName, defaultVal); - } + return NetClient::GetInstance()->SetNumberValue(GetNetId(), propertyName, value); } - return defaultVal; -} -bool HMDState::setFloatValue(const char* propertyName, float value) -{ - if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0) - { - SFusion.SetCenterPupilDepth(value); - return true; - } - return false; + return false; } - static unsigned CopyFloatArrayWithLimit(float dest[], unsigned destSize, float source[], unsigned sourceSize) { @@ -523,14 +512,13 @@ static unsigned CopyFloatArrayWithLimit(float dest[], unsigned destSize, return count; } - unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsigned arraySize) { if (arraySize) { if (OVR_strcmp(propertyName, "ScreenSize") == 0) { - float data[2] = { HMDInfo.ScreenSizeInMeters.w, HMDInfo.ScreenSizeInMeters.h }; + float data[2] = { OurHMDInfo.ScreenSizeInMeters.w, OurHMDInfo.ScreenSizeInMeters.h }; return CopyFloatArrayWithLimit(values, arraySize, data, 2); } @@ -540,36 +528,50 @@ unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsig } else if (OVR_strcmp(propertyName, "DK2Latency") == 0) { - if (HMDInfo.HmdType != HmdType_DK2) + if (OurHMDInfo.HmdType != HmdType_DK2) + { return 0; + } - float data[3]; - TimeManager.GetLatencyTimings(data); - - return CopyFloatArrayWithLimit(values, arraySize, data, 3); - } + union { + struct X { + float latencyRender, latencyTimewarp, latencyPostPresent; + } x; + float data[3]; + } m; - /* - else if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0) + static_assert(sizeof(m.x)==sizeof(m.data), "sizeof(struct X) failure"); + + TimeManager.GetLatencyTimings(m.x.latencyRender, m.x.latencyTimewarp, m.x.latencyPostPresent); + + return CopyFloatArrayWithLimit(values, arraySize, m.data, 3); + } + else if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetNumberValues, propertyName)) { - if (arraySize >= 1) + // Convert floats to doubles + double* da = new double[arraySize]; + for (int i = 0; i < (int)arraySize; ++i) { - values[0] = SFusion.GetCenterPupilDepth(); - return 1; + da[i] = values[i]; } - return 0; - } */ - else if (pHMD) - { - Profile* p = pHMD->GetProfile(); + int count = NetClient::GetInstance()->GetNumberValues(GetNetId(), propertyName, da, (int)arraySize); + + for (int i = 0; i < count; ++i) + { + values[i] = (float)da[i]; + } + + delete[] da; + + 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. - if (p) - { - unsigned count = p->GetFloatValues(propertyName, values, arraySize); - return count; - } + + return pProfile->GetFloatValues(propertyName, values, arraySize); } } @@ -579,26 +581,45 @@ unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsig bool HMDState::setFloatArray(const char* propertyName, float values[], unsigned arraySize) { if (!arraySize) + { return false; + } if (OVR_strcmp(propertyName, "DistortionClearColor") == 0) { CopyFloatArrayWithLimit(RenderState.ClearColor, 4, values, arraySize); return true; } - return false; -} + 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); + + delete[] da; + + return result; + } + + return false; +} const char* HMDState::getString(const char* propertyName, const char* defaultVal) { - if (pHMD) - { - // For now, just access the profile. - Profile* p = pHMD->GetProfile(); + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetStringValue, propertyName)) + { + return NetClient::GetInstance()->GetStringValue(GetNetId(), propertyName, defaultVal); + } + if (pProfile) + { LastGetStringValue[0] = 0; - if (p && p->GetValue(propertyName, LastGetStringValue, sizeof(LastGetStringValue))) + if (pProfile->GetValue(propertyName, LastGetStringValue, sizeof(LastGetStringValue))) { return LastGetStringValue; } @@ -607,92 +628,23 @@ const char* HMDState::getString(const char* propertyName, const char* defaultVal return defaultVal; } -//------------------------------------------------------------------------------------- -// *** Latency Test - -bool HMDState::ProcessLatencyTest(unsigned char rgbColorOut[3]) +bool HMDState::setString(const char* propertyName, const char* value) { - bool result = false; - - // Check create. - if (pLatencyTester) - { - if (pLatencyTester->IsConnected()) - { - Color colorToDisplay; - - LatencyUtil.ProcessInputs(); - result = LatencyUtil.DisplayScreenColor(colorToDisplay); - rgbColorOut[0] = colorToDisplay.R; - rgbColorOut[1] = colorToDisplay.G; - rgbColorOut[2] = colorToDisplay.B; - } - else - { - // Disconnect. - LatencyUtil.SetDevice(NULL); - pLatencyTester = 0; - LogText("LATENCY SENSOR disconnected.\n"); - } - } - else if (AddLatencyTestCount > 0) - { - // This might have some unlikely race condition issue which could cause us to miss a device... - AddLatencyTestCount = 0; + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetStringValue, propertyName)) + { + return NetClient::GetInstance()->SetStringValue(GetNetId(), propertyName, value); + } - pLatencyTester = *GlobalState::pInstance->GetManager()-> - EnumerateDevices().CreateDevice(); - if (pLatencyTester) - { - LatencyUtil.SetDevice(pLatencyTester); - LogText("LATENCY TESTER connected\n"); - } - } - - return result; + return false; } -void HMDState::ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime) -{ - // Check create. - if (!(EnabledHmdCaps & ovrHmdCap_LatencyTest)) - return; - - if (pLatencyTesterDisplay && !LatencyUtil2.HasDisplayDevice()) - { - if (!pLatencyTesterDisplay->IsConnected()) - { - LatencyUtil2.SetDisplayDevice(NULL); - } - } - else if (AddLatencyTestDisplayCount > 0) - { - // This might have some unlikely race condition issue - // which could cause us to miss a device... - AddLatencyTestDisplayCount = 0; - - pLatencyTesterDisplay = *GlobalState::pInstance->GetManager()-> - EnumerateDevices().CreateDevice(); - if (pLatencyTesterDisplay) - { - LatencyUtil2.SetDisplayDevice(pLatencyTesterDisplay); - } - } - if (LatencyUtil2.HasDevice() && pSensor && pSensor->IsConnected()) - { - LatencyUtil2.BeginTest(startTime); +//------------------------------------------------------------------------------------- +// *** Latency Test - Color colorToDisplay; - LatencyTest2Active = LatencyUtil2.DisplayScreenColor(colorToDisplay); - rgbColorOut[0] = colorToDisplay.R; - rgbColorOut[1] = colorToDisplay.G; - rgbColorOut[2] = colorToDisplay.B; - } - else - { - LatencyTest2Active = false; - } +bool HMDState::ProcessLatencyTest(unsigned char rgbColorOut[3]) +{ + return NetClient::GetInstance()->LatencyUtil_ProcessInputs(Timer::GetSeconds(), rgbColorOut); } //------------------------------------------------------------------------------------- @@ -708,6 +660,12 @@ bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], // null -> shut down. if (!apiConfig) { + if (pHSWDisplay) + { + pHSWDisplay->Shutdown(); + pHSWDisplay.Clear(); + } + if (pRenderer) pRenderer.Clear(); RenderingConfigured = false; @@ -718,15 +676,25 @@ bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], (apiConfig->Header.API != pRenderer->GetRenderAPI())) { // Shutdown old renderer. + if (pHSWDisplay) + { + pHSWDisplay->Shutdown(); + pHSWDisplay.Clear(); + } + if (pRenderer) pRenderer.Clear(); } + distortionCaps = distortionCaps & pHmdDesc->DistortionCaps; // Step 1: do basic setup configuration - RenderState.setupRenderDesc(eyeRenderDescOut, eyeFovIn); RenderState.EnabledHmdCaps = EnabledHmdCaps; // This is a copy... Any cleaner way? RenderState.DistortionCaps = distortionCaps; + RenderState.EyeRenderDesc[0] = RenderState.CalcRenderDesc(ovrEye_Left, eyeFovIn[0]); + RenderState.EyeRenderDesc[1] = RenderState.CalcRenderDesc(ovrEye_Right, eyeFovIn[1]); + eyeRenderDescOut[0] = RenderState.EyeRenderDesc[0]; + eyeRenderDescOut[1] = RenderState.EyeRenderDesc[1]; TimeManager.ResetFrameTiming(0, (EnabledHmdCaps & ovrHmdCap_DynamicPrediction) ? true : false, @@ -740,65 +708,109 @@ bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], if (!pRenderer) { pRenderer = *DistortionRenderer::APICreateRegistry - [apiConfig->Header.API](this, TimeManager, RenderState); + [apiConfig->Header.API](pHmdDesc, TimeManager, RenderState); } if (!pRenderer || - !pRenderer->Initialize(apiConfig, distortionCaps)) + !pRenderer->Initialize(apiConfig)) { 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. + { + pHSWDisplay->Shutdown(); + pHSWDisplay.Clear(); + } + + 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. + return true; } - -ovrPosef HMDState::BeginEyeRender(ovrEyeType eye) +void HMDState::SubmitEyeTextures(const ovrPosef renderPose[2], + const ovrTexture eyeTexture[2]) { - // Debug checks. - checkBeginFrameScope("ovrHmd_BeginEyeRender"); - ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_BeginEyeRender"); + RenderState.EyeRenderPoses[0] = renderPose[0]; + RenderState.EyeRenderPoses[1] = renderPose[1]; - // Unknown eyeId provided in ovrHmd_BeginEyeRender - OVR_ASSERT_LOG(eye == ovrEye_Left || eye == ovrEye_Right, - ("ovrHmd_BeginEyeRender eyeId out of range.")); - OVR_ASSERT_LOG(EyeRenderActive[eye] == false, - ("Multiple calls to ovrHmd_BeginEyeRender for the same eye.")); - - EyeRenderActive[eye] = true; - - // Only process latency tester for drawing the left eye (assumes left eye is drawn first) - if (pRenderer && eye == 0) + if (pRenderer) { - LatencyTestActive = ProcessLatencyTest(LatencyTestDrawColor); + pRenderer->SubmitEye(0, &eyeTexture[0]); + pRenderer->SubmitEye(1, &eyeTexture[1]); } - - return ovrHmd_GetEyePose(this, eye); } -void HMDState::EndEyeRender(ovrEyeType eye, ovrPosef renderPose, ovrTexture* eyeTexture) +// 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 ) { - // Debug checks. - checkBeginFrameScope("ovrHmd_EndEyeRender"); - ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_EndEyeRender"); + 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 = 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); - if (!EyeRenderActive[eye]) + if (meshData->pVertexData) { - OVR_ASSERT_LOG(false, - ("ovrHmd_EndEyeRender called without ovrHmd_BeginEyeRender.")); - return; + // Convert to index + meshData->IndexCount = triangleCount * 3; + meshData->VertexCount = vertexCount; + return 1; } - RenderState.EyeRenderPoses[eye] = renderPose; + return 0; +} - if (pRenderer) - pRenderer->SubmitEye(eye, eyeTexture); - EyeRenderActive[eye] = false; -} }} // namespace OVR::CAPI - diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.h b/LibOVR/Src/CAPI/CAPI_HMDState.h index 0a1466f..81ca64f 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDState.h +++ b/LibOVR/Src/CAPI/CAPI_HMDState.h @@ -5,16 +5,16 @@ Content : State associated with a single HMD Created : January 24, 2014 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -31,28 +31,25 @@ limitations under the License. #include "../Kernel/OVR_List.h" #include "../Kernel/OVR_Log.h" #include "../OVR_CAPI.h" -#include "../OVR_SensorFusion.h" -#include "../Util/Util_LatencyTest.h" -#include "../Util/Util_LatencyTest2.h" #include "CAPI_FrameTimeManager.h" +#include "CAPI_LatencyStatistics.h" #include "CAPI_HMDRenderState.h" #include "CAPI_DistortionRenderer.h" +#include "CAPI_HSWDisplay.h" -// Define OVR_CAPI_VISIONSUPPORT to compile in vision support -#ifdef OVR_CAPI_VISIONSUPPORT - #define OVR_CAPI_VISION_CODE(c) c - #include "../Vision/Vision_PoseTracker.h" -#else - #define OVR_CAPI_VISION_CODE(c) -#endif - +#include "../Service/Service_NetClient.h" +#include "../Net/OVR_NetworkTypes.h" +#include "../Util/Util_LatencyTest2Reader.h" struct ovrHmdStruct { }; namespace OVR { namespace CAPI { + using namespace OVR::Util::Render; +using namespace OVR::Service; +using namespace OVR::Net; //------------------------------------------------------------------------------------- @@ -104,7 +101,7 @@ public: FirstThread = 0; } - // Add thread-re-entrancy check for function scope. + // Add thread-reentrancy check for function scope. struct Scope { Scope(ThreadChecker* threadChecker, const char *functionName) : pChecker(threadChecker) @@ -131,61 +128,51 @@ private: class HMDState : public ListNode, public ovrHmdStruct, public NewOverrideBase { -public: + void operator=(const HMDState&) { } // Quiet warning. - HMDState(HMDDevice* device); - HMDState(ovrHmdType hmdType); +protected: + HMDState(const OVR::Service::HMDNetworkInfo& netInfo, + const OVR::HMDInfo& hmdInfo, + Profile* profile, + Service::NetClient* client); + HMDState(const HMDInfo& src, Profile* profile); + +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(); // *** Sensor Setup - bool StartSensor(unsigned supportedCaps, unsigned requiredCaps); - void StopSensor(); - void ResetSensor(); - ovrSensorState PredictedSensorState(double absTime); - bool GetSensorDesc(ovrSensorDesc* descOut); + bool ConfigureTracking(unsigned supportedCaps, unsigned requiredCaps); + void ResetTracking(); + void RecenterPose(); + ovrTrackingState PredictedTrackingState(double absTime); // Changes HMD Caps. // Capability bits that are not directly or logically tied to one system (such as sensor) // are grouped here. ovrHmdCap_VSync, for example, affects rendering and timing. void SetEnabledHmdCaps(unsigned caps); - + unsigned SetEnabledHmdCaps(); bool ProcessLatencyTest(unsigned char rgbColorOut[3]); - void ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime); - // *** Rendering Setup - - bool ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], - const ovrFovPort eyeFovIn[2], - const ovrRenderAPIConfig* apiConfig, - unsigned distortionCaps); + bool ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], + const ovrFovPort eyeFovIn[2], + const ovrRenderAPIConfig* apiConfig, + unsigned distortionCaps); - ovrPosef BeginEyeRender(ovrEyeType eye); - void EndEyeRender(ovrEyeType eye, ovrPosef renderPose, ovrTexture* eyeTexture); + void UpdateRenderProfile(Profile* profile); - const char* GetLastError() - { - const char* p = pLastError; - pLastError = 0; - return p; - } + void SubmitEyeTextures(const ovrPosef renderPose[2], + const ovrTexture eyeTexture[2]); - void NotifyAddDevice(DeviceType deviceType) - { - if (deviceType == Device_Sensor) - AddSensorCount++; - else if (deviceType == Device_LatencyTester) - { - AddLatencyTestCount++; - AddLatencyTestDisplayCount++; - } - } - bool checkCreateSensor(); + void sharedInit ( Profile *profile ); void applyProfileToSensorFusion(); @@ -197,7 +184,7 @@ public: OVR_UNUSED1(functionName); // for Release build. OVR_ASSERT_LOG(BeginFrameCalled == true, ("%s called outside ovrHmd_BeginFrame.", functionName)); - OVR_ASSERT_LOG(BeginFrameThreadId == OVR::GetCurrentThreadId(), + OVR_DEBUG_LOG_COND(BeginFrameThreadId != OVR::GetCurrentThreadId(), ("%s called on a different thread then ovrHmd_BeginFrame.", functionName)); } @@ -215,105 +202,68 @@ public: ("%s called outside ovrHmd_BeginFrameTiming.", functionName)); } - - HMDState* getThis() { return this; } - - void updateLowPersistenceMode(bool lowPersistence) const; - void updateLatencyTestForHmd(bool latencyTesting); - - void updateDK2FeaturesTiedToSensor(bool sensorCreatedJustNow); - // Get properties by name. - float getFloatValue(const char* propertyName, float defaultVal); + 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); bool setFloatArray(const char* propertyName, float values[], unsigned arraySize); - const char* getString(const char* propertyName, const char* defaultVal); + const char* getString(const char* propertyName, const char* defaultVal); + bool setString(const char* propertyName, const char* value); + + VirtualHmdId GetNetId() { return NetId; } + public: - - // Wrapper to support 'const' - struct HMDInfoWrapper - { - HMDInfoWrapper(ovrHmdType hmdType) - { - HmdTypeEnum t = HmdType_None; - if (hmdType == ovrHmd_DK1) - t = HmdType_DK1; - else if (hmdType == ovrHmd_CrystalCoveProto) - t = HmdType_CrystalCoveProto; - else if (hmdType == ovrHmd_DK2) - t = HmdType_DK2; - h = CreateDebugHMDInfo(t); - } - HMDInfoWrapper(HMDDevice* device) { if (device) device->GetDeviceInfo(&h); } - OVR::HMDInfo h; - }; + Ptr pProfile; + // Descriptor that gets allocated and returned to the user as ovrHmd. + ovrHmdDesc* pHmdDesc; + // Window handle passed in AttachWindow. + void* pWindow; - // Note: pHMD can be null if we are representing a virtualized debug HMD. - Ptr pHMD; + // Network + Service::NetClient* pClient; + VirtualHmdId NetId; + HMDNetworkInfo NetInfo; - // HMDInfo shouldn't change, as its string pointers are passed out. - const HMDInfoWrapper HMDInfoW; - const OVR::HMDInfo& HMDInfo; + // HMDInfo shouldn't change, as its string pointers are passed out. + HMDInfo OurHMDInfo; const char* pLastError; // Caps enabled for the HMD. unsigned EnabledHmdCaps; + + // Caps actually sent to the Sensor Service + unsigned EnabledServiceHmdCaps; + // These are the flags actually applied to the Sensor device, // used to track whether SetDisplayReport calls are necessary. - unsigned HmdCapsAppliedToSensor; - + //unsigned HmdCapsAppliedToSensor; // *** Sensor - - // Lock used to support thread-safe lifetime access to sensor. - Lock DevicesLock; - - // Atomic integer used as a flag that we should check the sensor device. - AtomicInt AddSensorCount; - - // All of Sensor variables may be modified/used with DevicesLock, with exception that - // the {SensorStarted, SensorCreated} can be read outside the lock to see - // if device creation check is necessary. - // Whether we called StartSensor() and requested sensor caps. - volatile bool SensorStarted; - volatile bool SensorCreated; - // pSensor may still be null or non-running after start if it wasn't yet available - Ptr pSensor; // Head - unsigned SensorCaps; - - // SensorFusion state may be accessible without a lock. - SensorFusion SFusion; - - - // Vision pose tracker is currently new-allocated - OVR_CAPI_VISION_CODE( - Vision::PoseTracker* pPoseTracker; - ) - - // Latency tester - Ptr pLatencyTester; - Util::LatencyTest LatencyUtil; - AtomicInt AddLatencyTestCount; + Tracking::CombinedSharedStateReader SharedStateReader; + Tracking::SensorStateReader TheSensorStateReader; + Util::RecordStateReader TheLatencyTestStateReader; bool LatencyTestActive; unsigned char LatencyTestDrawColor[3]; - // Using latency tester as debug display - Ptr pLatencyTesterDisplay; - AtomicInt AddLatencyTestDisplayCount; - Util::LatencyTest2 LatencyUtil2; - bool LatencyTest2Active; unsigned char LatencyTest2DrawColor[3]; - //bool ReadbackColor; // Rendering part FrameTimeManager TimeManager; + LagStatsCalculator LagStats; + LatencyStatisticsCSV LagStatsCSV; 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 @@ -323,7 +273,6 @@ public: // Last cached value returned by ovrHmd_GetString/ovrHmd_GetStringArray. char LastGetStringValue[256]; - // Debug flag set after ovrHmd_ConfigureRendering succeeds. bool RenderingConfigured; // Set after BeginFrame succeeds, and its corresponding thread id for debug checks. @@ -333,15 +282,23 @@ public: ThreadChecker RenderAPIThreadChecker; // bool BeginFrameTimingCalled; - - // Flags set when we've called BeginEyeRender on a given eye. - bool EyeRenderActive[2]; }; -}} // namespace OVR::CAPI -#endif // OVR_CAPI_HMDState_h +//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 new file mode 100644 index 0000000..ae11f5e --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_HSWDisplay.cpp @@ -0,0 +1,482 @@ +/************************************************************************************ + +Filename : CAPI_HSWDisplay.cpp +Content : Implements Health and Safety Warning system. +Created : July 3, 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_HSWDisplay.h" +#include "CAPI_HMDState.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 +// +// Defined as 0 or 1. Enables debugging features of this module. + +#if !defined(HSWDISPLAY_DEBUGGING) + #if defined(AUTHOR_PPEDRIANA) + #define HSWDISPLAY_DEBUGGING 1 + #else + #define HSWDISPLAY_DEBUGGING 0 + #endif +#endif + +#if HSWDISPLAY_DEBUGGING + OVR_DISABLE_ALL_MSVC_WARNINGS() + #include + #include + OVR_RESTORE_ALL_MSVC_WARNINGS() +#endif + +OVR_DISABLE_MSVC_WARNING(4996) // "This function or variable may be unsafe..." + + +//------------------------------------------------------------------------------------- +// ***** HSWDISPLAY_DEFAULT_ENABLED +// +// Defined as 0 or 1. 1 is default. If 0 then by default HSWDisplay is disabled. +// Developers can set it to 0 to disable HSW display. +// +#if !defined(HSWDISPLAY_DEFAULT_ENABLED) + #define HSWDISPLAY_DEFAULT_ENABLED 1 +#endif + + + +//------------------------------------------------------------------------------------- +// ***** 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 +// + +namespace OVR { namespace CAPI { + + +static const time_t HSWDisplayTimeNever = (time_t)0; // Constant which denotes the time of "never", as in the display has never been shown yet. + +#define HSWDISPLAY_POLL_INTERVAL 0.400 // Seconds between polling for whether the display should be shown. +#define OVR_KEY_HSWDISPLAYLASTDISPLAYEDTIME "HASWLastDisplayedTime" + + +#if defined(OVR_BUILD_DEBUG) + #define HSWDISPLAY_FIRST_DISMISSAL_TIME 4 // Earliest time in seconds until the user can dismiss the display. + #define HSWDISPLAY_REGULAR_DISMISSAL_TIME 2 +#else + #define HSWDISPLAY_FIRST_DISMISSAL_TIME 15 + #define HSWDISPLAY_REGULAR_DISMISSAL_TIME 6 +#endif + + +HSWDisplay::HSWDisplay(ovrRenderAPIType renderAPIType, ovrHmd hmd, const HMDRenderState& hmdRenderState) + : Enabled(HSWDISPLAY_DEFAULT_ENABLED ? true : false), + Displayed(false), + SDKRendered(false), + DismissRequested(false), + RenderEnabled(true), + UnloadGraphicsRequested(false), + StartTime(0.0), + DismissibleTime(0.0), + LastPollTime(0.0), + HMD(hmd), + HMDMounted(false), + HMDNewlyMounted(false), + RenderAPIType(renderAPIType), + RenderState(hmdRenderState), + LastProfileName(), + LastHSWTime(0) +{ +} + + +HSWDisplay::~HSWDisplay() +{ + // To consider: assert that we are already shut down. + HSWDisplay::Shutdown(); +} + + +void HSWDisplay::Enable(bool enable) +{ + Enabled = enable; + + if(!enable && Displayed) // If it's visible but should not be... + Dismiss(); +} + + +void HSWDisplay::EnableRender(bool enable) +{ + RenderEnabled = enable; +} + + +void HSWDisplay::Display() +{ + HSWDISPLAY_LOG(("[HSWDisplay] Display()")); + + DisplayInternal(); + + HMDNewlyMounted = false; + Displayed = true; + SDKRendered = RenderEnabled; + StartTime = ovr_GetTimeInSeconds(); + + const time_t lastDisplayedTime = HSWDisplay::GetCurrentProfileLastHSWTime(); + DismissibleTime = StartTime + ((lastDisplayedTime == HSWDisplayTimeNever) ? HSWDISPLAY_FIRST_DISMISSAL_TIME : HSWDISPLAY_REGULAR_DISMISSAL_TIME); + + SetCurrentProfileLastHSWTime(time(NULL)); +} + + +bool HSWDisplay::IsDisplayViewable() const +{ + // This function is called IsDisplayViewable, but currently it refers only to whether the + // HMD is mounted on the user's head. + + return HMDMounted; +} + + +bool HSWDisplay::Dismiss() +{ + #if HSWDISPLAY_DEBUGGING && defined(OVR_OS_WIN32) + if(GetKeyState(VK_SCROLL) & 0x0001) // If the scroll lock key is toggled on... + return false; // Make it so that the display doesn't dismiss, so we can debug this. + #endif + + // If dismissal is not requested yet, mark it as such. + bool newlyRequested = false; + + if(!DismissRequested) + { + DismissRequested = true; + newlyRequested = true; + } + + // If displayed and time has elapsed, do the dismissal. + OVR_ASSERT(DismissibleTime <= (ovr_GetTimeInSeconds() + HSWDISPLAY_FIRST_DISMISSAL_TIME)); // Make sure the dismissal time is sane. + if (Displayed && (ovr_GetTimeInSeconds() >= DismissibleTime)) + { + DismissInternal(); + Displayed = false; + DismissRequested = false; + SDKRendered = false; + return true; + } + + if(newlyRequested) + { HSWDISPLAY_LOG(("[HSWDisplay] Dismiss(): Not permitted yet. Queued for timeout in %.1f seconds.", DismissibleTime - ovr_GetTimeInSeconds())); } + + return false; // Cannot dismiss yet. +} + + +bool HSWDisplay::TickState(ovrHSWDisplayState *hswDisplayState, bool graphicsContext) +{ + bool newlyDisplayed = false; + const double currentTime = ovr_GetTimeInSeconds(); + + // See if we need to be currently displayed. By design we automatically display but don't automatically dismiss. + if (Displayed) + { + if (DismissRequested) // If dismiss was previously requested, see if it can be executed. + Dismiss(); + + if (Displayed) // If not already dismissed above... + { + // We currently have the debug behavior that we permit dismiss very soon after launch. + #if defined(OVR_BUILD_DEBUG) + if(currentTime >= (StartTime + 2)) + { + DismissibleTime = StartTime; + //Dismiss(); + } + #endif + } + + if (Displayed) // If not already dismissed above... + { + const ovrTrackingState ts = ((OVR::CAPI::HMDState*)HMD->Handle)->PredictedTrackingState(currentTime); + + if (ts.StatusFlags & ovrStatus_OrientationTracked) // If the Accelerometer data is valid... + { + const OVR::Vector3f v(ts.HeadPose.LinearAcceleration.x, ts.HeadPose.LinearAcceleration.y, ts.HeadPose.LinearAcceleration.z); + + const float minTapMagnitude = 350.0f; // Empirically determined by some testing. + + if (v.LengthSq() > minTapMagnitude) + Dismiss(); // This will do nothing if the display is not present. + } + } + } + else if (Enabled && (currentTime >= (LastPollTime + HSWDISPLAY_POLL_INTERVAL))) + { + LastPollTime = currentTime; + + // We need to display if any of the following are true: + // - The application is just started in Event Mode while the HMD is mounted (warning display would be viewable) and this app was not spawned from a launcher. + // - The current user has never seen the display yet while the HMD is mounted (warning display would be viewable). + // - The HMD is newly mounted (or the warning display is otherwise newly viewable). + // - The warning display hasn't shown in 24 hours (need to verify this as a requirement). + // Event Mode refers to when the app is being run in a public demo event such as a trade show. + + OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)HMD->Handle; + + if(pHMDState) + { + const time_t lastDisplayedTime = HSWDisplay::GetCurrentProfileLastHSWTime(); + + // We currently unilaterally set HMDMounted to true because we don't yet have the ability to detect this. To do: Implement this when possible. + const bool previouslyMounted = HMDMounted; + HMDMounted = true; + HMDNewlyMounted = (!previouslyMounted && HMDMounted); // We set this back to false in the Display function or if the HMD is unmounted before then. + + if((lastDisplayedTime == HSWDisplayTimeNever) || HMDNewlyMounted) + { + if(IsDisplayViewable()) // If the HMD is mounted and otherwise being viewed by the user... + { + Display(); + newlyDisplayed = true; + } + } + } + } + else if(graphicsContext && UnloadGraphicsRequested) + { + UnloadGraphics(); + UnloadGraphicsRequested = false; + } + + if(hswDisplayState) + GetState(hswDisplayState); + + return newlyDisplayed; +} + + +void HSWDisplay::GetState(ovrHSWDisplayState *hswDisplayState) const +{ + // Return the state to the caller. + OVR_ASSERT(hswDisplayState != NULL); + if(hswDisplayState) + { + hswDisplayState->Displayed = Displayed; + hswDisplayState->StartTime = StartTime; + hswDisplayState->DismissibleTime = DismissibleTime; + } +} + + +void HSWDisplay::Render(ovrEyeType eye, const ovrTexture* eyeTexture) +{ + SDKRendered = true; + RenderInternal(eye, eyeTexture); +} + +// Persist the HSW settings on the server, since it needs to be synchronized across all applications. +// Note that the profile manager singleton cannot be used for this task because it overwrites the global +// settings for which the rift config tool is supposed to be authoritative. That also would step on the +// settings generated by other rift apps. The server settings, however, are synchronized for all apps +// and so are appropriate for this task. +static String getHSWTimeKey(const char* userName) +{ + String keyName = "server:"; + keyName += OVR_KEY_HSWDISPLAYLASTDISPLAYEDTIME; + keyName += ":"; + if (userName) + { + keyName += userName; + } + return keyName; +} + +// Returns HSWDisplayTimeNever (0) if there is no profile or this is the first time we are seeing this profile. +time_t HSWDisplay::GetCurrentProfileLastHSWTime() const +{ + // We store the timeout value in HMDState's pProfile. + HMDState* pHMDState = (HMDState*)HMD->Handle; + + if (pHMDState) + { + const char* profileName = pHMDState->pProfile ? pHMDState->pProfile->GetValue(OVR_KEY_USER) : NULL; + + if (profileName) + { + if (LastProfileName == profileName) + { + return LastHSWTime; + } + + LastProfileName = profileName; + String timeKey = getHSWTimeKey(profileName); + int lastTime = pHMDState->getIntValue(timeKey.ToCStr(), (int)HSWDisplayTimeNever); + + LastHSWTime = lastTime; + return lastTime; + } + } + + return HSWDisplayTimeNever; +} + +void HSWDisplay::SetCurrentProfileLastHSWTime(time_t t) +{ + // The timeout value is stored in HMDState's pProfile. + HMDState* pHMDState = (HMDState*)HMD->Handle; + + if (pHMDState) + { + const char* profileName = pHMDState->pProfile ? pHMDState->pProfile->GetValue(OVR_KEY_USER) : NULL; + + if (profileName) + { + LastProfileName = profileName; + LastHSWTime = (int)t; + + String timeKey = getHSWTimeKey(profileName); + pHMDState->setIntValue(timeKey.ToCStr(), (int)t); + } + } +} + + +// Generates an appropriate stereo ortho projection matrix. +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); + + 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); + + 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); +} + + +const uint8_t* HSWDisplay::GetDefaultTexture(size_t& TextureSize) +{ + TextureSize = sizeof(healthAndSafety_tga); + return healthAndSafety_tga; +} + + + +}} // namespace OVR::CAPI + + + + +//------------------------------------------------------------------------------------- +// ***** HSWDisplay factory +// + +#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" + + +OVR::CAPI::HSWDisplay* OVR::CAPI::HSWDisplay::Factory(ovrRenderAPIType apiType, ovrHmd hmd, const OVR::CAPI::HMDRenderState& renderState) +{ + OVR::CAPI::HSWDisplay* pHSWDisplay = NULL; + + switch (apiType) + { + case ovrRenderAPI_None: + pHSWDisplay = new OVR::CAPI::HSWDisplay(apiType, hmd, renderState); + break; + + case ovrRenderAPI_OpenGL: + pHSWDisplay = new OVR::CAPI::GL::HSWDisplay(apiType, hmd, renderState); + break; + + #if defined(OVR_OS_WIN32) + case ovrRenderAPI_D3D9: + 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; + #else + case ovrRenderAPI_D3D9: + case ovrRenderAPI_D3D10: + case ovrRenderAPI_D3D11: // Fall through + #endif + + // Handle unsupported cases. + case ovrRenderAPI_Android_GLES: + case ovrRenderAPI_Count: // This is not actually a type. + default: + break; + } + + return pHSWDisplay; +} + + + + + diff --git a/LibOVR/Src/CAPI/CAPI_HSWDisplay.h b/LibOVR/Src/CAPI/CAPI_HSWDisplay.h new file mode 100644 index 0000000..ee984d8 --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_HSWDisplay.h @@ -0,0 +1,249 @@ +/************************************************************************************ + +Filename : CAPI_HSWDisplay.h +Content : Implements Health and Safety Warning system. +Created : July 3, 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_HSWDisplay_h +#define OVR_CAPI_HSWDisplay_h + +#include "../OVR_CAPI.h" +#include "CAPI_HMDRenderState.h" +#include + + + +//------------------------------------------------------------------------------------- +// ***** HSWDISPLAY_LOG +// +// Debug log wrapper. + +#if !defined(HSWDISPLAY_LOG_ENABLED) + #ifdef OVR_BUILD_DEBUG + #define HSWDISPLAY_LOG_ENABLED 1 + #else + #define HSWDISPLAY_LOG_ENABLED 0 + #endif +#endif + +#if HSWDISPLAY_LOG_ENABLED + #define HSWDISPLAY_LOG(...) OVR_DEBUG_LOG(__VA_ARGS__) +#else + #define HSWDISPLAY_LOG(...) +#endif + + +//------------------------------------------------------------------------------------- +// ***** HSWDISPLAY_DISTANCE +// +// Floating point value in the range of ~0.75 to ~3.0 which controls the distance +// (in meters) of the display from the viewer. + +#ifndef HSWDISPLAY_DISTANCE + #define HSWDISPLAY_DISTANCE 1.5f +#endif + + +//------------------------------------------------------------------------------------- +// ***** HSWDISPLAY_SCALE +// +// Floating point value in the range of ~0.1 to ~2.0 which controls the size scale of the +// SDK-rendered HSW display. The value is an arbitrary relative value, though this may +// change in future SDK versions. + +#ifndef HSWDISPLAY_SCALE + #define HSWDISPLAY_SCALE 0.92f +#endif + + + + +//------------------------------------------------------------------------------------- +// ***** 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 { + + +//------------------------------------------------------------------------------------- +// ***** CAPI::HSWDisplay +// +// Note: This will be renamed to HSWDisplay in the future. +// +// Implements the logic for the Health and Safety (HAS) warning display. Primarily this +// is two things: providing information about whether the warning needs to be currently +// displayed, and implementing the display itself. +// +// An HSWDisplay is associated 1:1 with an HMD. There can be at most one HSWDisplay +// being displayed on an HMD at a time. If a warning needs to be displayed while an +// existing one is present, it replaces the existing one. +// +// Notes +// Warnings are displayed per HMD (head mounted display). +// The app can have multiple HMDs. +// There can be multiple users of a given HMD over time, with each identified by a different user profile. +// There can be multiple apps using HMDs. +// +// Shows upon first entering a VR application (or VR mode in an application) when in Event Mode (e.g. trade show). +// Shows upon each wearing of the HMD. +// If the user profile is switched while display is active, the display must restart. +// Doesn't show in app when app was started by a launcher app. +// +// First display ever (per profile): 15 seconds until the display can be dismissed. +// Subsequent displays: 6 seconds until the display can be dismissed. Per profile. +// Dismissing occurs via HMD tap, designated keypress, gaze detection on OK button for N seconds, +// and possibly via an input gesture in the future. +// +// If the warning fades out upon completion, the fade out should begin after the full display time has elapsed, +// but it needs to avoid interfering (e.g. obscuring) with the application. This likely means the application +// would need to put in a couple seconds delay to allow the fade to complete. +// Ideally we'd handle the case of a user switching HMDs and not needing to see the warning again. + +class HSWDisplay : public RefCountBase +{ +public: + HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); + + virtual ~HSWDisplay(); + + // Must be called after construction and before use. + virtual bool Initialize(const ovrRenderAPIConfig*) + { return true; } + + // Must be called before destruction. + virtual void Shutdown() {} + + // Enables or disables the HSW display system. It may be disabled only for development uses. + // It is enabled by default. + void Enable(bool enable); + + // Enables or disables our internal rendering when Render is called. If set to false then the + // application is expected to implement drawing of the display when Displayed is true. + // It is enabled by default. + void EnableRender(bool enable); + + // Triggers a display of the HSW display for the associated HMD. Restarts the display if + // the warning is already being displayed. + void Display(); + + // This function should be called per HMD every frame in order to give this class processing time. + // Writes the new state to newHSWDisplayState if it's non-NULL. + // The graphicsContext argument indicates if the Tick is occurring within a graphics context and + // thus if graphics operations are allowed during the TickState call. + // Returns true if the new state results in a required warning display (ovrHSWDisplayState::Displayed became true). + bool TickState(ovrHSWDisplayState *newHSWDisplayState = NULL, bool graphicsContext = false); + + // Gets the current state of the HSW display. + // Corresponds to ovrhmd_GetHSWDisplayState. + void GetState(ovrHSWDisplayState *hasWarningState) const; + + // Removes the HSW display display if the minimum dismissal time has occurred. + // Returns true if the warning display could be dissmissed or was not displayed at the time of the call. + // Corresponds to ovrhmd_DismissHSWDisplay. + bool Dismiss(); + + // Returns true if the HMD appears to be currently mounted and in a state that a + // warning display would be viewable. + bool IsDisplayViewable() const; + + // 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. + virtual void Render(ovrEyeType, const ovrTexture*); + + // Resets the current profile's HAS settings (e.g. to act as if the user has never seen the HSW display before). + void ResetProfileData(); + + // Returns the ovrRenderAPIType. This is essentially the same as RTTI, as it's indicating what subclass + // is being used for this. + ovrRenderAPIType GetRenderAPIType() const // e.g. ovrRenderAPI_D3D11 + { return RenderAPIType; } + + // Returns the required HSW display text for the current profile's locale. + // Useful for implementing custom warning displays. Returns the required strlen + // of the text, and thus success is indicated by a return value < strCapacity. + // size_t GetText(char *str, size_t strCapacity); + + // Creates and constructs an instance of an HSWDisplay subclass based on the API type. + static HSWDisplay* Factory(ovrRenderAPIType apiType, ovrHmd hmd, const HMDRenderState& renderState); + +private: + OVR_NON_COPYABLE(HSWDisplay) + +protected: + virtual void DisplayInternal() {} + virtual void DismissInternal() {} + virtual void RenderInternal(ovrEyeType, const ovrTexture*) {} + virtual void UnloadGraphics() {} + virtual void LoadGraphics() {} + + // Profile functionality + time_t GetCurrentProfileLastHSWTime() const; + void SetCurrentProfileLastHSWTime(time_t t); + + // Generates an appropriate stereo ortho projection matrix. + static void GetOrthoProjection(const HMDRenderState& RenderState, Matrix4f OrthoProjection[2]); + + // Returns the default HSW display texture data. + static const uint8_t* GetDefaultTexture(size_t& TextureSize); + +protected: + bool Enabled; // If true then the HSW display system is enabled. True by default. + bool Displayed; // If true then the warning is currently visible and the following variables have meaning. Else there is no warning being displayed for this application on the given HMD. + bool SDKRendered; // If true then the display is being rendered by the SDK as opposed to the application. + bool DismissRequested; // If true then the warning has been requested to be hidden. + bool RenderEnabled; // If true then we handle rendering when Render is called. Else we skip it and assume the application is otherwise handling it itself. + bool UnloadGraphicsRequested; // If true then an unload of graphics was requested. This acts as a message from the main thread to the drawing thread so that the unload happens in the expected thread. + double StartTime; // Absolute time when the warning was first displayed. See ovr_GetTimeInSeconds(). + double DismissibleTime; // Absolute time when the warning can be dismissed. + double LastPollTime; // Used to prevent us from polling the required display state every frame but rather more like every 200 milliseconds. + const ovrHmd HMD; // The HMDState this HSWDisplay instance corresponds to. + mutable bool HMDMounted; // True if the HMD was most recently found to be mounted. We need this in order to maintain HMDNewlyMounted. + mutable bool HMDNewlyMounted; // True if HMDMounted has transitioned from false to true. We need this in order to tell if the HMD was recently mounted so we can display the HSW display. + const ovrRenderAPIType RenderAPIType; // e.g. ovrRenderAPI_D3D11 + const HMDRenderState& RenderState; // Information about the rendering setup. + + // Settings cache + mutable String LastProfileName; + mutable int LastHSWTime; + +}; // class HSWDisplay + + + +}} // namespace OVR::CAPI + + +#endif // OVR_CAPI_HSWDisplay_h diff --git a/LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp b/LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp new file mode 100644 index 0000000..c43418a --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp @@ -0,0 +1,316 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..0c2f3bd --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_LatencyStatistics.h @@ -0,0 +1,178 @@ +/************************************************************************************ + +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 index fbdee63..6439b57 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp @@ -5,16 +5,16 @@ Content : Distortion renderer instantiation for D3D10 Created : November 11, 2013 Authors : Volga Aksoy, Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h index dd697be..a6750f5 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h @@ -5,16 +5,16 @@ Content : Distortion renderer header for D3D10 Created : November 11, 2013 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -31,4 +31,4 @@ limitations under the License. #include "CAPI_D3D1X_DistortionRenderer.h" #undef OVR_D3D_VERSION -#endif \ No newline at end of file +#endif diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp new file mode 100644 index 0000000..33deffa --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp @@ -0,0 +1,35 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..c681c73 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h @@ -0,0 +1,41 @@ +/************************************************************************************ + +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 7a2a569..2ba9ccc 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp @@ -5,16 +5,16 @@ Content : Distortion renderer instantiation for D3D11 Created : November 11, 2013 Authors : Volga Aksoy, Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h index 4362d50..0216232 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h @@ -5,16 +5,16 @@ Content : Distortion renderer header for D3D11 Created : November 11, 2013 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -31,4 +31,4 @@ limitations under the License. #include "CAPI_D3D1X_DistortionRenderer.h" #undef OVR_D3D_VERSION -#endif \ No newline at end of file +#endif diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp new file mode 100644 index 0000000..2177815 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp @@ -0,0 +1,35 @@ +/************************************************************************************ + +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 + + + + + + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h new file mode 100644 index 0000000..ca896b0 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h @@ -0,0 +1,41 @@ +/************************************************************************************ + +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 + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp index 60e2c88..04cfd07 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp @@ -3,18 +3,18 @@ Filename : CAPI_D3D1X_DistortionRenderer.cpp Content : Experimental distortion renderer Created : November 11, 2013 -Authors : Volga Aksoy, Michael Antonov +Authors : Volga Aksoy, Michael Antonov, Shariq Hashme -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -27,26 +27,33 @@ 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/SimpleQuad_vs.h" -#include "../Shaders/SimpleQuad_vs_refl.h" -#include "../Shaders/SimpleQuad_ps.h" -#include "../Shaders/SimpleQuad_ps_refl.h" +#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 @@ -56,7 +63,7 @@ enum { DistortionVertexShaderBitMask = 3, DistortionVertexShaderCount = DistortionVertexShaderBitMask + 1, DistortionPixelShaderBitMask = 1, - DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1 + DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1, }; struct PrecompiledShader @@ -83,8 +90,21 @@ static PrecompiledShader DistortionVertexShaderLookup[DistortionVertexShaderCoun static PrecompiledShader DistortionPixelShaderLookup[DistortionPixelShaderCount] = { PCS_NOREFL(Distortion_ps), - PCS_NOREFL(DistortionChroma_ps) + PCS_REFL__(DistortionChroma_ps) +}; + +enum +{ + DistortionComputeShader2x2 = 0, + DistortionComputeShader2x2Pentile, + DistortionComputeShaderCount }; +static PrecompiledShader DistortionComputeShaderLookup[DistortionComputeShaderCount] = +{ + PCS_REFL__(DistortionCS2x2) +}; + + void DistortionShaderBitIndexCheck() { @@ -94,15 +114,24 @@ void DistortionShaderBitIndexCheck() -struct DistortionVertex +struct DistortionVertex // Must match the VB description DistortionMeshVertexDesc { - Vector2f Pos; - Vector2f TexR; - Vector2f TexG; - Vector2f TexB; + 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. @@ -135,6 +164,8 @@ 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); @@ -155,8 +186,7 @@ CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, } -bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned distortionCaps) +bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) { const ovrD3D1X(Config)* config = (const ovrD3D1X(Config)*)apiConfig; @@ -171,24 +201,48 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, 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.RTSize = config->D3D_NS.Header.RTSize; + RParams.BackBufferSize = config->D3D_NS.Header.BackBufferSize; RParams.Multisample = config->D3D_NS.Header.Multisample; GfxState = *new GraphicsState(RParams.pContext); - DistortionCaps = distortionCaps; + 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); - //DistortionWarper.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true); + +#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(Sample_Linear|Sample_ClampBorder)); + getSamplerState(hqFilter|Sample_ClampBorder)); pEyeTextures[1] = *new Texture(&RParams, Texture_RGBA, Sizei(0), - getSamplerState(Sample_Linear|Sample_ClampBorder)); + getSamplerState(hqFilter|Sample_ClampBorder)); initBuffersAndShaders(); @@ -199,8 +253,11 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, 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 @@ -211,8 +268,53 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, 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, ovrTexture* eyeTexture) +void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) { const ovrD3D1X(Texture)* tex = (const ovrD3D1X(Texture)*)eyeTexture; @@ -229,44 +331,64 @@ void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) 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::EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, - unsigned char* latencyTester2DrawColor) +void DistortionRenderer::renderEndFrame() { - if (!TimeManager.NeedDistortionTimeMeasurement()) - { - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) - { - // Wait for timewarp distortion if it is time and Gpu idle - FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); - } + renderDistortion(pEyeTextures[0], pEyeTextures[1]); + + if(RegisteredPostDistortionCallback) + RegisteredPostDistortionCallback(RParams.pContext); - renderDistortion(pEyeTextures[0], pEyeTextures[1]); + if(LatencyTest2Active) + { + renderLatencyPixel(LatencyTest2DrawColor); } - else +} + +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 needed, measure distortion time so that TimeManager can better estimate - // latency-reducing time-warp wait timing. - WaitUntilGpuIdle(); - double distortionStartTime = ovr_GetTimeInSeconds(); + 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(); - renderDistortion(pEyeTextures[0], pEyeTextures[1]); + renderEndFrame(); - WaitUntilGpuIdle(); - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + WaitUntilGpuIdle(); + TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + } } - - if(latencyTesterDrawColor) + else { - renderLatencyQuad(latencyTesterDrawColor); + renderEndFrame(); } - else if(latencyTester2DrawColor) + + if(LatencyTestActive) { - renderLatencyPixel(latencyTester2DrawColor); + renderLatencyQuad(LatencyTestDrawColor); } if (swapBuffers) @@ -278,7 +400,12 @@ void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTester // Force GPU to flush the scene, resulting in the lowest possible latency. // It's critical that this flush is *after* present. - WaitUntilGpuIdle(); + // 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 { @@ -312,99 +439,180 @@ void DistortionRenderer::WaitUntilGpuIdle() double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) { - double initialTime = ovr_GetTimeInSeconds(); - if (initialTime >= absTime) - return 0.0; - - // 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; - bool callGetData = false; - - if (RParams.pDevice->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK) - { - D3DSELECT_10_11(query->End(), - RParams.pContext->End(query)); - callGetData = true; - } - - double newTime = initialTime; - volatile int i; - - while (newTime < absTime) - { - if (callGetData) - { - // GetData will returns S_OK for both done == TRUE or FALSE. - // Stop calling GetData on failure. - callGetData = !FAILED(D3DSELECT_10_11(query->GetData(&done, sizeof(BOOL), 0), - RParams.pContext->GetData(query, &done, sizeof(BOOL), 0))) && !done; - } - else - { - for (int j = 0; j < 50; j++) - i = 0; - } - newTime = ovr_GetTimeInSeconds(); - } - - // How long we waited - return newTime - initialTime; + RParams.pContext->Flush(); + return WaitTillTime(absTime); } void DistortionRenderer::initBuffersAndShaders() { - for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) + if ( RState.DistortionCaps & ovrDistortionCap_ComputeShader ) { - // Allocate & generate distortion mesh vertices. - 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; + // 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]) ); } -// 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++ ) + } + else + { + for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) { - pCurVBVert->Pos.x = pCurOvrVert->Pos.x; - pCurVBVert->Pos.y = pCurOvrVert->Pos.y; - pCurVBVert->TexR = (*(Vector2f*)&pCurOvrVert->TexR); - pCurVBVert->TexG = (*(Vector2f*)&pCurOvrVert->TexG); - pCurVBVert->TexB = (*(Vector2f*)&pCurOvrVert->TexB); - // Convert [0.0f,1.0f] to [0,255] - pCurVBVert->Col.R = (OVR::UByte)( pCurOvrVert->VignetteFactor * 255.99f ); - pCurVBVert->Col.G = pCurVBVert->Col.R; - pCurVBVert->Col.B = pCurVBVert->Col.R; - pCurVBVert->Col.A = (OVR::UByte)( pCurOvrVert->TimeWarpFactor * 255.99f );; - pCurOvrVert++; - pCurVBVert++; + // 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 ); } - - 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++) { @@ -417,43 +625,166 @@ void DistortionRenderer::initBuffersAndShaders() 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); - RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0); - - setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h)); - + 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); + 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 (DistortionCaps & ovrDistortionCap_TimeWarp) + + if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) { - ovrMatrix4f timeWarpMatrices[2]; + ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, RState.EyeRenderPoses[eyeNum], timeWarpMatrices); - // Feed identity like matrices in until we get proper timewarp calculation going on - DistortionShader->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0])); - DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1])); - - renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], - NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles); + 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)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles); + 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() @@ -498,17 +829,20 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor ShaderFill quadFill(SimpleQuadShader); quadFill.SetInputLayout(SimpleQuadVertexIL); - setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h)); + 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.2f, 0.2f); - SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f, - (float)latencyTesterDrawColor[0] / 255.99f, - (float)latencyTesterDrawColor[0] / 255.99f, - 1.0f); + 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.4f : 0.4f, 0.0f); + SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.5f : 0.5f, 0.0f); renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip); } } @@ -521,20 +855,35 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol { createDrawQuad(); } - + ShaderFill quadFill(SimpleQuadShader); quadFill.SetInputLayout(SimpleQuadVertexIL); - setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h)); + 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); + } - SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f, - (float)latencyTesterPixelColor[0] / 255.99f, - (float)latencyTesterPixelColor[0] / 255.99f, - 1.0f); +#ifdef OVR_BUILD_DEBUG + SimpleQuadShader->SetUniform4f("Color", testerColor.x, testerColor.y, testerColor.z, 1.0f); - Vector2f scale(2.0f / RParams.RTSize.w, 2.0f / RParams.RTSize.h); + 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, 1.0f); + SimpleQuadShader->SetUniform2f("PositionOffset", 1.0f-scale.x, 1.0f-scale.y); renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip); } @@ -628,7 +977,7 @@ void DistortionRenderer::setViewport(const Recti& vp) - +// Must match struct DistortionVertex static D3D1X_(INPUT_ELEMENT_DESC) DistortionMeshVertexDesc[] = { {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0}, @@ -643,17 +992,43 @@ 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 ) { - PrecompiledShader vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps]; + // 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); - ID3D1xInputLayout** objRef = &DistortionVertexIL.GetRawRef(); + DistortionVertexIL = NULL; + ID3D1xInputLayout** objRef = &DistortionVertexIL.GetRawRef(); HRESULT validate = RParams.pDevice->CreateInputLayout( DistortionMeshVertexDesc, sizeof(DistortionMeshVertexDesc) / sizeof(DistortionMeshVertexDesc[0]), @@ -663,7 +1038,7 @@ void DistortionRenderer::initShaders() DistortionShader = *new ShaderSet; DistortionShader->SetShader(vtxShader); - PrecompiledShader psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps]; + PrecompiledShader psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & RState.DistortionCaps]; Ptr ps = *new D3D_NS::PixelShader( &RParams, @@ -680,6 +1055,7 @@ void DistortionRenderer::initShaders() 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( @@ -722,7 +1098,7 @@ ID3D1xSamplerState* DistortionRenderer::getSamplerState(int sm) else if (sm & Sample_Anisotropic) { ss.Filter = D3D1X_(FILTER_ANISOTROPIC); - ss.MaxAnisotropy = 8; + ss.MaxAnisotropy = 4; } else { @@ -740,6 +1116,7 @@ void DistortionRenderer::destroy() { DistortionMeshVBs[eyeNum].Clear(); DistortionMeshIBs[eyeNum].Clear(); + DistortionPinBuffer[eyeNum].Clear(); } DistortionVertexIL.Clear(); @@ -748,6 +1125,7 @@ void DistortionRenderer::destroy() { DistortionShader->UnsetShader(Shader_Vertex); DistortionShader->UnsetShader(Shader_Pixel); + DistortionShader->UnsetShader(Shader_Compute); DistortionShader.Clear(); } @@ -757,48 +1135,280 @@ void DistortionRenderer::destroy() 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 < 8; ++i) - samplerStates[i] = NULL; + 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::Save() +void DistortionRenderer::GraphicsState::clearMemory() { - if (rasterizerState != NULL) - rasterizerState->Release(); + SAFE_RELEASE ( rasterizerState ); - context->RSGetState(&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 < 8; ++i) + for (int i = 0; i < D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { - if (samplerStates[i] != NULL) - samplerStates[i]->Release(); + 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] ); } - context->PSGetSamplers(0, 8, samplerStates); + 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); - rasterizerState->Release(); - rasterizerState = NULL; - } - for (int i = 0; i < 8; ++i) - { - if (samplerStates[i] == NULL) - continue; + if (inputLayoutState != NULL) + context->IASetInputLayout(inputLayoutState); - context->PSSetSamplers(0, 1, &samplerStates[i]); - samplerStates[i]->Release(); - samplerStates[i] = NULL; - } + 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 index 433d6ec..0bbf049 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h @@ -5,16 +5,16 @@ Content : Experimental distortion renderer Created : November 11, 2013 Authors : Volga Aksoy -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -56,12 +56,11 @@ public: // ***** Public DistortionRenderer interface - virtual bool Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned distortionCaps); + virtual bool Initialize(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; - virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture); + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture); - virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor); + virtual void EndFrame(bool swapBuffers); // TBD: Make public? void WaitUntilGpuIdle(); @@ -76,13 +75,59 @@ protected: { public: GraphicsState(ID3D1xDeviceContext* context); + virtual ~GraphicsState(); + virtual void clearMemory(); virtual void Save(); virtual void Restore(); protected: - ID3D1xRasterizerState* rasterizerState; - ID3D1xSamplerState* samplerStates[8]; 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: @@ -90,6 +135,7 @@ private: void initBuffersAndShaders(); void initShaders(); void initFullscreenQuad(); + void initOverdrive(); void destroy(); void setViewport(const Recti& vp); @@ -100,6 +146,8 @@ private: Matrix4f* viewMatrix, int offset, int count, PrimitiveType rprim); + void renderEndFrame(); + void createDrawQuad(); void renderLatencyQuad(unsigned char* latencyTesterDrawColor); void renderLatencyPixel(unsigned char* latencyTesterPixelColor); @@ -108,22 +156,28 @@ private: ID3D1xSamplerState* getSamplerState(int sm); - // TBD: Should we be using oe from RState instead? - unsigned DistortionCaps; + //// 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; diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp new file mode 100644 index 0000000..61f915f --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp @@ -0,0 +1,595 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..2c5762d --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h @@ -0,0 +1,84 @@ +/************************************************************************************ + +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 index 90b4347..f95fb3c 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp @@ -5,16 +5,16 @@ Content : D3DX10 utility classes for rendering Created : September 10, 2012 Authors : Andrew Reisse -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -37,11 +37,28 @@ namespace OVR { namespace CAPI { namespace D3D_NS { void ShaderFill::Set(PrimitiveType prim) const { Shaders->Set(prim); - for(int i = 0; i < 8; i++) + + 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(Textures[i]) + if ( PsTextures[i] != NULL ) { - Textures[i]->Set(i); + PsTextures[i]->Set(i, Shader_Fragment); } } } @@ -54,7 +71,7 @@ Buffer::~Buffer() { } -bool Buffer::Data(int use, const void *buffer, size_t size) +bool Buffer::Data(int use, const void *buffer, size_t size, int computeBufferStride /*=-1*/) { if (D3DBuffer && Size >= size) { @@ -73,6 +90,7 @@ bool Buffer::Data(int use, const void *buffer, size_t size) } else { + OVR_ASSERT (!(use & Buffer_ReadOnly)); pParams->pContext->UpdateSubresource(D3DBuffer, 0, NULL, buffer, 0, 0); return true; } @@ -82,8 +100,12 @@ bool Buffer::Data(int use, const void *buffer, size_t size) D3DBuffer = NULL; Size = 0; Use = 0; - Dynamic = 0; + Dynamic = false; } + D3DSrv = NULL; +#if (OVR_D3D_VERSION >= 11) + D3DUav = NULL; +#endif D3D1X_(BUFFER_DESC) desc; memset(&desc, 0, sizeof(desc)); @@ -96,7 +118,7 @@ bool Buffer::Data(int use, const void *buffer, size_t size) { desc.Usage = D3D1X_(USAGE_DYNAMIC); desc.CPUAccessFlags = D3D1X_(CPU_ACCESS_WRITE); - Dynamic = 1; + Dynamic = true; } switch(use & Buffer_TypeMask) @@ -105,7 +127,32 @@ bool Buffer::Data(int use, const void *buffer, size_t size) case Buffer_Index: desc.BindFlags = D3D1X_(BIND_INDEX_BUFFER); break; case Buffer_Uniform: desc.BindFlags = D3D1X_(BIND_CONSTANT_BUFFER); - size += ((size + 15) & ~15) - size; + 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; } @@ -116,14 +163,46 @@ bool Buffer::Data(int use, const void *buffer, size_t size) 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; - return 1; } - return 0; + 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) @@ -170,6 +249,12 @@ template<> bool ShaderImpl::Load(void* shader, { 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 { @@ -179,6 +264,12 @@ template<> void ShaderImpl::Set(PrimitiveType) { 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) { @@ -188,19 +279,36 @@ template<> void ShaderImpl::SetUniformBuffer(Bu { 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(0) +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); + 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) @@ -292,7 +400,16 @@ void Texture::Set(int slot, ShaderStage stage) const 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; } } diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h index 5213565..dc5dc8d 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h @@ -5,16 +5,16 @@ Content : D3DX 10/11 utility classes for rendering Created : September 10, 2012 Authors : Andrew Reisse -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -42,6 +42,7 @@ limitations under the License. #include "../../Kernel/OVR_Math.h" #if defined(OVR_OS_WIN32) +#define WIN32_LEAN_AND_MEAN #include #include // for _COM_SMARTPTR_TYPEDEF() @@ -96,6 +97,13 @@ 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; @@ -107,6 +115,13 @@ 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; @@ -129,12 +144,13 @@ class Buffer; // Rendering parameters/pointers describing D3DX rendering setup. struct RenderParams { - ID3D1xDevice* pDevice; - ID3D1xDeviceContext* pContext; - ID3D1xRenderTargetView* pBackBufferRT; - IDXGISwapChain* pSwapChain; - Sizei RTSize; - int Multisample; + ID3D1xDevice* pDevice; + ID3D1xDeviceContext* pContext; + ID3D1xRenderTargetView* pBackBufferRT; + ID3D1xUnorderedAccessView* pBackBufferUAV; + IDXGISwapChain* pSwapChain; + Sizei BackBufferSize; + int Multisample; }; @@ -154,7 +170,8 @@ enum ShaderStage Shader_Vertex = 0, Shader_Fragment = 2, Shader_Pixel = 2, - Shader_Count = 3, + Shader_Compute = 3, // DX11+ only + Shader_Count = 4, }; enum MapFlags @@ -172,6 +189,7 @@ enum BufferUsage Buffer_Vertex = 1, Buffer_Index = 2, Buffer_Uniform = 4, + Buffer_Compute = 8, Buffer_TypeMask = 0xff, Buffer_ReadOnly = 0x100, // Buffer must be created with Data(). }; @@ -298,6 +316,13 @@ public: 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]); + } + }; @@ -306,7 +331,9 @@ public: class ShaderFill : public RefCountBase { Ptr Shaders; - Ptr Textures[8]; + Ptr PsTextures[8]; + Ptr VsTextures[8]; + Ptr CsTextures[8]; void* InputLayout; // HACK this should be abstracted public: @@ -317,7 +344,17 @@ public: void* GetInputLayout() const { return InputLayout; } virtual void Set(PrimitiveType prim = Prim_Unknown) const; - virtual void SetTexture(int i, class Texture* tex) { if (i < 8) Textures[i] = tex; } + + 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; } }; @@ -339,11 +376,12 @@ public: struct Uniform { const char* Name; - VarType Type; - int Offset, Size; + VarType Type; + int Offset; + int Size; }; - const Uniform* UniformRefl; - size_t UniformReflSize; + const Uniform* UniformRefl; + size_t UniformReflSize; ShaderBase(RenderParams* rp, ShaderStage stage); ~ShaderBase(); @@ -383,27 +421,53 @@ public: typedef ShaderImpl VertexShader; typedef ShaderImpl PixelShader; +#if (OVR_D3D_VERSION>=11) +typedef ShaderImpl ComputeShader; +#endif class Buffer : public RefCountBase { public: - RenderParams* pParams; - Ptr D3DBuffer; + 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), Size(0), Use(0) {} + 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; } + 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); + virtual bool Data(int use, const void* buffer, size_t size, int computeBufferStride = -1); }; @@ -415,6 +479,7 @@ public: Ptr TexSv; Ptr TexRtv; Ptr TexDsv; + // TODO: add UAV... mutable Ptr Sampler; Sizei TextureSize; int Samples; diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp deleted file mode 100644 index b777ab5..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_DistortionRenderer.cpp -Content : Experimental distortion renderer -Created : March 7th, 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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 { - - -///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) -{ -} -/**********************************************/ -DistortionRenderer::~DistortionRenderer() -{ - //Release any memory - eachEye[0].dxIndices->Release(); - eachEye[0].dxVerts->Release(); - eachEye[1].dxIndices->Release(); - eachEye[1].dxVerts->Release(); -} - - -/******************************************************************************/ -bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned arg_distortionCaps) -{ - ///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; - - //Glean all the required variables from the input structures - device = config->D3D9.pDevice; - swapChain = config->D3D9.pSwapChain; - screenSize = config->D3D9.Header.RTSize; - distortionCaps = arg_distortionCaps; - - GfxState = *new GraphicsState(device); - - CreateVertexDeclaration(); - CreateDistortionShaders(); - Create_Distortion_Models(); - - return true; -} - - -/**************************************************************/ -void DistortionRenderer::SubmitEye(int eyeId, 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 ); -} - - -/******************************************************************/ -void DistortionRenderer::EndFrame(bool swapBuffers, - unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) -{ - OVR_UNUSED(swapBuffers); - OVR_UNUSED(latencyTesterDrawColor); - - ///QUESTION : Should I be clearing the screen? - ///QUESTION : Should I be ensuring the screen is the render target - - if (!TimeManager.NeedDistortionTimeMeasurement()) - { - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) - { - // Wait for timewarp distortion if it is time and Gpu idle - WaitTillTimeAndFlushGpu(TimeManager.GetFrameTiming().TimewarpPointTime); - } - - RenderBothDistortionMeshes(); - } - else - { - // If needed, measure distortion time so that TimeManager can better estimate - // latency-reducing time-warp wait timing. - WaitUntilGpuIdle(); - double distortionStartTime = ovr_GetTimeInSeconds(); - - RenderBothDistortionMeshes(); - WaitUntilGpuIdle(); - - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); - } - - if(latencyTesterDrawColor) - { - ///QUESTION : Is this still to be supported? - ///renderLatencyQuad(latencyTesterDrawColor); - } - - if(latencyTester2DrawColor) - { - // TODO: - } - - 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. - 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)) ; - } - } -} - -double DistortionRenderer::WaitTillTimeAndFlushGpu(double absTime) -{ - double initialTime = ovr_GetTimeInSeconds(); - if (initialTime >= absTime) - return 0.0; - - WaitUntilGpuIdle(); - - double newTime = initialTime; - volatile int i; - - while (newTime < absTime) - { - for (int j = 0; j < 50; j++) - i = 0; - newTime = ovr_GetTimeInSeconds(); - } - - // How long we waited - return newTime - initialTime; -} - - - -DistortionRenderer::GraphicsState::GraphicsState(IDirect3DDevice9* d) -: device(d) -, numSavedStates(0) -{ -} - -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(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 ); -} - - -void DistortionRenderer::GraphicsState::Restore() -{ - for (int i = 0; iwhich == 0) - { - device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)sst->type, sst->valueToRevertTo); - } - else - { - device->SetRenderState((D3DRENDERSTATETYPE)sst->type, sst->valueToRevertTo); - } - } -} - - -}}} // OVR::CAPI::D3D1X - - diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h deleted file mode 100644 index 0ac7ae9..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h +++ /dev/null @@ -1,139 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_DistortionRenderer.h -Content : Experimental distortion renderer -Created : March 7, 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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" - -#undef new - -#if defined (OVR_OS_WIN32) -#if _MSC_VER < 1700 -#include -#else -#include -#endif -#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, - unsigned distortionCaps); - - virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture); - - virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor); - - // 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 WaitTillTimeAndFlushGpu(double absTime); - -protected: - - class GraphicsState : public CAPI::DistortionRenderer::GraphicsState - { - public: - GraphicsState(IDirect3DDevice9* d); - 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; - }; - -private: - - //Functions - void CreateDistortionShaders(void); - void Create_Distortion_Models(void); - void CreateVertexDeclaration(void); - void RenderBothDistortionMeshes(); - void RecordAndSetState(int which, int type, DWORD newValue); - void RevertAllStates(void); - - - //Data, structures and pointers - IDirect3DDevice9 * device; - IDirect3DSwapChain9 * swapChain; - IDirect3DVertexDeclaration9 * vertexDecl; - IDirect3DPixelShader9 * pixelShader; - IDirect3DVertexShader9 * vertexShader; - IDirect3DVertexShader9 * vertexShaderTimewarp; - ovrSizei screenSize; - unsigned distortionCaps; - - struct FOR_EACH_EYE - { - FOR_EACH_EYE() : TextureSize(0), RenderViewport(Sizei(0)) { } - - IDirect3DVertexBuffer9 * dxVerts; - IDirect3DIndexBuffer9 * dxIndices; - int numVerts; - int numIndices; - IDirect3DTexture9 * texture; - ovrVector2f UVScaleOffset[2]; - Sizei TextureSize; - Recti RenderViewport; - } eachEye[2]; -}; - -}}} // OVR::CAPI::D3D9 diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp deleted file mode 100644 index 793de74..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_Util.cpp -Content : D3D9 utility functions for rendering -Created : March 7 , 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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[95] = {4294836736,3014654,1111577667,28,127,4294836736,2,28,33024,120,68,131074,655361,88,0,104,2,131073,88,0,1415936325,1668436847,1716475477,1952805734,2880154368,196609,131073,1,0,1415936325,1668436847,1666405973,6646881,845116278,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,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[293] = {4294836736,4456446,1111577667,28,215,4294836736,4,28,33024,208,108,1310722,5373956,124,0,140,262146,1179652,124,0,157,131074,655361,176,0,192,2,131073,176,0,1382381893,1952543855,1164865385,2868929646,196611,262148,1,0,1382381893,1952543855,1399746409,1953653108,1702446336,1918070612,1331058019,1702061670,2880110708,196609,131073,1,0,1415936325,1668436847,1666405973,6646881,845116278,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147549184,2416902145,33554463,2147614720,2416902146,33554463,2147483653,2416902147,33554463,2147549189,2416902148,33554463,2147614725,2416902149,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,3758292992,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,3758292993,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,3758292994,2162425858,2162425856,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,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" -/***************************************************************************/ -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_2_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::Create_Distortion_Models(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, - 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]; - - 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]; - - ovrHmd_DestroyDistortionMesh( &meshData ); - } -} - -/**********************************************************/ -void DistortionRenderer::RenderBothDistortionMeshes(void) -{ - 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 (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); - } -} - -}}} \ No newline at end of file diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.csh b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.csh new file mode 100644 index 0000000..c30b32a --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.csh @@ -0,0 +1,389 @@ +/************************************************************************************ + +Filename : DistortionCS2x2Pentile.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. + +************************************************************************************/ + + +// Note - the only difference between the various Distortion Compute Shaders is these #defines. +// The code is otherwise identical, so if you change one, rememeber to change the others! +#define PENTILE_MODE 0 +#define ENABLE_OVERLAY 0 +#define ENABLE_TIMEWARP 1 + + +#define GRID_SIZE_IN_PIXELS 16 +#define PINS_PER_EDGE 128 +#define NXN_BLOCK_SIZE_PIXELS 2 +#define SIMD_SQUARE_SIZE 16 + + +struct DistortionComputePin +{ + float2 TanEyeAnglesR; + float2 TanEyeAnglesG; + float2 TanEyeAnglesB; + int Color; + int Padding[1]; +}; +struct DistortionComputePinUnpacked +{ + float2 TanEyeAnglesR; + float2 TanEyeAnglesG; + float2 TanEyeAnglesB; + float TimewarpLerp; + float Fade; +}; +struct DistortionComputePinTimewarped +{ + float2 HmdSpcTexCoordR; + float2 HmdSpcTexCoordG; + float2 HmdSpcTexCoordB; +#if ENABLE_OVERLAY + float2 OverlayTexCoordR; + float2 OverlayTexCoordG; + float2 OverlayTexCoordB; +#endif +}; + +// Cut'n'pasted from D3DX_DXGIFormatConvert.inl. Obviously we should have #included it, but... +typedef float4 XMFLOAT4; +typedef uint UINT; +#define D3DX11INLINE +#define hlsl_precise precise +D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_UNORM_to_FLOAT4(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + unpackedOutput.x = (FLOAT) (packedInput & 0x000000ff) / 255; + unpackedOutput.y = (FLOAT)(((packedInput>> 8) & 0x000000ff)) / 255; + unpackedOutput.z = (FLOAT)(((packedInput>>16) & 0x000000ff)) / 255; + unpackedOutput.w = (FLOAT) (packedInput>>24) / 255; + return unpackedOutput; +} + +DistortionComputePinUnpacked UnpackPin ( DistortionComputePin src ) +{ + DistortionComputePinUnpacked result; + result.TanEyeAnglesR = src.TanEyeAnglesR; + result.TanEyeAnglesG = src.TanEyeAnglesG; + result.TanEyeAnglesB = src.TanEyeAnglesB; + float4 tempColor = D3DX_R8G8B8A8_UNORM_to_FLOAT4 ( src.Color ); + result.Fade = tempColor.r * 2.0 - 1.0; + result.TimewarpLerp = tempColor.a; + return result; +} + + +float4x4 Padding1; +float4x4 Padding2; +float2 EyeToSourceUVScale; +float2 EyeToSourceUVOffset; +float3x3 EyeRotationStart; +float3x3 EyeRotationEnd; +float UseOverlay = 1; +float RightEye = 1; +float FbSizePixelsX; + + +RWTexture2D Framebuffer : register(u0); +SamplerState Linear : register(s0); +// Subtlety - fill->Set stops at the first NULL texture, so make sure you order them by priority! +Texture2D HmdSpcTexture : register(t0); +Texture2D OverlayTexture : register(t1); +// t1, t2, t3 for layers in future. +// This is set by other calls, so no problem putting it in t4. +StructuredBuffer UntransformedGridPins : register(t4); + +// Each eye has a grid of "pins" - spaced every gridSizeInPixels apart in a square grid. +// You can think of them as vertices in a mesh, but they are regularly +// distributed in screen space, not pre-distorted. +// Pins 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. +// pinsPerEdge is the pitch of the buffer, and is fixed whatver the resolution +// - it just needs to be large enough for the largest res we support. + +// The grid size remains fixed, but now each shader invocation does an NxN "tile" of output pixels. +// This allows it to read, timewarp & project the input pins just once, then interpolate final UV over a number of pixels. +// The "SIMD square size" is how large the square of dispatched pixels is - it's the +// thing set in numthreads(N,N,1). For a SIMD size of 64-wide, it needs to be more than 8, +// otherwise we'll starve the machine. + +// Summary: +// Each SIMD lane does a tileBlockSizePixels^2 of pixels. +// Each "CS group" (i.e. a virtualized SIMD thread) will cover a (simdSquareSize*tileBlockSizePixels)^2 block of pixels. +// The pin grid is unaffected by any of these (except it has to be larger than tileBlockSizePixels). +static const int gridSizeInPixels = GRID_SIZE_IN_PIXELS; +static const int pinsPerEdge = PINS_PER_EDGE; +static const int tileBlockSizePixels = NXN_BLOCK_SIZE_PIXELS; +static const int simdSquareSize = SIMD_SQUARE_SIZE; +static const int tilesPerGridSide = gridSizeInPixels / tileBlockSizePixels; + +DistortionComputePinTimewarped WarpAndDistort ( DistortionComputePinUnpacked inp ) +{ + // Pin inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). +#if ENABLE_TIMEWARP + // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. + float3 TanEyeAngle3R = float3 ( inp.TanEyeAnglesR.x, inp.TanEyeAnglesR.y, 1.0 ); + float3 TanEyeAngle3G = float3 ( inp.TanEyeAnglesG.x, inp.TanEyeAnglesG.y, 1.0 ); + float3 TanEyeAngle3B = float3 ( inp.TanEyeAnglesB.x, inp.TanEyeAnglesB.y, 1.0 ); + + // Apply the two 3x3 timewarp rotations to these vectors. + float3 TransformedRStart = mul ( EyeRotationStart, TanEyeAngle3R ); + float3 TransformedGStart = mul ( EyeRotationStart, TanEyeAngle3G ); + float3 TransformedBStart = mul ( EyeRotationStart, TanEyeAngle3B ); + float3 TransformedREnd = mul ( EyeRotationEnd, TanEyeAngle3R ); + float3 TransformedGEnd = mul ( EyeRotationEnd, TanEyeAngle3G ); + float3 TransformedBEnd = mul ( EyeRotationEnd, TanEyeAngle3B ); + // And blend between them. + float3 TransformedR = lerp ( TransformedRStart, TransformedREnd, inp.TimewarpLerp ); + float3 TransformedG = lerp ( TransformedGStart, TransformedGEnd, inp.TimewarpLerp ); + float3 TransformedB = lerp ( TransformedBStart, TransformedBEnd, inp.TimewarpLerp ); + + // Project them back onto the Z=1 plane of the rendered images. + float RecipZR = rcp ( TransformedR.z ); + float RecipZG = rcp ( TransformedG.z ); + float RecipZB = rcp ( TransformedB.z ); + float2 FlattenedR = float2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR ); + float2 FlattenedG = float2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG ); + float2 FlattenedB = float2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB ); +#else + float2 FlattenedR = inp.TanEyeAnglesR; + float2 FlattenedG = inp.TanEyeAnglesG; + float2 FlattenedB = inp.TanEyeAnglesB; +#endif + + DistortionComputePinTimewarped result; + + // These are now still in TanEyeAngle space. + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + result.HmdSpcTexCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset; + result.HmdSpcTexCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset; + result.HmdSpcTexCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset; + +#if ENABLE_OVERLAY + // Static layer texcoords don't get any time warp offset + result.OverlayTexCoordR = inp.TanEyeAnglesR * EyeToSourceUVScale + EyeToSourceUVOffset; + result.OverlayTexCoordG = inp.TanEyeAnglesG * EyeToSourceUVScale + EyeToSourceUVOffset; + result.OverlayTexCoordB = inp.TanEyeAnglesB * EyeToSourceUVScale + EyeToSourceUVOffset; +#endif + return result; +} + +float3 FindPixelColour ( float2 pinFrac, + DistortionComputePinUnpacked PinTL, + DistortionComputePinUnpacked PinTR, + DistortionComputePinUnpacked PinBL, + DistortionComputePinUnpacked PinBR, + DistortionComputePinTimewarped PinWarpTL, + DistortionComputePinTimewarped PinWarpTR, + DistortionComputePinTimewarped PinWarpBL, + DistortionComputePinTimewarped PinWarpBR) +{ + float pinWeightTL = (1.0-pinFrac.x) * (1.0-pinFrac.y); + float pinWeightTR = ( pinFrac.x) * (1.0-pinFrac.y); + float pinWeightBL = (1.0-pinFrac.x) * ( pinFrac.y); + float pinWeightBR = ( pinFrac.x) * ( pinFrac.y); + + float Fade = ( PinTL.Fade * pinWeightTL ) + + ( PinTR.Fade * pinWeightTR ) + + ( PinBL.Fade * pinWeightBL ) + + ( PinBR.Fade * pinWeightBR ); + float2 HmdSpcTexCoordR = ( PinWarpTL.HmdSpcTexCoordR * pinWeightTL ) + + ( PinWarpTR.HmdSpcTexCoordR * pinWeightTR ) + + ( PinWarpBL.HmdSpcTexCoordR * pinWeightBL ) + + ( PinWarpBR.HmdSpcTexCoordR * pinWeightBR ); + float2 HmdSpcTexCoordG = ( PinWarpTL.HmdSpcTexCoordG * pinWeightTL ) + + ( PinWarpTR.HmdSpcTexCoordG * pinWeightTR ) + + ( PinWarpBL.HmdSpcTexCoordG * pinWeightBL ) + + ( PinWarpBR.HmdSpcTexCoordG * pinWeightBR ); + float2 HmdSpcTexCoordB = ( PinWarpTL.HmdSpcTexCoordB * pinWeightTL ) + + ( PinWarpTR.HmdSpcTexCoordB * pinWeightTR ) + + ( PinWarpBL.HmdSpcTexCoordB * pinWeightBL ) + + ( PinWarpBR.HmdSpcTexCoordB * pinWeightBR ); + + float3 finalColor; + +#if PENTILE_MODE > 0 + // R & B channels have a 0.5 bias because of fewer pels. + const float mipBiasRB = 0.5; +#else + const float mipBiasRB = 0.0; +#endif + finalColor.r = HmdSpcTexture.SampleLevel(Linear, HmdSpcTexCoordR, mipBiasRB).r; + finalColor.g = HmdSpcTexture.SampleLevel(Linear, HmdSpcTexCoordG, 0 ).g; + finalColor.b = HmdSpcTexture.SampleLevel(Linear, HmdSpcTexCoordB, mipBiasRB).b; +#if ENABLE_OVERLAY + if(UseOverlay > 0) + { + float2 OverlayTexCoordR = ( PinWarpTL.OverlayTexCoordR * pinWeightTL ) + + ( PinWarpTR.OverlayTexCoordR * pinWeightTR ) + + ( PinWarpBL.OverlayTexCoordR * pinWeightBL ) + + ( PinWarpBR.OverlayTexCoordR * pinWeightBR ); + float2 OverlayTexCoordG = ( PinWarpTL.OverlayTexCoordG * pinWeightTL ) + + ( PinWarpTR.OverlayTexCoordG * pinWeightTR ) + + ( PinWarpBL.OverlayTexCoordG * pinWeightBL ) + + ( PinWarpBR.OverlayTexCoordG * pinWeightBR ); + float2 OverlayTexCoordB = ( PinWarpTL.OverlayTexCoordB * pinWeightTL ) + + ( PinWarpTR.OverlayTexCoordB * pinWeightTR ) + + ( PinWarpBL.OverlayTexCoordB * pinWeightBL ) + + ( PinWarpBR.OverlayTexCoordB * pinWeightBR ); + float2 overlayColorR = OverlayTexture.SampleLevel(Linear, OverlayTexCoordR, mipBiasRB).ra; + float2 overlayColorG = OverlayTexture.SampleLevel(Linear, OverlayTexCoordG, 0 ).ga; + float2 overlayColorB = OverlayTexture.SampleLevel(Linear, OverlayTexCoordB, mipBiasRB).ba; + // do premultiplied alpha blending - overlayColorX.x is color, overlayColorX.y is alpha + finalColor.r = finalColor.r * saturate(1-overlayColorR.y) + overlayColorR.x; + finalColor.g = finalColor.g * saturate(1-overlayColorG.y) + overlayColorG.x; + finalColor.b = finalColor.b * saturate(1-overlayColorB.y) + overlayColorB.x; + } +#endif + finalColor.rgb = saturate(finalColor.rgb * Fade); + return finalColor; +} + + +[numthreads(simdSquareSize, simdSquareSize, 1)] +void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID) +// Reminder: +// GroupThreadID.xy will range from 0 to (simdSquareSize-1). +// GroupID.xy will range from 0 to (screen_size.xy)/(simdSquareSize*tileBlockSizePixels) +// DispatchThreadID.xy = GroupID.xy * simdSquareSize + GroupThreadID.xy +{ + int2 PixelPosTile = DTid.xy * tileBlockSizePixels; + float2 PixelPosFloat = (float2)PixelPosTile; + float2 pinFracTileStart = (float2)PixelPosTile * ( 1.0 / gridSizeInPixels ); + float2 pinWholeTileStart = floor ( pinFracTileStart ); + pinFracTileStart -= pinWholeTileStart; + int2 pinInt = (int2)pinWholeTileStart; + pinInt.x = (0.5*FbSizePixelsX/gridSizeInPixels - 1) - pinInt.x; + pinFracTileStart.x = 1.0 - pinFracTileStart.x; + if ( RightEye > 0.5 ) + { + PixelPosTile.x += 0.5*FbSizePixelsX; + } + + int pinIndexTL = pinInt.x*pinsPerEdge + pinInt.y; + int pinIndexTR = pinIndexTL + pinsPerEdge; + int pinIndexBL = pinIndexTL + 1; + int pinIndexBR = pinIndexTR + 1; + DistortionComputePinUnpacked PinTL = UnpackPin ( UntransformedGridPins[pinIndexTL] ); + DistortionComputePinUnpacked PinTR = UnpackPin ( UntransformedGridPins[pinIndexTR] ); + DistortionComputePinUnpacked PinBL = UnpackPin ( UntransformedGridPins[pinIndexBL] ); + DistortionComputePinUnpacked PinBR = UnpackPin ( UntransformedGridPins[pinIndexBR] ); + if ( ( PinTL.Fade > 0.0 ) || + ( PinTR.Fade > 0.0 ) || + ( PinBL.Fade > 0.0 ) || + ( PinBR.Fade > 0.0 ) ) + { + DistortionComputePinTimewarped PinWarpTL = WarpAndDistort ( PinTL ); + DistortionComputePinTimewarped PinWarpTR = WarpAndDistort ( PinTR ); + DistortionComputePinTimewarped PinWarpBL = WarpAndDistort ( PinBL ); + DistortionComputePinTimewarped PinWarpBR = WarpAndDistort ( PinBR ); + + float2 pinFrac; + int2 PixelPos; + pinFrac.x = pinFracTileStart.x; + pinFrac.y = pinFracTileStart.y; + float3 finalColor00 = FindPixelColour ( pinFrac, + PinTL, + PinTR, + PinBL, + PinBR, + PinWarpTL, + PinWarpTR, + PinWarpBL, + PinWarpBR); + pinFrac.x = pinFracTileStart.x - (1.0 / gridSizeInPixels); + pinFrac.y = pinFracTileStart.y; + float3 finalColor01 = FindPixelColour ( pinFrac, + PinTL, + PinTR, + PinBL, + PinBR, + PinWarpTL, + PinWarpTR, + PinWarpBL, + PinWarpBR); + pinFrac.x = pinFracTileStart.x; + pinFrac.y = pinFracTileStart.y + (1.0 / gridSizeInPixels); + float3 finalColor10 = FindPixelColour ( pinFrac, + PinTL, + PinTR, + PinBL, + PinBR, + PinWarpTL, + PinWarpTR, + PinWarpBL, + PinWarpBR); + pinFrac.x = pinFracTileStart.x - (1.0 / gridSizeInPixels); + pinFrac.y = pinFracTileStart.y + (1.0 / gridSizeInPixels); + float3 finalColor11 = FindPixelColour ( pinFrac, + PinTL, + PinTR, + PinBL, + PinBR, + PinWarpTL, + PinWarpTR, + PinWarpBL, + PinWarpBR); + + float3 finalOut00; + float3 finalOut01; + float3 finalOut10; + float3 finalOut11; +#if PENTILE_MODE==0 + // No pentile, so it's easy. + finalOut00 = finalColor00; + finalOut01 = finalColor01; + finalOut10 = finalColor10; + finalOut11 = finalColor11; +#elif PENTILE_MODE==1 + // Now the DK2 pentile swizzle. Don't try to understand it; just rope, throw and brand it. + finalOut00.g = finalColor10.g; + finalOut01.g = finalColor01.g; + finalOut10.g = finalColor00.g; + finalOut11.g = finalColor11.g; + finalOut00.r = finalColor10.r; + finalOut01.r = finalColor01.r; + finalOut10.r = finalColor00.b; + finalOut11.r = finalColor11.b; + finalOut00.b = 0.0; + finalOut01.b = 0.0; + finalOut10.b = 0.0; + finalOut11.b = 0.0; +#endif + + PixelPos.x = PixelPosTile.x; + PixelPos.y = PixelPosTile.y; + Framebuffer[PixelPos.xy] = float4 ( finalOut00, 0.0 ); + PixelPos.x = PixelPosTile.x + 1; + PixelPos.y = PixelPosTile.y; + Framebuffer[PixelPos.xy] = float4 ( finalOut01, 0.0 ); + PixelPos.x = PixelPosTile.x; + PixelPos.y = PixelPosTile.y + 1; + Framebuffer[PixelPos.xy] = float4 ( finalOut10, 0.0 ); + PixelPos.x = PixelPosTile.x + 1; + PixelPos.y = PixelPosTile.y + 1; + Framebuffer[PixelPos.xy] = float4 ( finalOut11, 0.0 ); + } +}; + + + diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h new file mode 100644 index 0000000..78cbb03 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h @@ -0,0 +1,887 @@ +#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 new file mode 100644 index 0000000..27db6d3 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2_refl.h @@ -0,0 +1,16 @@ +#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 new file mode 100644 index 0000000..5bc4599 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.h @@ -0,0 +1,256 @@ +#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 new file mode 100644 index 0000000..c69fce0 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.psh @@ -0,0 +1,135 @@ +/************************************************************************************ + +Filename : DistortionChroma_ps.psh + +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. + +************************************************************************************/ + +Texture2D Texture : register(t0); +Texture2D LastTexture : register(t1); +SamplerState Linear : register(s0); + +float2 OverdriveScales; +float AaDerivativeMult; + +// Fast approximate gamma to linear conversion when averaging colors +float3 ToLinear(float3 inColor) { return inColor * inColor; } +float3 ToGamma(float3 inColor) { return sqrt(inColor); } + +void SampleStep(float2 oTexCoord0, float2 oTexCoord1, float2 oTexCoord2, float colorWeight, float2 texOffset, + inout float3 totalColor, inout float totalWeight) +{ + float3 newColor = 0; + newColor.r += Texture.Sample(Linear, oTexCoord0 + texOffset).r; + newColor.g += Texture.Sample(Linear, oTexCoord1 + texOffset).g; + newColor.b += Texture.Sample(Linear, oTexCoord2 + texOffset).b; + newColor = ToLinear(newColor); + + totalColor += newColor * colorWeight; + totalWeight += colorWeight; +} + +float3 ApplyHqAa(float2 oTexCoord0, float2 oTexCoord1, float2 oTexCoord2) +{ + float2 texWidth = fwidth(oTexCoord1); + float2 texStep = texWidth * AaDerivativeMult; + + float totalWeight = 0; + float3 totalColor = 0; + + // center sample + SampleStep(oTexCoord0, oTexCoord1, oTexCoord2, 4, 0, totalColor, totalWeight); + + float3 smplExp = 1.0 / 3.0; + float3 smplWgt = 1.0; + + SampleStep(oTexCoord0, oTexCoord1, oTexCoord2, smplWgt.x, -1.000 * smplExp.x * texStep, totalColor, totalWeight); + //SampleStep(oTexCoord0, oTexCoord1, oTexCoord2, smplWgt.y, -1.250 * smplExp.y * texStep, totalColor, totalWeight); + SampleStep(oTexCoord0, oTexCoord1, oTexCoord2, smplWgt.z, -1.875 * smplExp.z * texStep, totalColor, totalWeight); + SampleStep(oTexCoord0, oTexCoord1, oTexCoord2, smplWgt.z, 1.875 * smplExp.z * texStep, totalColor, totalWeight); + //SampleStep(oTexCoord0, oTexCoord1, oTexCoord2, smplWgt.y, 1.250 * smplExp.y * texStep, totalColor, totalWeight); + SampleStep(oTexCoord0, oTexCoord1, oTexCoord2, smplWgt.x, 1.000 * smplExp.x * texStep, totalColor, totalWeight); + + return ToGamma(totalColor.rgb / totalWeight); +} + +void main(in float4 oPosition : SV_Position, + in float oColor : COLOR, + in float2 oTexCoord0 : TEXCOORD0, + in float2 oTexCoord1 : TEXCOORD1, + in float2 oTexCoord2 : TEXCOORD2, + out float4 outColor0 : SV_Target0, + out float4 outColor1 : SV_Target1) +{ +#define USE_ANISO 0 + +#if USE_ANISO // enable "SampleMode hqFilter = (distortionCaps ... " in code + // Using anisotropic sampling - requires sRGB sampling + + #if 1 // feeding in proper ddx & ddy does not yield better visuals + float2 uvDeriv = float2(ddx(oTexCoord1.x), ddy(oTexCoord1.y)); + float ResultR = Texture.SampleGrad(Linear, oTexCoord0, uvDeriv.x, uvDeriv.y).r; + float ResultG = Texture.SampleGrad(Linear, oTexCoord1, uvDeriv.x, uvDeriv.y).g; + float ResultB = Texture.SampleGrad(Linear, oTexCoord2, uvDeriv.x, uvDeriv.y).b; + float3 newColor = float3(ResultR, ResultG, ResultB); + #else + float2 uvDerivX = ddx(oTexCoord1); + float2 uvDerivY = ddy(oTexCoord1); + float ResultR = Texture.SampleGrad(Linear, oTexCoord0, uvDerivX, uvDerivY).r; + float ResultG = Texture.SampleGrad(Linear, oTexCoord1, uvDerivX, uvDerivY).g; + float ResultB = Texture.SampleGrad(Linear, oTexCoord2, uvDerivX, uvDerivY).b; + float3 newColor = float3(ResultR, ResultG, ResultB); + #endif + +#else + + float3 newColor; + // High quality anti-aliasing in distortion + if(AaDerivativeMult > 0) + { + newColor = ApplyHqAa(oTexCoord0, oTexCoord1, oTexCoord2); + } + else + { + float ResultR = Texture.Sample(Linear, oTexCoord0).r; + float ResultG = Texture.Sample(Linear, oTexCoord1).g; + float ResultB = Texture.Sample(Linear, oTexCoord2).b; + newColor = float3(ResultR, ResultG, ResultB); + } + +#endif + + newColor = newColor * oColor.xxx; + outColor0 = float4(newColor, 1.0); + outColor1 = outColor0; + + // pixel luminance overdrive + if(OverdriveScales.x > 0) + { + 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); + 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 new file mode 100644 index 0000000..fff0da3 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps_refl.h @@ -0,0 +1,9 @@ +#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 new file mode 100644 index 0000000..5ffc945 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.h @@ -0,0 +1,101 @@ +#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.vsh b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.vsh new file mode 100644 index 0000000..bc35262 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.vsh @@ -0,0 +1,53 @@ +/************************************************************************************ + +Filename : DistortionChroma_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, + 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; + + // Scale them into UV lookup space + float2 tc0scaled = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; + float2 tc1scaled = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; + float2 tc2scaled = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; + + oTexCoord0 = tc0scaled; // R sample. + oTexCoord1 = tc1scaled; // G sample. + oTexCoord2 = tc2scaled; // B sample. + oColor = Color.r; // Used for vignette fade. +} + diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h new file mode 100644 index 0000000..7feb789 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h @@ -0,0 +1,9 @@ +#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 new file mode 100644 index 0000000..418b740 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.h @@ -0,0 +1,214 @@ +#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 new file mode 100644 index 0000000..7e5512b --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.vsh @@ -0,0 +1,66 @@ +/************************************************************************************ + +Filename : DistortionTimewarpChroma_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.xy, 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, + 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); + oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, lerpedEyeRot); + oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, lerpedEyeRot); + + 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 new file mode 100644 index 0000000..38a168f --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs_refl.h @@ -0,0 +1,11 @@ +#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 new file mode 100644 index 0000000..26fc0e2 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.h @@ -0,0 +1,167 @@ +#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 new file mode 100644 index 0000000..d594042 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.vsh @@ -0,0 +1,63 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..eab6baf --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs_refl.h @@ -0,0 +1,11 @@ +#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 new file mode 100644 index 0000000..8d7867a --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.h @@ -0,0 +1,65 @@ +#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.psh b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.psh new file mode 100644 index 0000000..e83c6d1 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.psh @@ -0,0 +1,34 @@ +/************************************************************************************ + +Filename : Distortion_ps.psh + +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. + +************************************************************************************/ + + +Texture2D Texture : register(t0); +SamplerState Linear : register(s0); + +float4 main(in float4 oPosition : SV_Position, + in float1 oColor : COLOR, + in float2 oTexCoord0 : TEXCOORD0) : SV_Target +{ + float3 Result = Texture.Sample(Linear, oTexCoord0).rgb; + return float4(Result * oColor, 1.0 ); +} diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h new file mode 100644 index 0000000..8a613f5 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h @@ -0,0 +1 @@ +// 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 new file mode 100644 index 0000000..52b9413 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.h @@ -0,0 +1,82 @@ +#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 new file mode 100644 index 0000000..d947772 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.vsh @@ -0,0 +1,41 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..b3e86ac --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs_refl.h @@ -0,0 +1,9 @@ +#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 new file mode 100644 index 0000000..00f928d --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.h @@ -0,0 +1,51 @@ +#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.psh b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.psh new file mode 100644 index 0000000..c03d293 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.psh @@ -0,0 +1,29 @@ +/************************************************************************************ + +Filename : SimpleQuad_ps.psh + +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. + +************************************************************************************/ + +float4 Color; + +float4 main() : SV_Target +{ + return Color; +} diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h new file mode 100644 index 0000000..7980b65 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h @@ -0,0 +1,8 @@ +#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 new file mode 100644 index 0000000..e68903f --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.h @@ -0,0 +1,64 @@ +#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.vsh b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.vsh new file mode 100644 index 0000000..94d6694 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.vsh @@ -0,0 +1,31 @@ +/************************************************************************************ + +Filename : SimplaeQuad_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 PositionOffset = float2(0, 0); +float2 Scale = float2(1, 1); + +void main( in float3 Position : POSITION, +out float4 oPosition : SV_Position) +{ + oPosition = float4(Position.xy * Scale + PositionOffset, 0.5, 1.0); +} \ No newline at end of file diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h new file mode 100644 index 0000000..23bb021 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h @@ -0,0 +1,9 @@ +#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 new file mode 100644 index 0000000..39fda03 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.h @@ -0,0 +1,77 @@ +#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.psh b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.psh new file mode 100644 index 0000000..d29c9af --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.psh @@ -0,0 +1,39 @@ +/************************************************************************************ + +Filename : SimpleTextureQuad_ps.psh + +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. + +************************************************************************************/ + +float4 Color; + +SamplerState LinearSampler : register(s0); +Texture2D Texture : register(t0); + +struct Values +{ + float4 Position : SV_Position; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +float4 main(in Values inputValues) : SV_Target +{ + return Color * inputValues.Color * Texture.Sample(LinearSampler, inputValues.TexCoord); +} diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h new file mode 100644 index 0000000..578cc45 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h @@ -0,0 +1,8 @@ +#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 new file mode 100644 index 0000000..8e18f8e --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.h @@ -0,0 +1,82 @@ +#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.vsh b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.vsh new file mode 100644 index 0000000..33a5fe5 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.vsh @@ -0,0 +1,39 @@ +/************************************************************************************ + +Filename : SimpleTextureQuad_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. + +************************************************************************************/ + +struct Values +{ + float4 Position : SV_Position; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +float2 PositionOffset = float2(0, 0); +float2 Scale = float2(1, 1); + +void main(in float3 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0, out Values outputValues) +{ + outputValues.Position = float4(Position.xy * Scale + PositionOffset, 0.5, 1.0); + outputValues.Color = Color; + outputValues.TexCoord = TexCoord; +} diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h new file mode 100644 index 0000000..5adb8a0 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h @@ -0,0 +1,9 @@ +#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/bin2header.exe b/LibOVR/Src/CAPI/D3D1X/Shaders/bin2header.exe new file mode 100644 index 0000000..b3f8d10 Binary files /dev/null and b/LibOVR/Src/CAPI/D3D1X/Shaders/bin2header.exe differ diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/genComputeShaderHeader.bat b/LibOVR/Src/CAPI/D3D1X/Shaders/genComputeShaderHeader.bat new file mode 100644 index 0000000..784bc86 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/genComputeShaderHeader.bat @@ -0,0 +1,15 @@ +@echo off +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" + +del "%1" +endlocal +popd diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/genPixelShaderHeader.bat b/LibOVR/Src/CAPI/D3D1X/Shaders/genPixelShaderHeader.bat new file mode 100644 index 0000000..76f17c2 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/genPixelShaderHeader.bat @@ -0,0 +1,15 @@ +@echo off +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 +bin2header.exe "%1" + +echo Generating shader reflection data for %1 +ShaderReflector "%1" "%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 new file mode 100644 index 0000000..7085775 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/genVertexShaderHeader.bat @@ -0,0 +1,15 @@ +@echo off +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 +bin2header.exe "%1" + +echo Generating shader reflection data for %1 +ShaderReflector "%1" "%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 new file mode 100644 index 0000000..05508ea --- /dev/null +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp @@ -0,0 +1,409 @@ +/************************************************************************************ + +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 + + diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h new file mode 100644 index 0000000..55c7d29 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h @@ -0,0 +1,142 @@ +/************************************************************************************ + +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 diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp new file mode 100644 index 0000000..2be55c1 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp @@ -0,0 +1,430 @@ +/************************************************************************************ + +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 + + + + + + + diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h new file mode 100644 index 0000000..b1d7191 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h @@ -0,0 +1,82 @@ +/************************************************************************************ + +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 + diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp new file mode 100644 index 0000000..0c6cd45 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp @@ -0,0 +1,273 @@ +/************************************************************************************ + +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(); +} + +}}} diff --git a/LibOVR/Src/CAPI/GL/CAPI_GLE.cpp b/LibOVR/Src/CAPI/GL/CAPI_GLE.cpp new file mode 100644 index 0000000..c41d745 --- /dev/null +++ b/LibOVR/Src/CAPI/GL/CAPI_GLE.cpp @@ -0,0 +1,7884 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..d2e8080 --- /dev/null +++ b/LibOVR/Src/CAPI/GL/CAPI_GLE.h @@ -0,0 +1,2003 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..2c3256d --- /dev/null +++ b/LibOVR/Src/CAPI/GL/CAPI_GLE_GL.h @@ -0,0 +1,4761 @@ +/************************************************************************************ + +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 21b6509..5ddbed2 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp @@ -5,12 +5,23 @@ Content : Distortion renderer header for GL Created : November 11, 2013 Authors : David Borel, Lee Cooper -Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. +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 +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_GL_DistortionRenderer.h" @@ -18,9 +29,18 @@ otherwise accompanies this software in either electronic or hard copy form. #include "CAPI_GL_DistortionShaders.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) + #include + #include +#endif namespace OVR { namespace CAPI { namespace GL { + // Distortion pixel shader lookup. // Bit 0: Chroma Correction // Bit 1: Timewarp @@ -69,10 +89,10 @@ void DistortionShaderBitIndexCheck() struct DistortionVertex { - Vector2f Pos; - Vector2f TexR; - Vector2f TexG; - Vector2f TexB; + Vector2f ScreenPosNDC; + Vector2f TanEyeAnglesR; + Vector2f TanEyeAnglesG; + Vector2f TanEyeAnglesB; Color Col; }; @@ -92,10 +112,15 @@ struct LatencyVertex DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState) : CAPI::DistortionRenderer(ovrRenderAPI_OpenGL, hmd, timeManager, renderState) + , RotateCCW90(false) , LatencyVAO(0) + , OverdriveFbo(0) { DistortionMeshVAOs[0] = 0; DistortionMeshVAOs[1] = 0; + + // Initialize render params. + memset(&RParams, 0, sizeof(RParams)); } DistortionRenderer::~DistortionRenderer() @@ -108,18 +133,14 @@ CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState) { -#if !defined(OVR_OS_MAC) InitGLExtensions(); -#endif + return new DistortionRenderer(hmd, timeManager, renderState); } -bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned distortionCaps) +bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) { - GfxState = *new GraphicsState(); - const ovrGLConfig* config = (const ovrGLConfig*)apiConfig; if (!config) @@ -132,42 +153,125 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, } RParams.Multisample = config->OGL.Header.Multisample; - RParams.RTSize = config->OGL.Header.RTSize; + RParams.BackBufferSize = config->OGL.Header.BackBufferSize; #if defined(OVR_OS_WIN32) RParams.Window = (config->OGL.Window) ? config->OGL.Window : GetActiveWindow(); + RParams.DC = config->OGL.DC; #elif defined(OVR_OS_LINUX) - RParams.Disp = (config->OGL.Disp) ? config->OGL.Disp : XOpenDisplay(NULL); - RParams.Win = config->OGL.Win; - if (!RParams.Win) + RotateCCW90 = false; + if ( RState.DistortionCaps & ovrDistortionCap_LinuxDevFullscreen + && SDKWindow::getRotation(HMD) == DistRotateCCW90) { - int unused; - XGetInputFocus(RParams.Disp, &RParams.Win, &unused); + RotateCCW90 = true; + } + if (config->OGL.Disp) + { + RParams.Disp = config->OGL.Disp; + } + if (!RParams.Disp) + { + RParams.Disp = glXGetCurrentDisplay(); + } + if (!RParams.Disp) + { + OVR_DEBUG_LOG(("glXGetCurrentDisplay failed.")); + return false; } #endif - DistortionCaps = distortionCaps; - - //DistortionWarper.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true); + DistortionMeshVAOs[0] = 0; + DistortionMeshVAOs[1] = 0; + + LatencyVAO = 0; + + GL::AutoContext autoGLContext(distortionContext); // Initializes distortionContext if not already, saves the current GL context, binds distortionContext, then at the end of scope re-binds the current GL context. pEyeTextures[0] = *new Texture(&RParams, 0, 0); pEyeTextures[1] = *new Texture(&RParams, 0, 0); initBuffersAndShaders(); + initOverdrive(); + return true; } -void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) +void DistortionRenderer::initOverdrive() { - // Doesn't do a lot in here?? - const ovrGLTexture* tex = (const ovrGLTexture*)eyeTexture; + if(RState.DistortionCaps & ovrDistortionCap_Overdrive) + { + LastUsedOverdriveTextureIndex = 0; + + glGenFramebuffers(1, &OverdriveFbo); + + GLint internalFormat = (RState.DistortionCaps & ovrDistortionCap_SRGB) ? GL_SRGB_ALPHA : GL_RGBA; + + for (int i = 0; i < NumOverdriveTextures ; i++) + { + pOverdriveTextures[i] = *new Texture(&RParams, RParams.BackBufferSize.w, RParams.BackBufferSize.h); + + glBindTexture(GL_TEXTURE_2D, pOverdriveTextures[i]->TexId); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, RParams.BackBufferSize.w, RParams.BackBufferSize.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + OVR_ASSERT( glGetError() == GL_NO_ERROR ); + + pOverdriveTextures[i]->SetSampleMode(Sample_ClampBorder | Sample_Linear); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + OVR_ASSERT(glGetError() == 0); + + // clear the new buffer + glBindFramebuffer(GL_FRAMEBUFFER, OverdriveFbo ); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pOverdriveTextures[i]->TexId, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + OVR_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0}; + glDrawBuffers(OVR_ARRAY_COUNT(drawBuffers), drawBuffers); + glClearColor(0,0,0,1); + glClear(GL_COLOR_BUFFER_BIT); + } - // Write in values - eachEye[eyeId].texture = tex->OGL.TexId; + { + OverdriveBackBufferTexture = *new Texture(&RParams, RParams.BackBufferSize.w, RParams.BackBufferSize.h); + + glBindTexture(GL_TEXTURE_2D, OverdriveBackBufferTexture->TexId); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, RParams.BackBufferSize.w, RParams.BackBufferSize.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + OVR_ASSERT(glGetError() == 0); + + OverdriveBackBufferTexture->SetSampleMode(Sample_ClampBorder | Sample_Linear); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + OVR_ASSERT(glGetError() == 0); + + // clear the new buffer + glBindFramebuffer(GL_FRAMEBUFFER, OverdriveFbo ); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OverdriveBackBufferTexture->TexId, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + OVR_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0}; + glDrawBuffers(OVR_ARRAY_COUNT(drawBuffers), drawBuffers); + glClearColor(0,0,0,1); + glClear(GL_COLOR_BUFFER_BIT); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + else + { + LastUsedOverdriveTextureIndex = -1; + } +} + +void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) +{ + // Doesn't do a lot in here?? + const ovrGLTexture* tex = (const ovrGLTexture*)eyeTexture; if (tex) { + // Write in values + eachEye[eyeId].texture = tex->OGL.TexId; + // 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->OGL.Header.TextureSize; @@ -179,216 +283,176 @@ void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) 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; + } + pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->OGL.TexId, tex->OGL.Header.TextureSize); } } -void DistortionRenderer::EndFrame(bool swapBuffers, - unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) +void DistortionRenderer::renderEndFrame() { - if (!TimeManager.NeedDistortionTimeMeasurement()) - { - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) - { - // Wait for timewarp distortion if it is time and Gpu idle - FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); - } + renderDistortion(pEyeTextures[0], pEyeTextures[1]); - renderDistortion(pEyeTextures[0], pEyeTextures[1]); + // TODO: Add rendering context to callback. + if(RegisteredPostDistortionCallback) + RegisteredPostDistortionCallback(NULL); + + if(LatencyTest2Active) + { + renderLatencyPixel(LatencyTest2DrawColor); } - else +} + +void DistortionRenderer::EndFrame(bool swapBuffers) +{ + Context currContext; + currContext.InitFromCurrent(); +#if defined(OVR_OS_MAC) + distortionContext.SetSurface( currContext ); +#endif + + // Don't spin if we are explicitly asked not to + if ((RState.DistortionCaps & ovrDistortionCap_TimeWarp) && + !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) { - // If needed, measure distortion time so that TimeManager can better estimate - // latency-reducing time-warp wait timing. - WaitUntilGpuIdle(); - double distortionStartTime = ovr_GetTimeInSeconds(); + if (!TimeManager.NeedDistortionTimeMeasurement()) + { + // Wait for timewarp distortion if it is time and Gpu idle + FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); - renderDistortion(pEyeTextures[0], pEyeTextures[1]); + distortionContext.Bind(); + renderEndFrame(); + } + else + { + // If needed, measure distortion time so that TimeManager can better estimate + // latency-reducing time-warp wait timing. + WaitUntilGpuIdle(); + double distortionStartTime = ovr_GetTimeInSeconds(); - WaitUntilGpuIdle(); - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); - } + distortionContext.Bind(); + renderEndFrame(); - if(latencyTesterDrawColor) + WaitUntilGpuIdle(); + TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + } + } + else { - renderLatencyQuad(latencyTesterDrawColor); + distortionContext.Bind(); + renderEndFrame(); } - else if(latencyTester2DrawColor) + + if(LatencyTestActive) { - renderLatencyPixel(latencyTester2DrawColor); + renderLatencyQuad(LatencyTestDrawColor); } if (swapBuffers) { bool useVsync = ((RState.EnabledHmdCaps & ovrHmdCap_NoVSync) == 0); - int swapInterval = (useVsync) ? 1 : 0; + int ourSwapInterval = (useVsync) ? 1 : 0; + int originalSwapInterval; + #if defined(OVR_OS_WIN32) - if (wglGetSwapIntervalEXT() != swapInterval) - wglSwapIntervalEXT(swapInterval); + originalSwapInterval = wglGetSwapIntervalEXT(); + + if (ourSwapInterval != originalSwapInterval) + wglSwapIntervalEXT(ourSwapInterval); - HDC dc = GetDC(RParams.Window); + HDC dc = (RParams.DC != NULL) ? RParams.DC : GetDC(RParams.Window); BOOL success = SwapBuffers(dc); - ReleaseDC(RParams.Window, dc); - OVR_ASSERT(success); - OVR_UNUSED(success); + OVR_ASSERT_AND_UNUSED(success, success); + + if (RParams.DC == NULL) + ReleaseDC(RParams.Window, dc); + #elif defined(OVR_OS_MAC) + originalSwapInterval = 0; CGLContextObj context = CGLGetCurrentContext(); - GLint currentSwapInterval = 0; - CGLGetParameter(context, kCGLCPSwapInterval, ¤tSwapInterval); - if (currentSwapInterval != swapInterval) - CGLSetParameter(context, kCGLCPSwapInterval, &swapInterval); + CGLError err = CGLGetParameter(context, kCGLCPSwapInterval, &originalSwapInterval); + OVR_ASSERT_AND_UNUSED(err == kCGLNoError, err); + + if (ourSwapInterval != originalSwapInterval) + CGLSetParameter(context, kCGLCPSwapInterval, &ourSwapInterval); CGLFlushDrawable(context); + #elif defined(OVR_OS_LINUX) - static const char* extensions = glXQueryExtensionsString(RParams.Disp, 0); - static bool supportsVSync = (extensions != NULL && strstr(extensions, "GLX_EXT_swap_control")); - if (supportsVSync) - { - GLuint currentSwapInterval = 0; - glXQueryDrawable(RParams.Disp, RParams.Win, GLX_SWAP_INTERVAL_EXT, ¤tSwapInterval); - if (currentSwapInterval != swapInterval) - glXSwapIntervalEXT(RParams.Disp, RParams.Win, swapInterval); - } - - glXSwapBuffers(RParams.Disp, RParams.Win); -#endif - } -} - -void DistortionRenderer::WaitUntilGpuIdle() -{ - glFlush(); - glFinish(); -} + originalSwapInterval = 0; + GLXDrawable drawable = glXGetCurrentDrawable(); + struct _XDisplay* x11Display = RParams.Disp; -double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) -{ - double initialTime = ovr_GetTimeInSeconds(); - if (initialTime >= absTime) - return 0.0; - - glFlush(); - glFinish(); + if(GLE_GLX_EXT_swap_control) + { + static_assert(sizeof(GLuint) == sizeof(originalSwapInterval), "size mismatch"); + glXQueryDrawable(x11Display, drawable, GLX_SWAP_INTERVAL_EXT, (GLuint*)&originalSwapInterval); - double newTime = initialTime; - volatile int i; + if (ourSwapInterval != originalSwapInterval) + glXSwapIntervalEXT(x11Display, drawable, ourSwapInterval); + } + else if (GLE_MESA_swap_control) // There is also GLX_SGI_swap_control + { + originalSwapInterval = glXGetSwapIntervalMESA(); - while (newTime < absTime) - { - for (int j = 0; j < 50; j++) - i = 0; + if (ourSwapInterval != originalSwapInterval) + glXSwapIntervalMESA(ourSwapInterval); + } - newTime = ovr_GetTimeInSeconds(); - } + glXSwapBuffers(x11Display, drawable); +#endif - // How long we waited - return newTime - initialTime; -} - - -DistortionRenderer::GraphicsState::GraphicsState() -{ - const char* glVersionString = (const char*)glGetString(GL_VERSION); - OVR_DEBUG_LOG(("GL_VERSION STRING: %s", (const char*)glVersionString)); - char prefix[64]; - bool foundVersion = false; - - for (int i = 10; i < 30; ++i) - { - int major = i / 10; - int minor = i % 10; - OVR_sprintf(prefix, 64, "%d.%d", major, minor); - if (strstr(glVersionString, prefix) == glVersionString) + // Force GPU to flush the scene, resulting in the lowest possible latency. + // It's critical that this flush is *after* present, because it results in the wait + // 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)) + WaitUntilGpuIdle(); + + // Restore the original swap interval if we changed it above. + if (originalSwapInterval != ourSwapInterval) { - GlMajorVersion = major; - GlMinorVersion = minor; - foundVersion = true; - break; +#if defined(OVR_OS_WIN32) + wglSwapIntervalEXT(originalSwapInterval); +#elif defined(OVR_OS_MAC) + CGLSetParameter(context, kCGLCPSwapInterval, &originalSwapInterval); +#elif defined(OVR_OS_LINUX) + if(GLE_GLX_EXT_swap_control) + glXSwapIntervalEXT(x11Display, drawable, (GLuint)originalSwapInterval); + else if(GLE_MESA_swap_control) + glXSwapIntervalMESA(originalSwapInterval); +#endif } } - - if (!foundVersion) - { - glGetIntegerv(GL_MAJOR_VERSION, &GlMajorVersion); - glGetIntegerv(GL_MAJOR_VERSION, &GlMinorVersion); - } - OVR_ASSERT(GlMajorVersion >= 2); - - if (GlMajorVersion >= 3) - { - SupportsVao = true; - } - else - { - const char* extensions = (const char*)glGetString(GL_EXTENSIONS); - SupportsVao = (strstr("GL_ARB_vertex_array_object", extensions) != NULL); - } -} - - -void DistortionRenderer::GraphicsState::ApplyBool(GLenum Name, GLint Value) -{ - if (Value != 0) - glEnable(Name); - else - glDisable(Name); + currContext.Bind(); } - - -void DistortionRenderer::GraphicsState::Save() + +void DistortionRenderer::WaitUntilGpuIdle() { - glGetIntegerv(GL_VIEWPORT, Viewport); - glGetFloatv(GL_COLOR_CLEAR_VALUE, ClearColor); - glGetIntegerv(GL_DEPTH_TEST, &DepthTest); - glGetIntegerv(GL_CULL_FACE, &CullFace); - glGetIntegerv(GL_CURRENT_PROGRAM, &Program); - glGetIntegerv(GL_ACTIVE_TEXTURE, &ActiveTexture); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &TextureBinding); - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArray); - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FrameBufferBinding); - glGetIntegerv(GL_BLEND, &Blend); - glGetIntegerv(GL_COLOR_WRITEMASK, ColorWritemask); - glGetIntegerv(GL_DITHER, &Dither); - glGetIntegerv(GL_RASTERIZER_DISCARD, &RasterizerDiscard); - if (GlMajorVersion >= 3 && GlMajorVersion >= 2) - glGetIntegerv(GL_SAMPLE_MASK, &SampleMask); - glGetIntegerv(GL_SCISSOR_TEST, &ScissorTest); - - IsValid = true; + glFinish(); // Block until current OpenGL commands (including swap) are complete. } - -void DistortionRenderer::GraphicsState::Restore() +double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) { - // Don't allow restore-before-save. - if (!IsValid) - return; + // because glFlush() is not strict enough certain GL drivers + // we do a glFinish(), but before doing so, we make sure we're not + // running late + double initialTime = ovr_GetTimeInSeconds(); + if (initialTime >= absTime) + return 0.0; - glViewport(Viewport[0], Viewport[1], Viewport[2], Viewport[3]); - glClearColor(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]); - - ApplyBool(GL_DEPTH_TEST, DepthTest); - ApplyBool(GL_CULL_FACE, CullFace); - - glUseProgram(Program); - glActiveTexture(ActiveTexture); - glBindTexture(GL_TEXTURE_2D, TextureBinding); - if (SupportsVao) - glBindVertexArray(VertexArray); - glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferBinding); - - ApplyBool(GL_BLEND, Blend); - - glColorMask((GLboolean)ColorWritemask[0], (GLboolean)ColorWritemask[1], (GLboolean)ColorWritemask[2], (GLboolean)ColorWritemask[3]); - ApplyBool(GL_DITHER, Dither); - ApplyBool(GL_RASTERIZER_DISCARD, RasterizerDiscard); - if (GlMajorVersion >= 3 && GlMajorVersion >= 2) - ApplyBool(GL_SAMPLE_MASK, SampleMask); - ApplyBool(GL_SCISSOR_TEST, ScissorTest); -} + glFinish(); + return WaitTillTime(absTime); +} void DistortionRenderer::initBuffersAndShaders() { @@ -397,8 +461,6 @@ void DistortionRenderer::initBuffersAndShaders() // Allocate & generate distortion mesh vertices. ovrDistortionMesh meshData; -// double startT = ovr_GetTimeInSeconds(); - if (!ovrHmd_CreateDistortionMesh( HMD, RState.EyeRenderDesc[eyeNum].Eye, RState.EyeRenderDesc[eyeNum].Fov, @@ -416,16 +478,36 @@ void DistortionRenderer::initBuffersAndShaders() for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ ) { - pCurVBVert->Pos.x = pCurOvrVert->Pos.x; - pCurVBVert->Pos.y = pCurOvrVert->Pos.y; - pCurVBVert->TexR = (*(Vector2f*)&pCurOvrVert->TexR); - pCurVBVert->TexG = (*(Vector2f*)&pCurOvrVert->TexG); - pCurVBVert->TexB = (*(Vector2f*)&pCurOvrVert->TexB); + 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."); + memcpy(&pCurVBVert->TanEyeAnglesR, &pCurOvrVert->TanEyeAnglesR, sizeof(pCurVBVert->TanEyeAnglesR)); + memcpy(&pCurVBVert->TanEyeAnglesG, &pCurOvrVert->TanEyeAnglesG, sizeof(pCurVBVert->TanEyeAnglesG)); + memcpy(&pCurVBVert->TanEyeAnglesB, &pCurOvrVert->TanEyeAnglesB, sizeof(pCurVBVert->TanEyeAnglesB)); + // Convert [0.0f,1.0f] to [0,255] - pCurVBVert->Col.R = (OVR::UByte)( pCurOvrVert->VignetteFactor * 255.99f ); + if (RState.DistortionCaps & ovrDistortionCap_Vignette) + { + if(RState.DistortionCaps & ovrDistortionCap_SRGB) + pCurOvrVert->VignetteFactor = pow(pCurOvrVert->VignetteFactor, 2.1f); + + 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 = (OVR::UByte)( pCurOvrVert->TimeWarpFactor * 255.99f );; + pCurVBVert->Col.A = (uint8_t)( pCurOvrVert->TimeWarpFactor * 255.99f );; pCurOvrVert++; pCurVBVert++; } @@ -433,7 +515,7 @@ void DistortionRenderer::initBuffersAndShaders() 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(SInt16) * meshData.IndexCount ) ); + DistortionMeshIBs[eyeNum]->Data ( Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, ( sizeof(int16_t) * meshData.IndexCount ) ); OVR_FREE ( pVBVerts ); ovrHmd_DestroyDistortionMesh( &meshData ); @@ -444,21 +526,56 @@ void DistortionRenderer::initBuffersAndShaders() void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture) { - GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); + bool overdriveActive = IsOverdriveActive(); + int currOverdriveTextureIndex = -1; + + if(overdriveActive) + { + currOverdriveTextureIndex = (LastUsedOverdriveTextureIndex + 1) % NumOverdriveTextures; + + //glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, OverdriveFbo ); + + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; + glDrawBuffers(OVR_ARRAY_COUNT(drawBuffers), drawBuffers); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pOverdriveTextures[currOverdriveTextureIndex]->TexId, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OverdriveBackBufferTexture->TexId, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + OVR_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + } + else + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } - glBindFramebuffer(GL_FRAMEBUFFER, 0); - setViewport( Recti(0,0, RParams.RTSize.w, RParams.RTSize.h) ); + setViewport( Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h) ); + + if (RState.DistortionCaps & ovrDistortionCap_SRGB) + glEnable(GL_FRAMEBUFFER_SRGB); + else + glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + if (GLE_EXT_draw_buffers2) + { + glDisablei(GL_BLEND, 0); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + } + else + { + glDisable(GL_BLEND); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + } + glDisable(GL_DITHER); glDisable(GL_RASTERIZER_DISCARD); - if (glState->GlMajorVersion >= 3 && glState->GlMajorVersion >= 2) + if (GLEContext::GetCurrentContext()->WholeVersion >= 302) + { glDisable(GL_SAMPLE_MASK); - glDisable(GL_SCISSOR_TEST); + } glClearColor( RState.ClearColor[0], @@ -469,14 +586,31 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ glClear(GL_COLOR_BUFFER_BIT); for (int eyeNum = 0; eyeNum < 2; eyeNum++) - { + { ShaderFill distortionShaderFill(DistortionShader); distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture); + if(overdriveActive) + { + distortionShaderFill.SetTexture(1, pOverdriveTextures[LastUsedOverdriveTextureIndex]); + + float overdriveScaleRegularRise; + float overdriveScaleRegularFall; + GetOverdriveScales(overdriveScaleRegularRise, overdriveScaleRegularFall); + DistortionShader->SetUniform3f("OverdriveScales_IsSrgb", overdriveScaleRegularRise, overdriveScaleRegularFall, + (RState.DistortionCaps & ovrDistortionCap_SRGB) ? 1.0f : -1.0f); + } + else + { + // -1.0f disables PLO + DistortionShader->SetUniform3f("OverdriveScales_IsSrgb", -1.0f, -1.0f, -1.0f); + } + DistortionShader->SetUniform2f("EyeToSourceUVScale", eachEye[eyeNum].UVScaleOffset[0].x, eachEye[eyeNum].UVScaleOffset[0].y); - DistortionShader->SetUniform2f("EyeToSourceUVOffset", eachEye[eyeNum].UVScaleOffset[1].x, eachEye[eyeNum].UVScaleOffset[1].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); - if (DistortionCaps & ovrDistortionCap_TimeWarp) + if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) { ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, @@ -495,8 +629,36 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles, &DistortionMeshVAOs[eyeNum], true); } } + + LastUsedOverdriveTextureIndex = currOverdriveTextureIndex; + + // Re-activate to only draw on back buffer + if(overdriveActive) + { + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0}; + glDrawBuffers(OVR_ARRAY_COUNT(drawBuffers), drawBuffers); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + //glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0); + OVR_ASSERT(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + + glBindFramebuffer( GL_READ_FRAMEBUFFER, OverdriveFbo ); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OverdriveBackBufferTexture->TexId, 0); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + OVR_ASSERT(glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + + glBlitFramebuffer( 0, 0, OverdriveBackBufferTexture->GetWidth(), OverdriveBackBufferTexture->GetHeight(), + 0, 0, OverdriveBackBufferTexture->GetWidth(), OverdriveBackBufferTexture->GetHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST ); + + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + GLint err = glGetError(); + OVR_ASSERT(!err); OVR_UNUSED(err); + } } + void DistortionRenderer::createDrawQuad() { const int numQuadVerts = 4; @@ -536,20 +698,21 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor createDrawQuad(); } - ShaderFill quadFill(SimpleQuadShader); + Ptr quadShader = (RState.DistortionCaps & ovrDistortionCap_SRGB) ? SimpleQuadGammaShader : SimpleQuadShader; + ShaderFill quadFill(quadShader); //quadFill.SetInputLayout(SimpleQuadVertexIL); - setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h)); + setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); - SimpleQuadShader->SetUniform2f("Scale", 0.2f, 0.2f); - SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f, - (float)latencyTesterDrawColor[0] / 255.99f, - (float)latencyTesterDrawColor[0] / 255.99f, - 1.0f); + quadShader->SetUniform2f("Scale", 0.3f, 0.3f); + quadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f, + (float)latencyTesterDrawColor[0] / 255.99f, + (float)latencyTesterDrawColor[0] / 255.99f, + 1.0f); for(int eyeNum = 0; eyeNum < 2; eyeNum++) { - SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.4f : 0.4f, 0.0f); + quadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.5f : 0.5f, 0.0f); renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false); } } @@ -563,18 +726,31 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol createDrawQuad(); } - ShaderFill quadFill(SimpleQuadShader); + Ptr quadShader = (RState.DistortionCaps & ovrDistortionCap_SRGB) ? SimpleQuadGammaShader : SimpleQuadShader; + ShaderFill quadFill(quadShader); - setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h)); + setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); - SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f, - (float)latencyTesterPixelColor[0] / 255.99f, - (float)latencyTesterPixelColor[0] / 255.99f, - 1.0f); +#ifdef OVR_BUILD_DEBUG + quadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f, + (float)latencyTesterPixelColor[1] / 255.99f, + (float)latencyTesterPixelColor[2] / 255.99f, + 1.0f); - Vector2f scale(2.0f / RParams.RTSize.w, 2.0f / RParams.RTSize.h); - SimpleQuadShader->SetUniform2f("Scale", scale.x, scale.y); - SimpleQuadShader->SetUniform2f("PositionOffset", 1.0f, 1.0f); + Vector2f scale(20.0f / RParams.BackBufferSize.w, 20.0f / RParams.BackBufferSize.h); +#else + quadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f, + (float)latencyTesterPixelColor[0] / 255.99f, + (float)latencyTesterPixelColor[0] / 255.99f, + 1.0f); + + 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); } @@ -584,8 +760,6 @@ void DistortionRenderer::renderPrimitives( int offset, int count, PrimitiveType rprim, GLuint* vao, bool isDistortionMesh) { - GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); - GLenum prim; switch (rprim) { @@ -611,20 +785,22 @@ void DistortionRenderer::renderPrimitives( { if (*vao != 0) { - glBindVertexArray(*vao); + glBindVertexArray(*vao); if (isDistortionMesh) glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL); else glDrawArrays(prim, 0, count); + + glBindVertexArray(0); } else { - if (glState->SupportsVao) + if (GL_ARB_vertex_array_object) { glGenVertexArrays(1, vao); glBindVertexArray(*vao); - } + } int attributeCount = (isDistortionMesh) ? 5 : 1; int* locs = new int[attributeCount]; @@ -641,11 +817,11 @@ void DistortionRenderer::renderPrimitives( locs[3] = glGetAttribLocation(prog, "TexCoord1"); locs[4] = glGetAttribLocation(prog, "TexCoord2"); - glVertexAttribPointer(locs[0], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, Pos)); + glVertexAttribPointer(locs[0], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, ScreenPosNDC)); glVertexAttribPointer(locs[1], 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, Col)); - glVertexAttribPointer(locs[2], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, TexR)); - glVertexAttribPointer(locs[3], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, TexG)); - glVertexAttribPointer(locs[4], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, TexB)); + glVertexAttribPointer(locs[2], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, TanEyeAnglesR)); + glVertexAttribPointer(locs[3], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, TanEyeAnglesG)); + glVertexAttribPointer(locs[4], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast(offset)+offsetof(DistortionVertex, TanEyeAnglesB)); } else { @@ -663,13 +839,18 @@ void DistortionRenderer::renderPrimitives( glDrawArrays(prim, 0, count); - if (!glState->SupportsVao) + if (!GL_ARB_vertex_array_object) { for (int i = 0; i < attributeCount; ++i) glDisableVertexAttribArray(locs[i]); } delete[] locs; + + if (GL_ARB_vertex_array_object) + { + glBindVertexArray(0); + } } } } @@ -682,14 +863,10 @@ void DistortionRenderer::setViewport(const Recti& vp) void DistortionRenderer::initShaders() { - GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); - - const char* shaderPrefix = - (glState->GlMajorVersion < 3 || (glState->GlMajorVersion == 3 && glState->GlMinorVersion < 2)) ? - glsl2Prefix : glsl3Prefix; + const char* shaderPrefix = (GLEContext::GetCurrentContext()->WholeVersion >= 302) ? glsl3Prefix : glsl2Prefix; { - ShaderInfo vsInfo = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps]; + ShaderInfo vsInfo = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & RState.DistortionCaps]; size_t vsSize = strlen(shaderPrefix)+vsInfo.ShaderSize; char* vsSource = new char[vsSize]; @@ -706,7 +883,7 @@ void DistortionRenderer::initShaders() delete[](vsSource); - ShaderInfo psInfo = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps]; + ShaderInfo psInfo = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & RState.DistortionCaps]; size_t psSize = strlen(shaderPrefix)+psInfo.ShaderSize; char* psSource = new char[psSize]; @@ -751,18 +928,53 @@ void DistortionRenderer::initShaders() SimpleQuadShader->SetShader(ps); delete[](psSource); - } + } + { + size_t vsSize = strlen(shaderPrefix)+sizeof(SimpleQuad_vs); + char* vsSource = new char[vsSize]; + OVR_strcpy(vsSource, vsSize, shaderPrefix); + OVR_strcat(vsSource, vsSize, SimpleQuad_vs); + + Ptr vs = *new GL::VertexShader( + &RParams, + (void*)vsSource, vsSize, + SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0])); + + SimpleQuadGammaShader = *new ShaderSet; + SimpleQuadGammaShader->SetShader(vs); + + delete[](vsSource); + + size_t psSize = strlen(shaderPrefix)+sizeof(SimpleQuadGamma_fs); + char* psSource = new char[psSize]; + OVR_strcpy(psSource, psSize, shaderPrefix); + OVR_strcat(psSource, psSize, SimpleQuadGamma_fs); + + Ptr ps = *new GL::FragmentShader( + &RParams, + (void*)psSource, psSize, + SimpleQuadGamma_fs_refl, sizeof(SimpleQuadGamma_fs_refl) / sizeof(SimpleQuadGamma_fs_refl[0])); + + SimpleQuadGammaShader->SetShader(ps); + + delete[](psSource); + } } void DistortionRenderer::destroy() { - GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); + Context currContext; + currContext.InitFromCurrent(); + + distortionContext.Bind(); for(int eyeNum = 0; eyeNum < 2; eyeNum++) { - if (glState->SupportsVao) + if (GL_ARB_vertex_array_object) + { glDeleteVertexArrays(1, &DistortionMeshVAOs[eyeNum]); + } DistortionMeshVAOs[eyeNum] = 0; @@ -778,7 +990,22 @@ void DistortionRenderer::destroy() } LatencyTesterQuadVB.Clear(); - LatencyVAO = 0; + + if(LatencyVAO != 0) + { + glDeleteVertexArrays(1, &LatencyVAO); + LatencyVAO = 0; + } + + if(OverdriveFbo != 0) + { + glDeleteFramebuffers(1, &OverdriveFbo); + } + + currContext.Bind(); + distortionContext.Destroy(); + // Who is responsible for destroying the app's context? } + }}} // OVR::CAPI::GL diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h index 60f1a9f..f48e42d 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h @@ -5,12 +5,23 @@ Content : Distortion renderer header for GL Created : November 11, 2013 Authors : David Borel, Lee Cooper -Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. +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 +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_GL_DistortionRenderer_h @@ -33,7 +44,7 @@ public: DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState); - ~DistortionRenderer(); + virtual ~DistortionRenderer(); // Creation function for the device. @@ -44,12 +55,11 @@ public: // ***** Public DistortionRenderer interface - virtual bool Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned distortionCaps); + virtual bool Initialize(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; - virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture); + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture); - virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor); + virtual void EndFrame(bool swapBuffers); void WaitUntilGpuIdle(); @@ -58,57 +68,11 @@ public: double FlushGpuAndWaitTillTime(double absTime); protected: - - - class GraphicsState : public CAPI::DistortionRenderer::GraphicsState - { - public: - GraphicsState(); - virtual void Save(); - virtual void Restore(); - - protected: - void ApplyBool(GLenum Name, GLint Value); - - public: - GLint GlMajorVersion; - GLint GlMinorVersion; - bool SupportsVao; - - GLint Viewport[4]; - GLfloat ClearColor[4]; - GLint DepthTest; - GLint CullFace; - GLint Program; - GLint ActiveTexture; - GLint TextureBinding; - GLint VertexArray; - GLint FrameBufferBinding; - - GLint Blend; - GLint ColorWritemask[4]; - GLint Dither; - GLint Fog; - GLint Lighting; - GLint RasterizerDiscard; - GLint RenderMode; - GLint SampleMask; - GLint ScissorTest; - GLfloat ZoomX; - GLfloat ZoomY; - }; - - // TBD: Should we be using oe from RState instead? - unsigned DistortionCaps; struct FOR_EACH_EYE { - FOR_EACH_EYE() : TextureSize(0), RenderViewport(Sizei(0)) { } + FOR_EACH_EYE() : numVerts(0), numIndices(0), texture(0), /*UVScaleOffset[],*/ TextureSize(0, 0), RenderViewport(0, 0, 0, 0) { } -#if 0 - IDirect3DVertexBuffer9 * dxVerts; - IDirect3DIndexBuffer9 * dxIndices; -#endif int numVerts; int numIndices; @@ -119,10 +83,15 @@ protected: Recti RenderViewport; } eachEye[2]; + Ptr pOverdriveTextures[NumOverdriveTextures]; + Ptr OverdriveBackBufferTexture; + // GL context and utility variables. - RenderParams RParams; + 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. // Helpers + void initOverdrive(); void initBuffersAndShaders(); void initShaders(); void initFullscreenQuad(); @@ -140,6 +109,8 @@ protected: void renderLatencyQuad(unsigned char* latencyTesterDrawColor); void renderLatencyPixel(unsigned char* latencyTesterPixelColor); + void renderEndFrame(); + Ptr pEyeTextures[2]; Ptr DistortionMeshVBs[2]; // one per-eye @@ -148,6 +119,8 @@ protected: Ptr DistortionShader; + bool RotateCCW90; + struct StandardUniformData { Matrix4f Proj; @@ -157,10 +130,9 @@ protected: GLuint LatencyVAO; Ptr LatencyTesterQuadVB; Ptr SimpleQuadShader; + Ptr SimpleQuadGammaShader; - Ptr CurRenderTarget; - Array > DepthBuffers; - GLuint CurrentFbo; + GLuint OverdriveFbo; GLint SavedViewport[4]; GLfloat SavedClearColor[4]; @@ -175,4 +147,4 @@ protected: }}} // OVR::CAPI::GL -#endif // OVR_CAPI_GL_DistortionRenderer_h \ No newline at end of file +#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 03fd174..6f48122 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h @@ -5,11 +5,22 @@ Created : November 11, 2013 Authors : David Borel, Volga Aksoy - Copyright : Copyright 2013 Oculus VR, 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. + 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. ************************************************************************************/ @@ -25,21 +36,39 @@ namespace OVR { namespace CAPI { namespace GL { static const char glsl2Prefix[] = "#version 110\n" "#extension GL_ARB_shader_texture_lod : enable\n" + "#extension GL_ARB_draw_buffers : enable\n" + "#extension GL_EXT_gpu_shader4 : enable\n" "#define _FRAGCOLOR_DECLARATION\n" + "#define _MRTFRAGCOLOR0_DECLARATION\n" + "#define _MRTFRAGCOLOR1_DECLARATION\n" + "#define _GLFRAGCOORD_DECLARATION\n" "#define _VS_IN attribute\n" "#define _VS_OUT varying\n" "#define _FS_IN varying\n" "#define _TEXTURELOD texture2DLod\n" - "#define _FRAGCOLOR gl_FragColor\n"; + "#define _TEXTURE texture2D\n" + "#define _FRAGCOLOR gl_FragColor\n" + "#define _MRTFRAGCOLOR0 gl_FragData[0]\n" + "#define _MRTFRAGCOLOR1 gl_FragData[1]\n" // The texture coordinate [0.0,1.0] for texel i of a texture of size N is: (2i + 1)/2N + "#ifdef GL_EXT_gpu_shader4\n" + " #define _TEXELFETCHDECL vec4 texelFetch(sampler2D tex, ivec2 coord, int lod){ ivec2 size = textureSize2D(tex, lod); return texture2D(tex, vec2(float((coord.x * 2) + 1) / float(size.x * 2), float((coord.y * 2) + 1) / float(size.y * 2))); }\n" + "#endif\n"; static const char glsl3Prefix[] = "#version 150\n" "#define _FRAGCOLOR_DECLARATION out vec4 FragColor;\n" + "#define _MRTFRAGCOLOR0_DECLARATION out vec4 FragData0;\n" + "#define _MRTFRAGCOLOR1_DECLARATION out vec4 FragData1;\n" + "#define _GLFRAGCOORD_DECLARATION in vec4 gl_FragCoord;\n" "#define _VS_IN in\n" "#define _VS_OUT out\n" "#define _FS_IN in\n" "#define _TEXTURELOD textureLod\n" - "#define _FRAGCOLOR FragColor\n"; + "#define _TEXTURE texture\n" + "#define _FRAGCOLOR FragColor\n" + "#define _MRTFRAGCOLOR0 FragData0\n" + "#define _MRTFRAGCOLOR1 FragData1\n" + "#define _TEXELFETCHDECL\n"; static const char SimpleQuad_vs[] = "uniform vec2 PositionOffset;\n" @@ -72,7 +101,70 @@ namespace OVR { namespace CAPI { namespace GL { { { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 }, }; + + static const char SimpleQuadGamma_fs[] = + "uniform vec4 Color;\n" + + "_FRAGCOLOR_DECLARATION\n" + + "void main()\n" + "{\n" + " _FRAGCOLOR.rgb = pow(Color.rgb, vec3(2.2));\n" + " _FRAGCOLOR.a = Color.a;\n" + "}\n"; + + const OVR::CAPI::GL::ShaderBase::Uniform SimpleQuadGamma_fs_refl[] = + { + { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 }, + }; + + // This must be prefixed with glsl2Prefix or glsl3Prefix before being compiled. + static const char SimpleTexturedQuad_vs[] = + "uniform vec2 PositionOffset;\n" + "uniform vec2 Scale;\n" + + "_VS_IN vec3 Position;\n" + "_VS_IN vec4 Color;\n" + "_VS_IN vec2 TexCoord;\n" + + "_VS_OUT vec4 oColor;\n" + "_VS_OUT vec2 oTexCoord;\n" + + "void main()\n" + "{\n" + " gl_Position = vec4(Position.xy * Scale + PositionOffset, 0.5, 1.0);\n" + " oColor = Color;\n" + " oTexCoord = TexCoord;\n" + "}\n"; + + // The following declaration is copied from the generated D3D SimpleTexturedQuad_vs_refl.h file, with D3D_NS renamed to GL. + const OVR::CAPI::GL::ShaderBase::Uniform SimpleTexturedQuad_vs_refl[] = + { + { "PositionOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "Scale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + }; + + + // This must be prefixed with glsl2Prefix or glsl3Prefix before being compiled. + static const char SimpleTexturedQuad_ps[] = + "uniform sampler2D Texture0;\n" + + "_FS_IN vec4 oColor;\n" + "_FS_IN vec2 oTexCoord;\n" + "_FRAGCOLOR_DECLARATION\n" + + "void main()\n" + "{\n" + " _FRAGCOLOR = oColor * _TEXTURE(Texture0, oTexCoord);\n" + "}\n"; + + // The following is copied from the generated D3D SimpleTexturedQuad_ps_refl.h file, with D3D_NS renamed to GL. + const OVR::CAPI::GL::ShaderBase::Uniform SimpleTexturedQuad_ps_refl[] = + { + { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 }, + }; + static const char Distortion_vs[] = "uniform vec2 EyeToSourceUVScale;\n" @@ -94,7 +186,6 @@ namespace OVR { namespace CAPI { namespace GL { // 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" - " oTexCoord0.y = 1.0 - oTexCoord0.y;\n" " oColor = Color;\n" // Used for vignette fade. "}\n"; @@ -114,7 +205,7 @@ namespace OVR { namespace CAPI { namespace GL { "void main()\n" "{\n" - " _FRAGCOLOR = _TEXTURELOD(Texture0, oTexCoord0, 0.0);\n" + " _FRAGCOLOR = _TEXTURE(Texture0, oTexCoord0, 0.0);\n" " _FRAGCOLOR.a = 1.0;\n" "}\n"; @@ -129,8 +220,8 @@ namespace OVR { namespace CAPI { namespace GL { "_VS_IN vec4 Color;\n" "_VS_IN vec2 TexCoord0;\n" - "_FS_IN vec4 oColor;\n" - "_FS_IN vec2 oTexCoord0;\n" + "_VS_OUT vec4 oColor;\n" + "_VS_OUT vec2 oTexCoord0;\n" "void main()\n" "{\n" @@ -163,7 +254,6 @@ namespace OVR { namespace CAPI { namespace GL { // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) " vec2 SrcCoord = Flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" " oTexCoord0 = SrcCoord;\n" - " oTexCoord0.y = 1.0-oTexCoord0.y;\n" " oColor = vec4(Color.r, Color.r, Color.r, Color.r);\n" // Used for vignette fade. "}\n"; @@ -199,11 +289,8 @@ namespace OVR { namespace CAPI { namespace GL { // 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" - " oTexCoord0.y = 1.0-oTexCoord0.y;\n" " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord1.y = 1.0-oTexCoord1.y;\n" " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord2.y = 1.0-oTexCoord2.y;\n" " oColor = Color;\n" // Used for vignette fade. "}\n"; @@ -216,23 +303,69 @@ namespace OVR { namespace CAPI { namespace GL { static const char DistortionChroma_fs[] = "uniform sampler2D Texture0;\n" - + "uniform sampler2D Texture1;\n" + "uniform vec3 OverdriveScales_IsSrgb;\n" + "_FS_IN vec4 oColor;\n" "_FS_IN vec2 oTexCoord0;\n" "_FS_IN vec2 oTexCoord1;\n" "_FS_IN vec2 oTexCoord2;\n" - "_FRAGCOLOR_DECLARATION\n" + "_MRTFRAGCOLOR0_DECLARATION\n" // Desired color (next frame's "PrevTexture") + "_MRTFRAGCOLOR1_DECLARATION\n" // Overdriven color (Back-buffer) + "_GLFRAGCOORD_DECLARATION\n" + + "#ifdef _TEXELFETCHDECL\n" + "_TEXELFETCHDECL\n" + "#endif\n" "void main()\n" "{\n" - " float ResultR = _TEXTURELOD(Texture0, oTexCoord0, 0.0).r;\n" - " float ResultG = _TEXTURELOD(Texture0, oTexCoord1, 0.0).g;\n" - " float ResultB = _TEXTURELOD(Texture0, oTexCoord2, 0.0).b;\n" - - " _FRAGCOLOR = vec4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" + " float ResultR = _TEXTURE(Texture0, oTexCoord0, 0.0).r;\n" + " float ResultG = _TEXTURE(Texture0, oTexCoord1, 0.0).g;\n" + " float ResultB = _TEXTURE(Texture0, oTexCoord2, 0.0).b;\n" + " vec3 newColor = vec3(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b);\n" + + " _MRTFRAGCOLOR0 = vec4(newColor, 1);\n" + " _MRTFRAGCOLOR1 = _MRTFRAGCOLOR0;\n" + + " #ifdef _TEXELFETCHDECL\n" + // pixel luminance overdrive + " if(OverdriveScales_IsSrgb.x > 0.0)\n" + " {\n" + " ivec2 pixelCoord = ivec2(gl_FragCoord.x, gl_FragCoord.y);\n" + " vec3 oldColor = texelFetch(Texture1, pixelCoord, 0).rgb;\n" + + " vec3 adjustedScales;\n" + " adjustedScales.x = newColor.x > oldColor.x ? OverdriveScales_IsSrgb.x : OverdriveScales_IsSrgb.y;\n" + " adjustedScales.y = newColor.y > oldColor.y ? OverdriveScales_IsSrgb.x : OverdriveScales_IsSrgb.y;\n" + " adjustedScales.z = newColor.z > oldColor.z ? OverdriveScales_IsSrgb.x : OverdriveScales_IsSrgb.y;\n" + + // overdrive is tuned for gamma space so if we're in linear space fix gamma before doing the calculation + " vec3 overdriveColor;\n" + " if(OverdriveScales_IsSrgb.z > 0.0)\n" + " {\n" + " oldColor = pow(oldColor, vec3(1.0/2.2, 1.0/2.2, 1.0/2.2));\n" + " newColor = pow(newColor, vec3(1.0/2.2, 1.0/2.2, 1.0/2.2));\n" + " overdriveColor = clamp(newColor + (newColor - oldColor) * adjustedScales, 0.0, 1.0);\n" + " overdriveColor = pow(overdriveColor, vec3(2.2, 2.2, 2.2));\n" + " }\n" + " else\n" + " overdriveColor = clamp(newColor + (newColor - oldColor) * adjustedScales, 0.0, 1.0);\n" + + " _MRTFRAGCOLOR1 = vec4(overdriveColor, 1.0);\n" + " }\n" + " #else\n" + // If statement to keep OverdriveScales_IsSrgb from being optimized out. + " if(OverdriveScales_IsSrgb.x > 0.0)\n" + " _MRTFRAGCOLOR1 = vec4(newColor, 1);\n" + " #endif\n" "}\n"; + const OVR::CAPI::GL::ShaderBase::Uniform DistortionChroma_ps_refl[] = + { + { "OverdriveScales_IsSrgb", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 12 }, + }; static const char DistortionTimewarpChroma_vs[] = "uniform vec2 EyeToSourceUVScale;\n" @@ -303,11 +436,8 @@ namespace OVR { namespace CAPI { namespace GL { " vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" " oTexCoord0 = SrcCoordR;\n" - " oTexCoord0.y = 1.0-oTexCoord0.y;\n" " oTexCoord1 = SrcCoordG;\n" - " oTexCoord1.y = 1.0-oTexCoord1.y;\n" " oTexCoord2 = SrcCoordB;\n" - " oTexCoord2.y = 1.0-oTexCoord2.y;\n" " oColor = vec4(Color.r, Color.r, Color.r, Color.r);\n" // Used for vignette fade. "}\n"; diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp new file mode 100644 index 0000000..a795fa9 --- /dev/null +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp @@ -0,0 +1,500 @@ +/************************************************************************************ + +Filename : CAPI_GL_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_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" + + +OVR_DISABLE_MSVC_WARNING(4996) // "This function or variable may be unsafe..." + + +namespace OVR { namespace CAPI { + + +// Loads the TGA data from the File as an array of width * height 32 bit Texture_RGBA values. +// Returned pointer must be freed with OVR_FREE. +uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height) +{ + // See http://www.fileformat.info/format/tga/egff.htm for format details. + // TGA files are stored with little-endian data. + uint8_t* pRGBA = NULL; + + f->SeekToBegin(); + + const int desclen = f->ReadUByte(); + const int palette = f->ReadUByte(); + OVR_UNUSED(palette); + const int imgtype = f->ReadUByte(); + f->ReadUInt16(); // Skip bytes + int palCount = f->ReadUInt16(); + int palSize = f->ReadUByte(); + f->ReadUInt16(); + f->ReadUInt16(); + width = f->ReadUInt16(); + height = f->ReadUInt16(); + int bpp = f->ReadUByte(); + f->ReadUByte(); + + const int ImgTypeBGRAUncompressed = 2; + const int ImgTypeBGRARLECompressed = 10; + + OVR_ASSERT(((imgtype == ImgTypeBGRAUncompressed) || (imgtype == ImgTypeBGRARLECompressed)) && ((bpp == 24) || (bpp == 32))); + + // imgType 2 is uncompressed true-color image. + // imgType 10 is run-length encoded true-color image. + if(((imgtype == ImgTypeBGRAUncompressed) || (imgtype == ImgTypeBGRARLECompressed)) && ((bpp == 24) || (bpp == 32))) + { + int imgsize = width * height * 4; + pRGBA = (uint8_t*) OVR_ALLOC(imgsize); + f->Skip(desclen); + f->Skip(palCount * (palSize + 7) >> 3); + int strideBytes = width * 4; // This is the number of bytes between successive rows. + + unsigned char buf[4] = { 0, 0, 0, alpha }; // If bpp is 24 then this alpha will be unmodified below. + + switch (imgtype) + { + case ImgTypeBGRAUncompressed: + switch (bpp) + { + case 24: + case 32: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + f->Read(buf, bpp / 8); // Data is stored as B, G, R + pRGBA[y*strideBytes + x*4 + 0] = buf[2]; + pRGBA[y*strideBytes + x*4 + 1] = buf[1]; + pRGBA[y*strideBytes + x*4 + 2] = buf[0]; + pRGBA[y*strideBytes + x*4 + 3] = buf[3]; + } + } + break; + } + break; + + case ImgTypeBGRARLECompressed: + switch (bpp) + { + case 24: + case 32: + for (int y = 0; y < height; y++) // RLE spans don't cross successive rows. + { + int x = 0; + + while(x < width) + { + uint8_t rleByte; + f->Read(&rleByte, 1); + + if(rleByte & 0x80) // If the high byte is set then what follows are RLE bytes. + { + size_t rleCount = ((rleByte & 0x7f) + 1); + f->Read(buf, bpp / 8); // Data is stored as B, G, R, A + + for (; rleCount; --rleCount, ++x) + { + pRGBA[y*strideBytes + x*4 + 0] = buf[2]; + pRGBA[y*strideBytes + x*4 + 1] = buf[1]; + pRGBA[y*strideBytes + x*4 + 2] = buf[0]; + pRGBA[y*strideBytes + x*4 + 3] = buf[3]; + } + } + else // Else what follows are regular bytes of a count indicated by rleByte + { + for (size_t rleCount = (rleByte + 1); rleCount; --rleCount, ++x) + { + f->Read(buf, bpp / 8); // Data is stored as B, G, R, A + pRGBA[y*strideBytes + x*4 + 0] = buf[2]; + pRGBA[y*strideBytes + x*4 + 1] = buf[1]; + pRGBA[y*strideBytes + x*4 + 2] = buf[0]; + pRGBA[y*strideBytes + x*4 + 3] = buf[3]; + } + } + } + } + break; + } + break; + } + } + + return pRGBA; +} // LoadTextureTgaData + + + +namespace GL { + + +// 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); + } +}; + + + +// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. +Texture* LoadTextureTga(RenderParams& rParams, int samplerMode, OVR::File* f, uint8_t alpha) +{ + OVR::CAPI::GL::Texture* pTexture = NULL; + + int width, height; + const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); + + if (pRGBA) + { + pTexture = new OVR::CAPI::GL::Texture(&rParams, width, height); + + // SetSampleMode forces the use of mipmaps through GL_LINEAR_MIPMAP_LINEAR. + pTexture->SetSampleMode(samplerMode); // Calls glBindTexture internally. + + // We are intentionally not using mipmaps. We need to use this because Texture::SetSampleMode unilaterally uses GL_LINEAR_MIPMAP_LINEAR. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + OVR_ASSERT(glGetError() == 0); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pRGBA); + OVR_ASSERT(glGetError() == 0); + + // With OpenGL 4.2+ we can use this instead of glTexImage2D: + // glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height); + // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pRGBA); + + OVR_FREE(const_cast(pRGBA)); + } + + return pTexture; +} + + +// Loads a texture from a memory image of a TGA file. +Texture* LoadTextureTga(RenderParams& rParams, int samplerMode, const uint8_t* pData, int dataSize, uint8_t alpha) +{ + MemoryFile memoryFile("", pData, dataSize); + + return LoadTextureTga(rParams, samplerMode, &memoryFile, alpha); +} + + + + +// 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() + , GLContext() + , FrameBuffer(0) + , pTexture() + , pShaderSet() + , pVertexShader() + , pFragmentShader() + , pVB() + , VAO(0) + , VAOInitialized(false) + , OrthoProjection() +{ +} + + +bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) +{ + const ovrGLConfig* config = (const ovrGLConfig*)apiConfig; + + if(config) + { + // The following is essentially copied from CAPI_GL_DistortionRender.cpp's + // Initialize function. To do: Merge this to a central location. + RenderParams.Multisample = config->OGL.Header.Multisample; + RenderParams.BackBufferSize = config->OGL.Header.BackBufferSize; + + #if defined(OVR_OS_WIN32) + RenderParams.Window = (config->OGL.Window) ? config->OGL.Window : GetActiveWindow(); + RenderParams.DC = config->OGL.DC; + #elif defined(OVR_OS_LINUX) + if (config->OGL.Disp) + { + RenderParams.Disp = config->OGL.Disp; + } + if (!RenderParams.Disp) + { + RenderParams.Disp = glXGetCurrentDisplay(); + } + if (!RenderParams.Disp) + { + OVR_DEBUG_LOG(("glXGetCurrentDisplay failed.")); + return false; + } + #endif + } + else + { + UnloadGraphics(); + } + + return true; +} + + +void HSWDisplay::Shutdown() +{ + UnloadGraphics(); +} + + +void HSWDisplay::DisplayInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay GL] DisplayInternal()")); + // We may want to call LoadGraphics here instead of within Render. +} + + +void HSWDisplay::DismissInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay GL] DismissInternal()")); + UnloadGraphicsRequested = true; // We don't directly call UnloadGraphics here because this may be executed within a different thread. +} + + +void HSWDisplay::UnloadGraphics() +{ + if(pTexture) // If initialized... + { + Context currentGLContext; + 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) + { + glDeleteVertexArrays(1, &VAO); + currentGLContext.Bind(); + GLContext.Destroy(); + } +} +} + + +void HSWDisplay::LoadGraphics() +{ + // We assume here that the current GL context is the one our resources will be associated with. + + if (FrameBuffer == 0) + { + glGenFramebuffers(1, &FrameBuffer); + } + + 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, Sample_Linear | Sample_Clamp, TextureData, (int)textureSize, 255); + } + + if (!pShaderSet) + { + pShaderSet = *new ShaderSet(); + } + + if(!pVertexShader) + { + OVR::String strShader((GLEContext::GetCurrentContext()->WholeVersion >= 302) ? glsl3Prefix : glsl2Prefix); + strShader += SimpleTexturedQuad_vs; + + pVertexShader = *new VertexShader(&RenderParams, const_cast(strShader.ToCStr()), strShader.GetLength(), SimpleTexturedQuad_vs_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_vs_refl)); + pShaderSet->SetShader(pVertexShader); + } + + if(!pFragmentShader) + { + OVR::String strShader((GLEContext::GetCurrentContext()->WholeVersion >= 302) ? glsl3Prefix : glsl2Prefix); + strShader += SimpleTexturedQuad_ps; + + pFragmentShader = *new FragmentShader(&RenderParams, const_cast(strShader.ToCStr()), strShader.GetLength(), SimpleTexturedQuad_ps_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_ps_refl)); + pShaderSet->SetShader(pFragmentShader); + } + + if(!pVB) + { + pVB = *new Buffer(&RenderParams); + + pVB->Data(Buffer_Vertex, NULL, 4 * sizeof(HASWVertex)); + HASWVertex* pVertices = (HASWVertex*)pVB->Map(0, 4 * 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); + } + } + + // We don't bind or initialize the vertex arrays here. + if (!VAO && GLE_ARB_vertex_array_object) + { + OVR_ASSERT(!VAOInitialized); + glGenVertexArrays(1, &VAO); + } +} + + +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. + ovrGLTexture* eyeTextureGL = const_cast(reinterpret_cast(eyeTexture)); + OVR_ASSERT(eyeTextureGL->Texture.Header.API == ovrRenderAPI_OpenGL); + + GL::AutoContext autoGLContext(GLContext); // Saves the current GL context, binds our GLContext, then at the end of scope re-binds the current GL context. + + // Load the graphics if not loaded already. + if (!pTexture) + LoadGraphics(); + + // Calculate ortho projection. + GetOrthoProjection(RenderState, OrthoProjection); + + // Set the rendering to be to the eye texture. + glBindFramebuffer(GL_FRAMEBUFFER, FrameBuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, eyeTextureGL->OGL.TexId, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); // We aren't using depth, as we currently want this to overwrite everything. + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + OVR_ASSERT(status == GL_FRAMEBUFFER_COMPLETE); OVR_UNUSED(status); + + // Set up the viewport + const GLint x = (GLint)eyeTextureGL->Texture.Header.RenderViewport.Pos.x; + const GLint y = (GLint)eyeTextureGL->Texture.Header.RenderViewport.Pos.y; // Note that GL uses bottom-up coordinates. + const GLsizei w = (GLsizei)eyeTextureGL->Texture.Header.RenderViewport.Size.w; + const GLsizei h = (GLsizei)eyeTextureGL->Texture.Header.RenderViewport.Size.h; + glViewport(x, y, w, h); + + // Set fixed-function render states. + //glDepthRange(0.0, 1.0); // This is the default + glDepthMask(GL_FALSE); + glDisable(GL_DEPTH_TEST); + glFrontFace(GL_CW); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Enable the buffer and shaders we use. + ShaderFill fill(pShaderSet); + if (pTexture) + fill.SetTexture(0, pTexture); + + // Set shader uniforms. + 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->SetUniform2f("PositionOffset", OrthoProjection[eye].GetTranslation().x, 0.0f); + + // Set vertex attributes + if (GLE_ARB_vertex_array_object) + { + OVR_ASSERT(VAO != 0); + glBindVertexArray(VAO); + } + + if(!VAOInitialized) // This executes for the case that VAO isn't supported. + { + glBindBuffer(GL_ARRAY_BUFFER, pVB->GLBuffer); // This must be called before glVertexAttribPointer is called below. + + const GLuint shaderProgram = pShaderSet->Prog; + GLint attributeLocationArray[3]; + + attributeLocationArray[0] = glGetAttribLocation(shaderProgram, "Position"); + glVertexAttribPointer(attributeLocationArray[0], sizeof(Vector3f)/sizeof(float), GL_FLOAT, false, sizeof(HASWVertex), reinterpret_cast(offsetof(HASWVertex, Pos))); + + attributeLocationArray[1] = glGetAttribLocation(shaderProgram, "Color"); + glVertexAttribPointer(attributeLocationArray[1], sizeof(Color)/sizeof(uint8_t), GL_UNSIGNED_BYTE, true, sizeof(HASWVertex), reinterpret_cast(offsetof(HASWVertex, C))); // True because we want it to convert [0,255] to [0,1] for us. + + attributeLocationArray[2] = glGetAttribLocation(shaderProgram, "TexCoord"); + glVertexAttribPointer(attributeLocationArray[2], sizeof(float[2])/sizeof(float), GL_FLOAT, false, sizeof(HASWVertex), reinterpret_cast(offsetof(HASWVertex, U))); + + for (size_t i = 0; i < OVR_ARRAY_COUNT(attributeLocationArray); i++) + glEnableVertexAttribArray((GLuint)i); + } + + fill.Set(Prim_TriangleStrip); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + if (GLE_ARB_vertex_array_object) + { + VAOInitialized = true; + glBindVertexArray(0); + } + } +} + + +}}} // namespace OVR::CAPI::GL diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h new file mode 100644 index 0000000..333fbab --- /dev/null +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h @@ -0,0 +1,77 @@ +/************************************************************************************ + +Filename : CAPI_GL_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_GL_HSWDisplay_h +#define OVR_CAPI_GL_HSWDisplay_h + + +#include "../CAPI_HSWDisplay.h" +#include "CAPI_GL_Util.h" + + +namespace OVR { namespace CAPI { namespace GL { + + class HSWDisplay : public CAPI::HSWDisplay + { + public: + HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); + + // Must be called before use. apiConfig is such that: + // const ovrGLConfig* config = (const ovrGLConfig*)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 UnloadGraphics(); + void LoadGraphics(); + + OVR::CAPI::GL::RenderParams RenderParams; + OVR::CAPI::GL::Context GLContext; // Our prive OpenGL context for drawing. + GLuint FrameBuffer; // This is a container for a texture, depth buffer, stencil buffer to be rendered to. To consider: Make a wrapper class, like the OculusWorldDemo RBuffer class. + Ptr pTexture; + Ptr pShaderSet; + Ptr pVertexShader; + Ptr pFragmentShader; + Ptr pVB; + GLuint VAO; // Vertex Array Object. + bool VAOInitialized; // True if the VAO was initialized with vertex buffer data. + Matrix4f OrthoProjection[2]; // Projection for 2D. + + private: + OVR_NON_COPYABLE(HSWDisplay) + }; + +}}} // namespace OVR::CAPI::GL + + +#endif // OVR_CAPI_GL_HSWDisplay_h + diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp index 910e28c..e3fdaac 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp @@ -1,19 +1,22 @@ /************************************************************************************ -Filename : Render_GL_Device.cpp +Filename : CAPI_GL_Util.cpp Content : RenderDevice implementation for OpenGL Created : September 10, 2012 Authors : David Borel, Andrew Reisse -Copyright : Copyright 2012 Oculus VR, Inc. 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, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. -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 +http://www.oculusvr.com/licenses/LICENSE-3.2 -Unless required by applicable law or agreed to in writing, software +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,182 +28,49 @@ limitations under the License. #include "../../Kernel/OVR_Log.h" #include -namespace OVR { namespace CAPI { namespace GL { +#if defined(OVR_OS_LINUX) + #include "../../Displays/OVR_Linux_SDKWindow.h" +#endif +#if defined(OVR_OS_MAC) + #include + #include +typedef void *CGSConnectionID; +typedef int32_t CGSWindowID; +typedef int32_t CGSSurfaceID; -// GL Hooks for non-Mac. -#if !defined(OVR_OS_MAC) +extern "C" CGLError CGLGetSurface(CGLContextObj ctx, CGSConnectionID *cid, CGSWindowID *wid, CGSSurfaceID *sid); +extern "C" CGLError CGLSetSurface(CGLContextObj ctx, CGSConnectionID cid, CGSWindowID wid, CGSSurfaceID sid); +#endif -#if defined(OVR_OS_WIN32) -PFNWGLGETPROCADDRESS wglGetProcAddress; -PFNGLENABLEPROC glEnable; -PFNGLDISABLEPROC glDisable; -PFNGLGETFLOATVPROC glGetFloatv; -PFNGLGETINTEGERVPROC glGetIntegerv; -PFNGLGETSTRINGPROC glGetString; -PFNGLCOLORMASKPROC glColorMask; -PFNGLCLEARPROC glClear; -PFNGLCLEARCOLORPROC glClearColor; -PFNGLCLEARDEPTHPROC glClearDepth; -PFNGLVIEWPORTPROC glViewport; -PFNGLDRAWELEMENTSPROC glDrawElements; -PFNGLTEXPARAMETERIPROC glTexParameteri; -PFNGLFLUSHPROC glFlush; -PFNGLFINISHPROC glFinish; -PFNGLDRAWARRAYSPROC glDrawArrays; -PFNGLGENTEXTURESPROC glGenTextures; -PFNGLDELETETEXTURESPROC glDeleteTextures; -PFNGLBINDTEXTUREPROC glBindTexture; -PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; -PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; +namespace OVR { -#elif defined(OVR_OS_LINUX) -PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; +OVR::GLEContext gleContext; -#endif -PFNGLDELETESHADERPROC glDeleteShader; -PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -PFNGLACTIVETEXTUREPROC glActiveTexture; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -PFNGLBINDBUFFERPROC glBindBuffer; -PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; -PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -PFNGLDELETEBUFFERSPROC glDeleteBuffers; -PFNGLBUFFERDATAPROC glBufferData; -PFNGLGENBUFFERSPROC glGenBuffers; -PFNGLMAPBUFFERPROC glMapBuffer; -PFNGLUNMAPBUFFERPROC glUnmapBuffer; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -PFNGLGETSHADERIVPROC glGetShaderiv; -PFNGLCOMPILESHADERPROC glCompileShader; -PFNGLSHADERSOURCEPROC glShaderSource; -PFNGLCREATESHADERPROC glCreateShader; -PFNGLCREATEPROGRAMPROC glCreateProgram; -PFNGLATTACHSHADERPROC glAttachShader; -PFNGLDETACHSHADERPROC glDetachShader; -PFNGLDELETEPROGRAMPROC glDeleteProgram; -PFNGLUNIFORM1IPROC glUniform1i; -PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; -PFNGLUSEPROGRAMPROC glUseProgram; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; -PFNGLGETPROGRAMIVPROC glGetProgramiv; -PFNGLLINKPROGRAMPROC glLinkProgram; -PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; -PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; -PFNGLUNIFORM4FVPROC glUniform4fv; -PFNGLUNIFORM3FVPROC glUniform3fv; -PFNGLUNIFORM2FVPROC glUniform2fv; -PFNGLUNIFORM1FVPROC glUniform1fv; -PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; -PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; -PFNGLBINDVERTEXARRAYPROC glBindVertexArray; - - -#if defined(OVR_OS_WIN32) - -void* GetFunction(const char* functionName) +OVR::GLEContext* GetGLEContext() { - return wglGetProcAddress(functionName); + return &gleContext; } -#else -void (*GetFunction(const char *functionName))( void ) -{ - return glXGetProcAddress((GLubyte*)functionName); -} +namespace CAPI { namespace GL { -#endif void InitGLExtensions() { - if (glGenVertexArrays) - return; - -#if defined(OVR_OS_WIN32) - HINSTANCE hInst = LoadLibrary(L"Opengl32.dll"); - if (!hInst) - return; - - glGetFloatv = (PFNGLGETFLOATVPROC) GetProcAddress(hInst, "glGetFloatv"); - glGetIntegerv = (PFNGLGETINTEGERVPROC) GetProcAddress(hInst, "glGetIntegerv"); - glGetString = (PFNGLGETSTRINGPROC) GetProcAddress(hInst, "glGetString"); - glEnable = (PFNGLENABLEPROC) GetProcAddress(hInst, "glEnable"); - glDisable = (PFNGLDISABLEPROC) GetProcAddress(hInst, "glDisable"); - glColorMask = (PFNGLCOLORMASKPROC) GetProcAddress(hInst, "glColorMask"); - glClear = (PFNGLCLEARPROC) GetProcAddress(hInst, "glClear" ); - glClearColor = (PFNGLCLEARCOLORPROC) GetProcAddress(hInst, "glClearColor"); - glClearDepth = (PFNGLCLEARDEPTHPROC) GetProcAddress(hInst, "glClearDepth"); - glViewport = (PFNGLVIEWPORTPROC) GetProcAddress(hInst, "glViewport"); - glFlush = (PFNGLFLUSHPROC) GetProcAddress(hInst, "glFlush"); - glFinish = (PFNGLFINISHPROC) GetProcAddress(hInst, "glFinish"); - glDrawArrays = (PFNGLDRAWARRAYSPROC) GetProcAddress(hInst, "glDrawArrays"); - glDrawElements = (PFNGLDRAWELEMENTSPROC) GetProcAddress(hInst, "glDrawElements"); - glGenTextures = (PFNGLGENTEXTURESPROC) GetProcAddress(hInst,"glGenTextures"); - glDeleteTextures = (PFNGLDELETETEXTURESPROC) GetProcAddress(hInst,"glDeleteTextures"); - glBindTexture = (PFNGLBINDTEXTUREPROC) GetProcAddress(hInst,"glBindTexture"); - glTexParameteri = (PFNGLTEXPARAMETERIPROC) GetProcAddress(hInst, "glTexParameteri"); - - wglGetProcAddress = (PFNWGLGETPROCADDRESS) GetProcAddress(hInst, "wglGetProcAddress"); - - wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) GetFunction("wglGetSwapIntervalEXT"); - wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) GetFunction("wglSwapIntervalEXT"); -#elif defined(OVR_OS_LINUX) - glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) GetFunction("glXSwapIntervalEXT"); -#endif - - glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) GetFunction("glBindFramebufferEXT"); - glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GetFunction("glGenVertexArrays"); - glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GetFunction("glDeleteVertexArrays"); - glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) GetFunction("glBindVertexArray"); - glGenBuffers = (PFNGLGENBUFFERSPROC) GetFunction("glGenBuffers"); - glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) GetFunction("glDeleteBuffers"); - glBindBuffer = (PFNGLBINDBUFFERPROC) GetFunction("glBindBuffer"); - glBufferData = (PFNGLBUFFERDATAPROC) GetFunction("glBufferData"); - glMapBuffer = (PFNGLMAPBUFFERPROC) GetFunction("glMapBuffer"); - glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) GetFunction("glUnmapBuffer"); - glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) GetFunction("glDisableVertexAttribArray"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) GetFunction("glVertexAttribPointer"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) GetFunction("glEnableVertexAttribArray"); - glActiveTexture = (PFNGLACTIVETEXTUREPROC) GetFunction("glActiveTexture"); - glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) GetFunction("glUniformMatrix3fv"); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) GetFunction("glUniformMatrix4fv"); - glUniform1i = (PFNGLUNIFORM1IPROC) GetFunction("glUniform1i"); - glUniform1fv = (PFNGLUNIFORM1FVPROC) GetFunction("glUniform1fv"); - glUniform2fv = (PFNGLUNIFORM2FVPROC) GetFunction("glUniform2fv"); - glUniform3fv = (PFNGLUNIFORM3FVPROC) GetFunction("glUniform3fv"); - glUniform2fv = (PFNGLUNIFORM2FVPROC) GetFunction("glUniform2fv"); - glUniform4fv = (PFNGLUNIFORM4FVPROC) GetFunction("glUniform4fv"); - glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) GetFunction("glGetUniformLocation"); - glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) GetFunction("glGetActiveUniform"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) GetFunction("glGetShaderInfoLog"); - glGetShaderiv = (PFNGLGETSHADERIVPROC) GetFunction("glGetShaderiv"); - glCompileShader = (PFNGLCOMPILESHADERPROC) GetFunction("glCompileShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC) GetFunction("glShaderSource"); - glCreateShader = (PFNGLCREATESHADERPROC) GetFunction("glCreateShader"); - glDeleteShader = (PFNGLDELETESHADERPROC) GetFunction("glDeleteShader"); - glCreateProgram = (PFNGLCREATEPROGRAMPROC) GetFunction("glCreateProgram"); - glDeleteProgram = (PFNGLDELETEPROGRAMPROC) GetFunction("glDeleteProgram"); - glUseProgram = (PFNGLUSEPROGRAMPROC) GetFunction("glUseProgram"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) GetFunction("glGetProgramInfoLog"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC) GetFunction("glGetProgramiv"); - glLinkProgram = (PFNGLLINKPROGRAMPROC) GetFunction("glLinkProgram"); - glAttachShader = (PFNGLATTACHSHADERPROC) GetFunction("glAttachShader"); - glDetachShader = (PFNGLDETACHSHADERPROC) GetFunction("glDetachShader"); - glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) GetFunction("glBindAttribLocation"); - glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) GetFunction("glGetAttribLocation"); + if(!gleContext.IsInitialized()) + { + gleContext.SetCurrentContext(&gleContext); + gleContext.Init(); + } } -#endif Buffer::Buffer(RenderParams* rp) : pParams(rp), Size(0), Use(0), GLBuffer(0) { @@ -214,7 +84,7 @@ Buffer::~Buffer() bool Buffer::Data(int use, const void* buffer, size_t size) { - Size = size; + Size = size; switch (use & Buffer_TypeMask) { @@ -252,8 +122,17 @@ bool Buffer::Unmap(void*) return r != 0; } -ShaderSet::ShaderSet() +ShaderSet::ShaderSet() : + //Shaders[], + UniformInfo(), + //Prog(0) + ProjLoc(0), + ViewLoc(0), + //TexLoc[], + UsesLighting(false), + LightingVer(0) { + memset(TexLoc, 0, sizeof(TexLoc)); Prog = glCreateProgram(); } ShaderSet::~ShaderSet() @@ -263,26 +142,26 @@ ShaderSet::~ShaderSet() GLint ShaderSet::GetGLShader(Shader* s) { - switch (s->Stage) - { - case Shader_Vertex: { - ShaderImpl* gls = (ShaderImpl*)s; - return gls->GLShader; - } break; - case Shader_Fragment: { - ShaderImpl* gls = (ShaderImpl*)s; - return gls->GLShader; - } break; + switch (s->Stage) + { + case Shader_Vertex: { + ShaderImpl* gls = (ShaderImpl*)s; + return gls->GLShader; + } break; + case Shader_Fragment: { + ShaderImpl* gls = (ShaderImpl*)s; + return gls->GLShader; + } break; default: break; - } + } - return -1; + return -1; } void ShaderSet::SetShader(Shader *s) { Shaders[s->Stage] = s; - GLint GLShader = GetGLShader(s); + GLint GLShader = GetGLShader(s); glAttachShader(Prog, GLShader); if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment]) Link(); @@ -291,9 +170,9 @@ void ShaderSet::SetShader(Shader *s) void ShaderSet::UnsetShader(int stage) { if (Shaders[stage] == NULL) - return; + return; - GLint GLShader = GetGLShader(Shaders[stage]); + GLint GLShader = GetGLShader(Shaders[stage]); glDetachShader(Prog, GLShader); Shaders[stage] = NULL; @@ -342,9 +221,9 @@ bool ShaderSet::Link() LightingVer = 0; UsesLighting = 0; - GLint uniformCount = 0; - glGetProgramiv(Prog, GL_ACTIVE_UNIFORMS, &uniformCount); - OVR_ASSERT(uniformCount >= 0); + GLint uniformCount = 0; + glGetProgramiv(Prog, GL_ACTIVE_UNIFORMS, &uniformCount); + OVR_ASSERT(uniformCount >= 0); for(GLuint i = 0; i < (GLuint)uniformCount; i++) { @@ -454,10 +333,10 @@ void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize) UniformData = (unsigned char*)OVR_ALLOC(UniformsSize); } -Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(true), pParams(rp), TexId(0), Width(w), Height(h) +Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(false), pParams(rp), TexId(0), Width(w), Height(h) { - if (w && h) - glGenTextures(1, &TexId); + if (w && h) + glGenTextures(1, &TexId); } Texture::~Texture() @@ -468,8 +347,8 @@ Texture::~Texture() void Texture::Set(int slot, ShaderStage) const { - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(GL_TEXTURE_2D, TexId); + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_2D, TexId); } void Texture::SetSampleMode(int sm) @@ -480,18 +359,21 @@ void Texture::SetSampleMode(int sm) case Sample_Linear: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if(GLE_EXT_texture_filter_anisotropic) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); break; case Sample_Anisotropic: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if(GLE_EXT_texture_filter_anisotropic) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8); break; case Sample_Nearest: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + if(GLE_EXT_texture_filter_anisotropic) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); break; } @@ -517,14 +399,173 @@ void Texture::SetSampleMode(int sm) void Texture::UpdatePlaceholderTexture(GLuint texId, const Sizei& textureSize) { - if (!IsUserAllocated && TexId && texId != TexId) - glDeleteTextures(1, &TexId); + if (!IsUserAllocated && TexId && texId != TexId) + glDeleteTextures(1, &TexId); TexId = texId; - Width = textureSize.w; - Height = textureSize.h; + Width = textureSize.w; + Height = textureSize.h; + + IsUserAllocated = true; +} + + + + + +Context::Context() : initialized(false), ownsContext(true), incarnation(0) +{ +#if defined(OVR_OS_MAC) + systemContext = 0; +#elif defined(OVR_OS_WIN32) + hdc = 0; + systemContext = 0; +#elif defined(OVR_OS_LINUX) + x11Display = NULL; + x11Drawable = 0; + systemContext = 0; + memset(&x11Visual, 0, sizeof(x11Visual)); +#endif + +} + +void Context::InitFromCurrent() +{ + Destroy(); + + 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); + } + +#elif defined(OVR_OS_WIN32) + hdc = wglGetCurrentDC(); + systemContext = wglGetCurrentContext(); +#elif defined(OVR_OS_LINUX) + x11Display = glXGetCurrentDisplay(); + x11Drawable = glXGetCurrentDrawable(); + systemContext = glXGetCurrentContext(); + if (!SDKWindow::getVisualFromDrawable(x11Drawable, &x11Visual)) + { + OVR::LogError("[Context] Unable to obtain x11 visual from context"); + memset(&x11Visual, 0, sizeof(x11Visual)); + } +#endif +} + + +void Context::CreateShared( Context & ctx ) +{ + Destroy(); + OVR_ASSERT( ctx.initialized == true ); + if( ctx.initialized == false ) + { + return; + } - IsUserAllocated = true; + 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); + SetSurface(ctx); +#elif defined(OVR_OS_WIN32) + hdc = ctx.hdc; + systemContext = wglCreateContext( ctx.hdc ); + BOOL success = wglShareLists(ctx.systemContext, systemContext ); + OVR_ASSERT( success == TRUE ); + OVR_UNUSED(success); +#elif defined(OVR_OS_LINUX) + x11Display = ctx.x11Display; + x11Drawable = ctx.x11Drawable; + x11Visual = ctx.x11Visual; + systemContext = glXCreateContext( ctx.x11Display, &x11Visual, ctx.systemContext, True ); + OVR_ASSERT( systemContext != NULL ); +#endif +} + +#if defined(OVR_OS_MAC) +void Context::SetSurface( Context & ctx ) { + CGLError e = kCGLNoError; + CGSConnectionID cid, cid2; + CGSWindowID wid, wid2; + CGSSurfaceID sid, sid2; + + e = CGLGetSurface(ctx.systemContext, &cid, &wid, &sid); + OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e); + e = CGLGetSurface(systemContext, &cid2, &wid2, &sid2); + OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e); + if( sid && sid != sid2 ) { + e = CGLSetSurface(systemContext, cid, wid, sid); + OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e); + } +} +#endif + +void Context::Destroy() +{ + if( initialized == false ) + { + return; + } + + if (systemContext) + { +#if defined(OVR_OS_MAC) + CGLDestroyContext( systemContext ); +#elif defined(OVR_OS_WIN32) + BOOL success = wglDeleteContext( systemContext ); + OVR_ASSERT( success == TRUE ); + OVR_UNUSED( success ); +#elif defined(OVR_OS_LINUX) + glXDestroyContext( x11Display, systemContext ); +#endif + + systemContext = NULL; + } + + initialized = false; + ownsContext = true; +} + +void Context::Bind() +{ + if(systemContext) + { +#if defined(OVR_OS_MAC) + glFlush(); //Apple doesn't automatically flush within CGLSetCurrentContext, unlike other platforms. + CGLSetCurrentContext( systemContext ); +#elif defined(OVR_OS_WIN32) + wglMakeCurrent( hdc, systemContext ); +#elif defined(OVR_OS_LINUX) + glXMakeCurrent( x11Display, x11Drawable, systemContext ); +#endif + } +} + +void Context::Unbind() +{ +#if defined(OVR_OS_MAC) + glFlush(); //Apple doesn't automatically flush within CGLSetCurrentContext, unlike other platforms. + CGLSetCurrentContext( NULL ); +#elif defined(OVR_OS_WIN32) + wglMakeCurrent( hdc, NULL ); +#elif defined(OVR_OS_LINUX) + glXMakeCurrent( x11Display, None, NULL ); +#endif } -}}} +}}} // namespace OVR::CAPI::GL diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h index a410f17..69d4d08 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h @@ -5,15 +5,18 @@ Content : Utility header for OpenGL Created : March 27, 2014 Authors : Andrew Reisse, David Borel -Copyright : Copyright 2012 Oculus VR, Inc. 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, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. -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 +http://www.oculusvr.com/licenses/LICENSE-3.2 -Unless required by applicable law or agreed to in writing, software +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 @@ -33,124 +36,30 @@ limitations under the License. #include "../../Kernel/OVR_Log.h" #if defined(OVR_OS_WIN32) +#define WIN32_LEAN_AND_MEAN #include #endif -#if defined(OVR_OS_MAC) -#include -#include -#else -#ifndef GL_GLEXT_PROTOTYPES -#define GL_GLEXT_PROTOTYPES -#endif -#include -#include -#if defined(OVR_OS_WIN32) -#include -#elif defined(OVR_OS_LINUX) -#include -#endif +#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. #endif -namespace OVR { namespace CAPI { namespace GL { -// GL extension Hooks for Non-Mac. -#if !defined(OVR_OS_MAC) - -// Let Windows apps build without linking GL. -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MAC) + #include + #include +#endif -typedef void (__stdcall *PFNGLENABLEPROC) (GLenum); -typedef void (__stdcall *PFNGLDISABLEPROC) (GLenum); -typedef void (__stdcall *PFNGLGETFLOATVPROC) (GLenum, GLfloat*); -typedef const GLubyte * (__stdcall *PFNGLGETSTRINGPROC) (GLenum); -typedef void (__stdcall *PFNGLGETINTEGERVPROC) (GLenum, GLint*); -typedef PROC (__stdcall *PFNWGLGETPROCADDRESS) (LPCSTR); -typedef void (__stdcall *PFNGLFLUSHPROC) (); -typedef void (__stdcall *PFNGLFINISHPROC) (); -typedef void (__stdcall *PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (__stdcall *PFNGLCLEARPROC) (GLbitfield); -typedef void (__stdcall *PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -typedef void (__stdcall *PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); -typedef void (__stdcall *PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); -typedef void (__stdcall *PFNGLDELETETEXTURESPROC) (GLsizei n, GLuint *textures); -typedef void (__stdcall *PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); -typedef void (__stdcall *PFNGLCLEARCOLORPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a); -typedef void (__stdcall *PFNGLCLEARDEPTHPROC) (GLclampd depth); -typedef void (__stdcall *PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); -typedef void (__stdcall *PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); - -extern PFNWGLGETPROCADDRESS wglGetProcAddress; -extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; -extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; - -extern PFNGLENABLEPROC glEnable; -extern PFNGLDISABLEPROC glDisable; -extern PFNGLCOLORMASKPROC glColorMask; -extern PFNGLGETFLOATVPROC glGetFloatv; -extern PFNGLGETSTRINGPROC glGetString; -extern PFNGLGETINTEGERVPROC glGetIntegerv; -extern PFNGLCLEARPROC glClear; -extern PFNGLCLEARCOLORPROC glClearColor; -extern PFNGLCLEARDEPTHPROC glClearDepth; -extern PFNGLVIEWPORTPROC glViewport; -extern PFNGLDRAWARRAYSPROC glDrawArrays; -extern PFNGLDRAWELEMENTSPROC glDrawElements; -extern PFNGLGENTEXTURESPROC glGenTextures; -extern PFNGLDELETETEXTURESPROC glDeleteTextures; -extern PFNGLBINDTEXTUREPROC glBindTexture; -extern PFNGLTEXPARAMETERIPROC glTexParameteri; -extern PFNGLFLUSHPROC glFlush; -extern PFNGLFINISHPROC glFinish; -#elif defined(OVR_OS_LINUX) +namespace OVR +{ + // Get the shared LibOVR GLEContext instance. + class GLEContext; + GLEContext* GetGLEContext(); +} -extern PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; - -#endif // defined(OVR_OS_WIN32) - -extern PFNGLDELETESHADERPROC glDeleteShader; -extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -extern PFNGLACTIVETEXTUREPROC glActiveTexture; -extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -extern PFNGLBINDBUFFERPROC glBindBuffer; -extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; -extern PFNGLBUFFERDATAPROC glBufferData; -extern PFNGLGENBUFFERSPROC glGenBuffers; -extern PFNGLMAPBUFFERPROC glMapBuffer; -extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; -extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -extern PFNGLGETSHADERIVPROC glGetShaderiv; -extern PFNGLCOMPILESHADERPROC glCompileShader; -extern PFNGLSHADERSOURCEPROC glShaderSource; -extern PFNGLCREATESHADERPROC glCreateShader; -extern PFNGLCREATEPROGRAMPROC glCreateProgram; -extern PFNGLATTACHSHADERPROC glAttachShader; -extern PFNGLDETACHSHADERPROC glDetachShader; -extern PFNGLDELETEPROGRAMPROC glDeleteProgram; -extern PFNGLUNIFORM1IPROC glUniform1i; -extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; -extern PFNGLUSEPROGRAMPROC glUseProgram; -extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; -extern PFNGLGETPROGRAMIVPROC glGetProgramiv; -extern PFNGLLINKPROGRAMPROC glLinkProgram; -extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; -extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; -extern PFNGLUNIFORM4FVPROC glUniform4fv; -extern PFNGLUNIFORM3FVPROC glUniform3fv; -extern PFNGLUNIFORM2FVPROC glUniform2fv; -extern PFNGLUNIFORM1FVPROC glUniform1fv; -extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; -extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; -extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; - -extern void InitGLExtensions(); - -#endif // !defined(OVR_OS_MAC) +namespace OVR { namespace CAPI { namespace GL { +void InitGLExtensions(); // Rendering primitive type used to render Model. @@ -223,12 +132,12 @@ struct RenderParams { #if defined(OVR_OS_WIN32) HWND Window; + HDC DC; #elif defined(OVR_OS_LINUX) - Display* Disp; - Window Win; + struct _XDisplay* Disp; #endif - ovrSizei RTSize; + ovrSizei BackBufferSize; int Multisample; }; @@ -314,6 +223,8 @@ protected: String Name; int Location, Size; int Type; // currently number of floats in vector + + Uniform() : Name(), Location(0), Size(0), Type(0){} }; Array UniformInfo; @@ -377,6 +288,14 @@ public: return SetUniform(name, 16, &mt.M[0][0]); } + virtual bool SetUniform3x3f(const char* name, const Matrix4f& m) + { + Matrix4f mt = m.Transposed(); + // float3x3 is actually stored the same way as float4x3, with the last items ignored by the code. + return SetUniform(name, 12, &mt.M[0][0]); + } + + protected: GLint GetGLShader(Shader* s); bool Link(); @@ -456,17 +375,33 @@ public: struct Uniform { const char* Name; - VarType Type; - int Offset, Size; + VarType Type; + int Offset; + int Size; }; - const Uniform* UniformRefl; - size_t UniformReflSize; - ShaderBase(RenderParams* rp, ShaderStage stage) : Shader(stage), pParams(rp), UniformData(0), UniformsSize(0) {} + const Uniform* UniformRefl; + size_t UniformReflSize; + + ShaderBase(RenderParams* rp, ShaderStage stage) : + Shader(stage), + pParams(rp), + UniformData(NULL), + UniformsSize(0), + UniformRefl(NULL), + UniformReflSize(0) + { + } ~ShaderBase() { - if (UniformData) - OVR_FREE(UniformData); + if (UniformData) + { + OVR_FREE(UniformData); + UniformData = NULL; + } + + // Do not need to free UniformRefl + UniformRefl = NULL; } void InitUniforms(const Uniform* refl, size_t reflSize); @@ -489,6 +424,7 @@ public: OVR_UNUSED(size); success = Compile((const char*) s); OVR_ASSERT(success); + OVR_UNUSED(success); InitUniforms(refl, reflSize); } ~ShaderImpl() @@ -532,6 +468,86 @@ private: typedef ShaderImpl VertexShader; typedef ShaderImpl FragmentShader; -}}} + + +// Allows us to have independent OpenGL contexts for our systems. +class Context +{ + bool initialized; + bool ownsContext; + int incarnation; +#if defined(OVR_OS_WIN32) + HDC hdc; + HGLRC systemContext; +#elif defined(OVR_OS_LINUX) + Display *x11Display; + GLXDrawable x11Drawable; + GLXContext systemContext; + XVisualInfo x11Visual; +#elif defined(OVR_OS_MAC) + CGLContextObj systemContext; +#endif + +public: + + Context(); + void InitFromCurrent(); + void CreateShared( Context & ctx ); +#if defined(OVR_OS_MAC) + void SetSurface( Context & ctx ); +#endif + void Destroy(); + void Bind(); + void Unbind(); + int GetIncarnation() const { return incarnation; } + +}; + + +// AutoContext +// +// Implements a common sequence of function calls with the Context class. +// See the AutoContext constructor below for what it does. +// +// Example usage: +// void SomeClass::Draw() +// { +// AutoContext autoContext(someClassContext); +// +// +// } + +struct AutoContext +{ + Context savedCurrentContext; + Context& ourContext; + + AutoContext(Context& context) : + savedCurrentContext(), ourContext(context) + { + // We use a member savedCurrentContext which is initialized here, as opposed to having the user pass in a + // pre-existing Context (which the user could declare as a global or C++ member variable). We have to do this + // because if we were to use some pre-existing Context the app might delete its underlying GL context behind our back + // or associate it with another thread, which would cause our bind of it in our dtor to be a bad operation. + savedCurrentContext.InitFromCurrent(); + if(ourContext.GetIncarnation() == 0) // If not yet initialized... + ourContext.CreateShared(savedCurrentContext); + ourContext.Bind(); + #if defined(OVR_OS_MAC) // To consider: merge the following into the Bind function. + ourContext.SetSurface(savedCurrentContext); + #endif + } + + ~AutoContext() + { + savedCurrentContext.Bind(); + } + + OVR_NON_COPYABLE(AutoContext) +}; + + +}}} // namespace OVR::CAPI::GL + #endif // INC_OVR_CAPI_GL_Util_h diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h deleted file mode 100644 index 991f9ad..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef DISTORTIONCHROMA_PS_H -#define DISTORTIONCHROMA_PS_H - -static const unsigned char DistortionChroma_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0xf8, 0x80, 0xa6, 0xb4, 0xd3, 0xf2, 0xe4, 0x8b, - 0xd1, 0x64, 0x65, 0x3a, 0x55, 0xe3, 0xdf, 0xc9, 0x01, 0x00, 0x00, 0x00, - 0x90, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0xdc, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00, - 0x14, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xa0, 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, 0x36, 0x2e, - 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, - 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, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0f, 0x07, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x07, 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, 0x58, 0x01, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x56, 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, 0x72, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x00, 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, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x12, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 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, 0x38, 0x00, 0x00, 0x07, 0x22, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 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, 0x00, 0x00, 0x07, 0x42, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2a, 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, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 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, 0x03, 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/Shaders/DistortionChroma_ps.psh b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh deleted file mode 100644 index 768d491..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh +++ /dev/null @@ -1,12 +0,0 @@ -Texture2D Texture : register(t0); -SamplerState Linear : register(s0); - -float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR, - in float3 oTexCoord0 : TEXCOORD0, in float3 oTexCoord1 : TEXCOORD1, in float3 oTexCoord2 : TEXCOORD2) : SV_Target -{ - float ResultR = Texture.SampleLevel(Linear, oTexCoord0.xy, 0.0).r; - float ResultG = Texture.SampleLevel(Linear, oTexCoord1.xy, 0.0).g; - float ResultB = Texture.SampleLevel(Linear, oTexCoord2.xy, 0.0).b; - return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0); - //" return oColor.rrrr; -} diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h deleted file mode 100644 index a306aa5..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h +++ /dev/null @@ -1 +0,0 @@ -// No data available for shader reflection DistortionChroma_ps_refl \ No newline at end of file diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h deleted file mode 100644 index 56c5e2e..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef DISTORTIONCHROMA_VS_H -#define DISTORTIONCHROMA_VS_H - -static const unsigned char DistortionChroma_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0xaf, 0x53, 0xeb, 0x12, 0x64, 0x0d, 0xd1, 0xaa, - 0x9c, 0x9d, 0x13, 0x42, 0x57, 0x7b, 0x4c, 0xb4, 0x01, 0x00, 0x00, 0x00, - 0xa0, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x38, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x7c, 0x02, 0x00, 0x00, - 0x24, 0x04, 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, 0x36, 0x2e, 0x33, 0x2e, 0x39, - 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 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, 0x0f, 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, 0x0f, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x07, 0x08, 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, 0xa0, 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x68, 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, 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, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x04, 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, 0xf2, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 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, 0x02, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x42, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x32, 0x00, 0x00, 0x0b, 0x32, 0x20, 0x10, 0x00, - 0x03, 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, - 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x32, 0x00, 0x00, 0x0b, - 0x32, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x03, 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, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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/Shaders/DistortionChroma_vs.vsh b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.vsh deleted file mode 100644 index bd154a0..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.vsh +++ /dev/null @@ -1,24 +0,0 @@ -float2 EyeToSourceUVScale; -float2 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 float4 oColor : COLOR, out float3 oTexCoord0 : TEXCOORD0, - out float3 oTexCoord1 : TEXCOORD1, out float3 oTexCoord2 : TEXCOORD2) -{ - oPosition.x = Position.x; - oPosition.y = Position.y; - oPosition.z = 0.5; - oPosition.w = 1.0; - - // Scale them into UV lookup space - float2 tc0scaled = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; - float2 tc1scaled = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; - float2 tc2scaled = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; - - oTexCoord0 = float3(tc0scaled, 1); // R sample. - oTexCoord1 = float3(tc1scaled, 1); // G sample. - oTexCoord2 = float3(tc2scaled, 1); // B sample. - oColor = Color; // Used for vignette fade. -} - diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs_refl.h deleted file mode 100644 index 7feb789..0000000 --- a/LibOVR/Src/CAPI/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/Shaders/DistortionTimewarpChroma_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h deleted file mode 100644 index 74b12e2..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef DISTORTIONTIMEWARPCHROMA_VS_H -#define DISTORTIONTIMEWARPCHROMA_VS_H - -static const unsigned char DistortionTimewarpChroma_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0x03, 0x43, 0xb6, 0xcd, 0xb7, 0xe5, 0xeb, 0x34, - 0x11, 0x77, 0xf9, 0xfc, 0x49, 0xa0, 0x5a, 0x69, 0x01, 0x00, 0x00, 0x00, - 0xec, 0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x9c, 0x01, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x00, - 0x70, 0x09, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x60, 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, 0x36, 0x2e, - 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, - 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, 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, 0x0f, 0x00, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x08, 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, 0x88, 0x06, 0x00, 0x00, - 0x40, 0x00, 0x01, 0x00, 0xa2, 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, 0xf2, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, - 0x04, 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, 0xf2, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 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, 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, - 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa6, 0x0a, 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, 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, 0x03, 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, 0x42, 0x20, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 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, 0x12, 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, - 0x22, 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, 0x46, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0x32, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x00, 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, 0x42, 0x20, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x20, 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, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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/Shaders/DistortionTimewarpChroma_vs.vsh b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.vsh deleted file mode 100644 index 9650b7e..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.vsh +++ /dev/null @@ -1,40 +0,0 @@ -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.xy, 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, - in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, - out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float3 oTexCoord0 : TEXCOORD0, - out float3 oTexCoord1 : TEXCOORD1, out float3 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); - //" float4x4 lerpedEyeRot = EyeRotationStart; - - // warped positions are a bit more involved, hence a separate function - oTexCoord0 = float3(TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot), 1); - oTexCoord1 = float3(TimewarpTexCoordToWarpedPos(TexCoord1, lerpedEyeRot), 1); - oTexCoord2 = float3(TimewarpTexCoordToWarpedPos(TexCoord2, lerpedEyeRot), 1); - - oColor = Color.r; // Used for vignette fade. -} diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs_refl.h deleted file mode 100644 index 38a168f..0000000 --- a/LibOVR/Src/CAPI/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/Shaders/DistortionTimewarp_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h deleted file mode 100644 index 290f13f..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef DISTORTIONTIMEWARP_VS_H -#define DISTORTIONTIMEWARP_VS_H - -static const unsigned char DistortionTimewarp_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0xef, 0x5d, 0x05, 0x24, 0x51, 0x13, 0x68, 0xcf, - 0x6d, 0x7a, 0xa5, 0x09, 0x84, 0xf9, 0x6c, 0xfc, 0x01, 0x00, 0x00, 0x00, - 0x94, 0x07, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x9c, 0x01, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, - 0x18, 0x07, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x60, 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, 0x36, 0x2e, - 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, - 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, 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, 0x0f, 0x00, 0x00, 0x00, - 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x08, 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, 0x90, 0x04, 0x00, 0x00, - 0x40, 0x00, 0x01, 0x00, 0x24, 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, 0xf2, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 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, 0xf2, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 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, 0x22, 0x00, 0x10, 0x00, - 0x02, 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, 0x12, 0x00, 0x10, 0x00, 0x02, 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, 0x46, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x00, 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, 0x42, 0x20, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x16, 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, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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/Shaders/DistortionTimewarp_vs.vsh b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.vsh deleted file mode 100644 index cf41ec0..0000000 --- a/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.vsh +++ /dev/null @@ -1,36 +0,0 @@ -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 float4 oColor : COLOR, out float3 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 = float3(TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot), 1); - oColor = Color.r; // Used for vignette fade. -} - - diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs_refl.h deleted file mode 100644 index eab6baf..0000000 --- a/LibOVR/Src/CAPI/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/Shaders/Distortion_ps.h b/LibOVR/Src/CAPI/Shaders/Distortion_ps.h deleted file mode 100644 index 870805e..0000000 --- a/LibOVR/Src/CAPI/Shaders/Distortion_ps.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef DISTORTION_PS_H -#define DISTORTION_PS_H - -static const unsigned char Distortion_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0xc9, 0x40, 0x1a, 0xf6, 0x24, 0x65, 0x62, 0xf5, - 0x0a, 0x75, 0x65, 0xc3, 0x5e, 0x8d, 0xb8, 0x56, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0xdc, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, - 0x3c, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xa0, 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, 0x36, 0x2e, - 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, - 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, 0x07, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x07, 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, 0xb0, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x2c, 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, 0x72, 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, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x00, 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, 0x01, 0x40, 0x00, 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, - 0x46, 0x12, 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, - 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 - -}; - -#endif diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh b/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh deleted file mode 100644 index 3e8b87f..0000000 --- a/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh +++ /dev/null @@ -1,9 +0,0 @@ -Texture2D Texture : register(t0); -SamplerState Linear : register(s0); - -float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR, - in float3 oTexCoord0 : TEXCOORD0) : SV_Target -{ - float3 Result = Texture.SampleLevel(Linear, oTexCoord0.xy, 0.0).rgb; - return float4(Result.r * oColor.r, Result.g * oColor.g, Result.b * oColor.b, 1.0); -} diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_ps_refl.h b/LibOVR/Src/CAPI/Shaders/Distortion_ps_refl.h deleted file mode 100644 index 8a613f5..0000000 --- a/LibOVR/Src/CAPI/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/Shaders/Distortion_vs.h b/LibOVR/Src/CAPI/Shaders/Distortion_vs.h deleted file mode 100644 index ef43903..0000000 --- a/LibOVR/Src/CAPI/Shaders/Distortion_vs.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef DISTORTION_VS_H -#define DISTORTION_VS_H - -static const unsigned char Distortion_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0x69, 0x55, 0x09, 0xe1, 0x88, 0x43, 0xa7, 0xcb, - 0xe6, 0xdf, 0x06, 0x37, 0x5b, 0xc1, 0x8c, 0xa1, 0x01, 0x00, 0x00, 0x00, - 0x90, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x38, 0x01, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, - 0x14, 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, 0x36, 0x2e, 0x33, 0x2e, 0x39, - 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 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, 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, 0x07, 0x08, 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, 0xf0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x3c, 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, 0x72, 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, 0xf2, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 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, 0x02, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x42, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, - 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 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, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -}; - -#endif diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh b/LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh deleted file mode 100644 index ddf65e3..0000000 --- a/LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh +++ /dev/null @@ -1,14 +0,0 @@ -float2 EyeToSourceUVScale; -float2 EyeToSourceUVOffset; - -void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0, - out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float3 oTexCoord0 : TEXCOORD0) -{ - oPosition.x = Position.x; - oPosition.y = Position.y; - oPosition.z = 0.5; - oPosition.w = 1.0; - oTexCoord0 = float3(EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset, 1); - oColor = Color; // Used for vignette fade. -} - diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_vs_refl.h b/LibOVR/Src/CAPI/Shaders/Distortion_vs_refl.h deleted file mode 100644 index b3e86ac..0000000 --- a/LibOVR/Src/CAPI/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/Shaders/ShaderReflector.exe b/LibOVR/Src/CAPI/Shaders/ShaderReflector.exe deleted file mode 100644 index 7cabde8..0000000 Binary files a/LibOVR/Src/CAPI/Shaders/ShaderReflector.exe and /dev/null differ diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h deleted file mode 100644 index f492ad1..0000000 --- a/LibOVR/Src/CAPI/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, 0xc5, 0x64, 0xa2, 0x55, 0x15, 0x24, 0x7d, 0xe6, - 0x27, 0xd2, 0xf4, 0x4e, 0x42, 0xb6, 0xba, 0x78, 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, 0x36, - 0x2e, 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, - 0x34, 0x00, 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/Shaders/SimpleQuad_ps.psh b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.psh deleted file mode 100644 index a98329b..0000000 --- a/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.psh +++ /dev/null @@ -1,6 +0,0 @@ -float4 Color; - -float4 main() : SV_Target -{ - return Color; -} diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps_refl.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps_refl.h deleted file mode 100644 index 7980b65..0000000 --- a/LibOVR/Src/CAPI/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/Shaders/SimpleQuad_vs.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h deleted file mode 100644 index 0f27754..0000000 --- a/LibOVR/Src/CAPI/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, 0xb2, 0x87, 0xff, 0xa1, 0x41, 0xd7, 0x0e, 0x94, - 0x59, 0xd6, 0x1b, 0x8c, 0x94, 0x3d, 0xb9, 0x46, 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, 0x36, 0x2e, 0x33, 0x2e, 0x39, - 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 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, 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, 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/Shaders/SimpleQuad_vs.vsh b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.vsh deleted file mode 100644 index d5961a5..0000000 --- a/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.vsh +++ /dev/null @@ -1,8 +0,0 @@ -float2 PositionOffset = float2(0, 0); -float2 Scale = float2(1, 1); - -void main( in float3 Position : POSITION, -out float4 oPosition : SV_Position) -{ - oPosition = float4(Position.xy * Scale + PositionOffset, 0.5, 1.0); -} \ No newline at end of file diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs_refl.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs_refl.h deleted file mode 100644 index 23bb021..0000000 --- a/LibOVR/Src/CAPI/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/Shaders/bin2header.exe b/LibOVR/Src/CAPI/Shaders/bin2header.exe deleted file mode 100644 index b3f8d10..0000000 Binary files a/LibOVR/Src/CAPI/Shaders/bin2header.exe and /dev/null differ diff --git a/LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat b/LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat deleted file mode 100644 index 76f17c2..0000000 --- a/LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat +++ /dev/null @@ -1,15 +0,0 @@ -@echo off -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 -bin2header.exe "%1" - -echo Generating shader reflection data for %1 -ShaderReflector "%1" "%1_refl.h" - -del "%1" -endlocal -popd diff --git a/LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat b/LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat deleted file mode 100644 index 7085775..0000000 --- a/LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat +++ /dev/null @@ -1,15 +0,0 @@ -@echo off -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 -bin2header.exe "%1" - -echo Generating shader reflection data for %1 -ShaderReflector "%1" "%1_refl.h" - -del "%1" -endlocal -popd diff --git a/LibOVR/Src/CAPI/Textures/healthAndSafety.tga.h b/LibOVR/Src/CAPI/Textures/healthAndSafety.tga.h new file mode 100644 index 0000000..74fd097 --- /dev/null +++ b/LibOVR/Src/CAPI/Textures/healthAndSafety.tga.h @@ -0,0 +1,3363 @@ +const uint8_t healthAndSafety_tga[107525] = { + 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x20,0x08,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc7,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd, + 0x9f,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0x00,0x00,0x00,0x00,0xb3,0x82,0x7e, + 0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x8c,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xc6,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0x9d,0x00, + 0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0xfc,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6, + 0x84,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x8a,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc6,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x9d,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xfb,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86, + 0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x89,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc6,0x00,0x00,0x00,0xb3,0x05,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xe6,0xe6, + 0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x9d,0x00,0x00,0x00,0xb3,0x05,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa, + 0xff,0xff,0xff,0xff,0xd2,0xd2,0xd2,0xe6,0xfc,0x00,0x00,0x00,0xb3,0x05,0xef,0xef,0xef,0xf5,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0, + 0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x88, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x96,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e, + 0xc7,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e, + 0x7e,0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd,0x89,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x91,0x00,0x00,0x00,0xb3,0x00, + 0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x95,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00, + 0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x8a,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7, + 0x00,0x33,0x33,0x33,0xb8,0x83,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x8b,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e, + 0x7e,0xc7,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x99,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81, + 0x7e,0x7e,0x7e,0xc7,0x9b,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7, + 0x86,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00, + 0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x00, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x01, + 0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x04,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0xef,0xef, + 0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x03,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x83,0xff,0xff,0xff,0xff,0x01,0xef,0xef, + 0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0x86,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xd2,0xd2,0xd2,0xe6,0x81,0xff, + 0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x88,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x04,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd, + 0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00, + 0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x81,0x00,0x00, + 0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x01,0x6a, + 0x6a,0x6a,0xc2,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0x81,0xff,0xff, + 0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3, + 0x01,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6, + 0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff, + 0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef, + 0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7, + 0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf, + 0xaf,0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x6a, + 0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x05,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xd2, + 0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x84,0x00,0x00, + 0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0x00, + 0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x87,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x33,0x33, + 0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00, + 0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x88,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd, + 0x84,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x85,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x86,0x00,0x00,0x00, + 0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf, + 0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0x00,0x00, + 0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x85,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x86,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xfe,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00, + 0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0xbb,0xbb,0xbb,0xdc,0x33,0x33, + 0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x03,0xa0,0xa0,0xa0,0xd1,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc, + 0xdc,0xeb,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e, + 0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff, + 0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7, + 0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00, + 0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xd2,0xd2, + 0xd2,0xe6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7, + 0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x85,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff, + 0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc, + 0xdc,0xeb,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81, + 0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff, + 0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff, + 0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xd2, + 0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0x7e, + 0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff, + 0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x02,0x6a, + 0x6a,0x6a,0xc2,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00, + 0xc7,0xc7,0xc7,0xe1,0x84,0xaf,0xaf,0xaf,0xd6,0x05,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7, + 0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x02,0x7e,0x7e,0x7e,0xc7,0xbb,0xbb,0xbb,0xdc,0xe6,0xe6,0xe6,0xf0,0x82,0xff, + 0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x90,0x90,0x90,0xcc, + 0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0xc7, + 0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x87,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81, + 0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf,0xd6, + 0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x01,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x01,0xff,0xff,0xff,0xff,0xc7,0xc7,0xc7, + 0xe1,0x87,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff, + 0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3, + 0x03,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6, + 0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x85,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xbb, + 0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff, + 0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x06,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa, + 0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xaf,0xaf,0xaf,0xd6,0x01,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef, + 0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82, + 0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff, + 0x03,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x84,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x86,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1, + 0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7, + 0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x86,0x00,0x00, + 0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb, + 0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xe6,0xe6, + 0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc, + 0x81,0xff,0xff,0xff,0xff,0x09,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xbb,0xbb, + 0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00, + 0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x04, + 0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00, + 0xb3,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x7e,0x7e,0x7e,0xc7, + 0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb, + 0xdc,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52, + 0xbd,0x88,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00, + 0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff, + 0xd2,0xd2,0xd2,0xe6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0, + 0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xd2, + 0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x04,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3, + 0x03,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x00,0xa0,0xa0,0xa0,0xd1,0x87,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x05,0xaf,0xaf, + 0xaf,0xd6,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8, + 0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x04,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x82, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x05,0x7e,0x7e, + 0x7e,0xc7,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0x52,0x52,0x52,0xbd,0xbb,0xbb,0xbb,0xdc, + 0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a,0x6a,0xc2, + 0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x05,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff, + 0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3, + 0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff, + 0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xc7,0xc7,0xc7,0xe1, + 0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0x7e, + 0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x0a,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6, + 0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x03,0x52,0x52,0x52,0xbd,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x08,0xaf,0xaf,0xaf,0xd6,0x52, + 0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82, + 0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x05,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7, + 0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x85, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0, + 0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff, + 0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x02,0xe6, + 0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x85,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7, + 0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xaf,0xaf,0xaf,0xd6,0x81, + 0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x05,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x01,0xdc, + 0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x01, + 0xd2,0xd2,0xd2,0xe6,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02, + 0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff, + 0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81, + 0xff,0xff,0xff,0xff,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x09,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7, + 0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x03,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x81, + 0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef, + 0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x0a,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6, + 0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x84,0xff,0xff,0xff, + 0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef, + 0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff, + 0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00, + 0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x08,0x00,0x00, + 0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xe6,0xe6, + 0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x84,0x00,0x00,0x00,0xb3,0x86,0xff,0xff,0xff,0xff,0x02,0x00, + 0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x86,0x00,0x00,0x00,0xb3,0x04,0x33,0x33,0x33,0xb8,0xf7, + 0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0xe6, + 0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xa0, + 0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83, + 0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0, + 0xd1,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2, + 0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7, + 0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7, + 0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01, + 0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x03,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0x81,0x00, + 0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x06, + 0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00, + 0xb3,0x01,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x86,0x00,0x00,0x00,0xb3,0x02,0x33,0x33, + 0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a, + 0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0xa0,0xa0,0xa0,0xd1,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x00,0x00, + 0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x02,0xd2,0xd2,0xd2,0xe6,0xdc,0xdc,0xdc,0xeb,0xc7,0xc7, + 0xc7,0xe1,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb, + 0x0b,0xd2,0xd2,0xd2,0xe6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7, + 0xfa,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00,0xb3, + 0x00,0x52,0x52,0x52,0xbd,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x01,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff, + 0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff, + 0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x06,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0xff,0xff, + 0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xd2,0xd2,0xd2,0xe6,0x52,0x52,0x52,0xbd,0x83,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff, + 0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0, + 0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x05,0xbb,0xbb,0xbb,0xdc,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7, + 0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5, + 0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x52,0x52, + 0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1, + 0x81,0xdc,0xdc,0xdc,0xeb,0x01,0x52,0x52,0x52,0xbd,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2, + 0xe6,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff, + 0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xc7, + 0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3, + 0x01,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7, + 0xca,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa0,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0xa5,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xaa,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x91,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0x93,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0xcb, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa0,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0xa5,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xaa,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x91,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0x93,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x87,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0xcb,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa0,0x00,0x00,0x00,0xb3,0x00,0x33, + 0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd,0xa5,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xaa,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x91,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x93,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0x01,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x85,0xdc,0xdc,0xdc,0xeb,0x01,0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52,0xbd,0xcc,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xca,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xaa,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x91,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x93,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd6,0x00,0x00, + 0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0xca,0x00,0x00,0x00,0xb3,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0xaa,0x00,0x00,0x00,0xb3, + 0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x91,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x93,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x8f,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb4,0xf1,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd6,0x00,0x00,0x00,0xb3,0xc3,0x00,0x00,0x00,0xb4,0xff,0x01,0x00,0x00,0xb4, + 0xdb,0x01,0x00,0x00,0xb4,0xc3,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0x82,0x00,0x00,0x00,0xb4,0x8b,0x00,0x00,0x00,0xb3,0x97,0x00,0x00,0x00,0xb4,0x92,0x01,0x00,0x00,0xb4,0x91,0x01,0x00,0x00, + 0xb5,0x8c,0x01,0x01,0x00,0xb5,0xff,0x01,0x01,0x01,0xb6,0xf3,0x01,0x01,0x01,0xb6,0x8c,0x01,0x01,0x00,0xb5,0x91,0x01,0x00,0x00,0xb5,0x92,0x01,0x00,0x00,0xb4,0x97, + 0x00,0x00,0x00,0xb4,0x8b,0x00,0x00,0x00,0xb3,0x82,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa3,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa8,0x00,0x00,0x00,0xb3,0x9b,0x00,0x00,0x00,0xb4,0x8e,0x01,0x00,0x00,0xb4,0x88,0x01,0x00,0x00,0xb5,0x81,0x01,0x01,0x00,0xb5, + 0x8f,0x01,0x01,0x01,0xb6,0x00,0x01,0x01,0x01,0xb7,0x8b,0x02,0x01,0x01,0xb7,0xa8,0x02,0x01,0x01,0xb8,0x00,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0x82,0x02, + 0x02,0x01,0xb9,0x82,0x03,0x02,0x01,0xb9,0x83,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01, + 0xb9,0x00,0x03,0x02,0x01,0xb9,0x85,0x02,0x02,0x01,0xb9,0x02,0x03,0x02,0x01,0xb9,0x02,0x02,0x01,0xb9,0x03,0x02,0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x00,0x03,0x02, + 0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x04,0x03,0x02,0x01,0xb9,0x02,0x02,0x01,0xb9,0x03,0x02,0x01,0xb9,0x02,0x02, + 0x01,0xb9,0x03,0x02,0x01,0xb9,0x84,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x83,0x02,0x02,0x01,0xb9,0x00, + 0x03,0x02,0x01,0xb9,0x85,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x83,0x02,0x02,0x01,0xb9,0x00,0x03,0x02, + 0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0x02,0x02,0x02,0x01,0xb9,0x03,0x02,0x01,0xb9,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0x81,0x02, + 0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x8d,0x02,0x02,0x01,0xb9,0x01,0x03,0x02,0x01,0xb9,0x02,0x02,0x01,0xb9, + 0x81,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x87,0x02,0x02,0x01,0xb9,0x81,0x03, + 0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x83,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x87,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01, + 0xb9,0x85,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x85,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x84, + 0x02,0x02,0x01,0xb9,0x82,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x01,0x03,0x02,0x01,0xb9,0x02,0x02,0x01, + 0xb9,0x82,0x03,0x02,0x01,0xb9,0x83,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x8b,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x8d, + 0x02,0x01,0x01,0xb8,0x00,0x02,0x02,0x01,0xb8,0x90,0x02,0x01,0x01,0xb8,0x00,0x02,0x02,0x01,0xb8,0x87,0x02,0x01,0x01,0xb8,0x8b,0x02,0x01,0x01,0xb7,0x00,0x01,0x01, + 0x01,0xb7,0x8f,0x01,0x01,0x01,0xb6,0x81,0x01,0x01,0x00,0xb5,0x88,0x01,0x00,0x00,0xb5,0x8e,0x01,0x00,0x00,0xb4,0x9b,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0x96,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa6,0x00,0x00,0x00,0xb3,0x91,0x00,0x00,0x00,0xb4,0x87,0x01, + 0x00,0x00,0xb4,0x85,0x01,0x00,0x00,0xb5,0x88,0x01,0x01,0x00,0xb5,0x86,0x01,0x01,0x01,0xb6,0x81,0x01,0x01,0x01,0xb7,0x86,0x02,0x01,0x01,0xb7,0x83,0x02,0x01,0x01, + 0xb8,0x00,0x02,0x02,0x01,0xb8,0x86,0x02,0x01,0x01,0xb8,0x83,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0x89,0x03,0x02,0x01,0xba,0x82,0x03,0x02,0x02,0xbb,0x00, + 0x03,0x02,0x01,0xbb,0x8c,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x02,0xbc,0x8d,0x04,0x02,0x02,0xbc,0xff,0x04,0x03,0x02,0xbd,0xd9,0x04,0x03,0x02,0xbd,0x85,0x04,0x02, + 0x02,0xbc,0x00,0x04,0x03,0x02,0xbc,0x86,0x04,0x02,0x02,0xbc,0x00,0x03,0x02,0x02,0xbc,0x87,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0x87,0x03,0x02,0x02,0xbb, + 0x89,0x03,0x02,0x01,0xba,0x00,0x03,0x02,0x01,0xb9,0x84,0x02,0x02,0x01,0xb9,0x8b,0x02,0x01,0x01,0xb8,0x86,0x02,0x01,0x01,0xb7,0x81,0x01,0x01,0x01,0xb7,0x86,0x01, + 0x01,0x01,0xb6,0x88,0x01,0x01,0x00,0xb5,0x85,0x01,0x00,0x00,0xb5,0x87,0x01,0x00,0x00,0xb4,0x91,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0x94,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x9d,0x00,0x00,0x00,0xb3,0x92,0x00,0x00,0x00,0xb4,0x88,0x01,0x00,0x00,0xb4,0x84, + 0x01,0x00,0x00,0xb5,0x86,0x01,0x01,0x00,0xb5,0x83,0x01,0x01,0x01,0xb6,0x01,0x02,0x01,0x01,0xb7,0x01,0x01,0x01,0xb7,0x85,0x02,0x01,0x01,0xb7,0x86,0x02,0x01,0x01, + 0xb8,0x82,0x02,0x02,0x01,0xb9,0x82,0x03,0x02,0x01,0xb9,0x83,0x03,0x02,0x01,0xba,0x00,0x03,0x02,0x01,0xbb,0x82,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0x83, + 0x03,0x02,0x02,0xbb,0x81,0x03,0x02,0x02,0xbc,0x01,0x04,0x02,0x02,0xbc,0x03,0x02,0x02,0xbc,0x84,0x04,0x02,0x02,0xbc,0x88,0x04,0x03,0x02,0xbd,0x01,0x04,0x03,0x02, + 0xbe,0x05,0x03,0x02,0xbe,0x85,0x04,0x03,0x02,0xbe,0x00,0x04,0x03,0x02,0xbf,0x85,0x05,0x03,0x02,0xbf,0x85,0x05,0x03,0x02,0xc0,0x00,0x05,0x04,0x01,0xc0,0x81,0x05, + 0x03,0x02,0xc0,0x00,0x05,0x03,0x03,0xc0,0x8d,0x05,0x04,0x03,0xc0,0x00,0x06,0x04,0x03,0xc1,0x83,0x05,0x04,0x03,0xc1,0x02,0x06,0x04,0x03,0xc1,0x05,0x04,0x03,0xc1, + 0x05,0x04,0x01,0xc1,0x81,0x05,0x04,0x03,0xc1,0x81,0x06,0x04,0x03,0xc1,0x05,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x05, + 0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x82,0x05,0x04,0x03,0xc1,0x00,0x05,0x04,0x01,0xc1,0x81,0x05,0x04,0x03,0xc1,0x00,0x06,0x04,0x03,0xc1,0x83,0x05,0x04,0x03,0xc1, + 0x00,0x06,0x04,0x03,0xc1,0x83,0x05,0x04,0x03,0xc1,0x00,0x05,0x04,0x01,0xc1,0x81,0x05,0x04,0x03,0xc1,0x00,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc1,0x02,0x06, + 0x04,0x03,0xc1,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc1,0x02,0x06,0x04,0x03,0xc1,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x82,0x05,0x04, + 0x03,0xc1,0x00,0x06,0x04,0x03,0xc1,0x82,0x05,0x04,0x03,0xc1,0xd9,0x06,0x04,0x03,0xc2,0x05,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x05,0x04,0x03,0xc1,0x06,0x04, + 0x03,0xc1,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x83,0x05,0x04,0x03,0xc1,0x02,0x06,0x04,0x03,0xc1,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03, + 0xc1,0x00,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc1,0x00,0x06,0x04,0x03,0xc1,0x82,0x05,0x04,0x03,0xc1,0x00,0x06,0x04,0x03,0xc1,0x82,0x05,0x04,0x03,0xc1,0x01, + 0x05,0x04,0x01,0xc1,0x05,0x04,0x03,0xc1,0x82,0x06,0x04,0x03,0xc1,0x00,0x05,0x04,0x03,0xc1,0x81,0x06,0x04,0x03,0xc1,0x03,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1, + 0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x85,0x05,0x04,0x03,0xc1,0x00,0x05,0x04,0x01,0xc1,0x81,0x05,0x04,0x03,0xc1,0x01,0x06,0x04,0x03,0xc1,0x05,0x04,0x03,0xc1, + 0x81,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc1,0x81,0x06,0x04,0x03,0xc1,0x8d,0x05,0x04,0x03,0xc0,0x00,0x05,0x03,0x03,0xc0,0x81,0x05,0x03,0x02,0xc0,0x00,0x05, + 0x04,0x01,0xc0,0x85,0x05,0x03,0x02,0xc0,0x85,0x05,0x03,0x02,0xbf,0x00,0x04,0x03,0x02,0xbf,0x81,0x04,0x03,0x02,0xbe,0x82,0x05,0x03,0x02,0xbe,0x02,0x04,0x03,0x02, + 0xbe,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x88,0x04,0x03,0x02,0xbd,0x84,0x04,0x02,0x02,0xbc,0x82,0x03,0x02,0x02,0xbc,0x00,0x04,0x02,0x02,0xbc,0x88,0x03,0x02, + 0x02,0xbb,0x83,0x03,0x02,0x01,0xba,0x82,0x03,0x02,0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x86,0x02,0x01,0x01,0xb8,0x85,0x02,0x01,0x01,0xb7,0x81,0x01,0x01,0x01,0xb7, + 0x83,0x01,0x01,0x01,0xb6,0x86,0x01,0x01,0x00,0xb5,0x84,0x01,0x00,0x00,0xb5,0x88,0x01,0x00,0x00,0xb4,0x92,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0x8b,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x9b,0x00,0x00,0x00,0xb3,0x91,0x00,0x00,0x00,0xb4,0x87,0x01,0x00,0x00, + 0xb4,0x82,0x01,0x00,0x00,0xb5,0x81,0x01,0x01,0x00,0xb5,0x89,0x01,0x01,0x01,0xb6,0x81,0x02,0x01,0x01,0xb7,0x8a,0x02,0x01,0x01,0xb8,0x81,0x02,0x02,0x01,0xb9,0x81, + 0x03,0x02,0x01,0xb9,0x84,0x03,0x02,0x01,0xba,0x83,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x02,0xbc,0x85,0x04,0x02,0x02,0xbc,0x84,0x04,0x03,0x02,0xbd,0x01,0x04,0x03, + 0x02,0xbe,0x05,0x03,0x02,0xbe,0x81,0x04,0x03,0x02,0xbe,0x81,0x05,0x03,0x02,0xbe,0x82,0x04,0x03,0x02,0xbe,0x00,0x04,0x03,0x02,0xbf,0x81,0x05,0x03,0x02,0xbf,0x82, + 0x05,0x03,0x02,0xc0,0x00,0x05,0x04,0x03,0xc0,0x81,0x05,0x04,0x03,0xc1,0x02,0x06,0x04,0x03,0xc1,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x85,0x05,0x04,0x03,0xc1, + 0x87,0x06,0x04,0x03,0xc2,0x86,0x06,0x04,0x03,0xc3,0x86,0x06,0x04,0x03,0xc4,0x81,0x07,0x04,0x03,0xc5,0x97,0x07,0x05,0x02,0xc5,0xa4,0x07,0x05,0x02,0xc6,0x8b,0x07, + 0x05,0x04,0xc6,0x00,0x07,0x05,0x02,0xc6,0x96,0x07,0x05,0x04,0xc6,0x00,0x07,0x05,0x02,0xc6,0x98,0x07,0x05,0x04,0xc6,0x00,0x07,0x05,0x02,0xc6,0x8b,0x07,0x05,0x04, + 0xc6,0x00,0x07,0x05,0x02,0xc6,0x88,0x07,0x05,0x04,0xc6,0x00,0x07,0x05,0x02,0xc6,0x85,0x07,0x05,0x04,0xc6,0xa4,0x07,0x05,0x02,0xc6,0x98,0x07,0x05,0x02,0xc5,0x00, + 0x07,0x04,0x03,0xc5,0x81,0x06,0x04,0x03,0xc4,0x81,0x07,0x04,0x03,0xc4,0x82,0x06,0x04,0x03,0xc4,0x86,0x06,0x04,0x03,0xc3,0x87,0x06,0x04,0x03,0xc2,0x82,0x06,0x04, + 0x03,0xc1,0x01,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc1,0x00,0x05,0x04,0x01,0xc1,0x82,0x05,0x04,0x03,0xc1,0x01,0x05,0x04,0x03,0xc0,0x05, + 0x03,0x03,0xc0,0x81,0x05,0x03,0x02,0xc0,0x82,0x05,0x03,0x02,0xbf,0x00,0x05,0x03,0x02,0xbe,0x85,0x04,0x03,0x02,0xbe,0x01,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe, + 0x84,0x04,0x03,0x02,0xbd,0x82,0x04,0x02,0x02,0xbc,0x00,0x04,0x03,0x02,0xbc,0x82,0x04,0x02,0x02,0xbc,0x83,0x03,0x02,0x02,0xbb,0x84,0x03,0x02,0x01,0xba,0x82,0x03, + 0x02,0x01,0xb9,0x00,0x02,0x02,0x01,0xb9,0x8a,0x02,0x01,0x01,0xb8,0x81,0x02,0x01,0x01,0xb7,0x89,0x01,0x01,0x01,0xb6,0x81,0x01,0x01,0x00,0xb5,0x82,0x01,0x00,0x00, + 0xb5,0x87,0x01,0x00,0x00,0xb4,0x91,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x89,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0x99,0x00,0x00,0x00,0xb3,0x91,0x00,0x00,0x00,0xb4,0x81,0x01,0x00,0x00,0xb4,0x87,0x01,0x00,0x00,0xb5,0x82,0x01,0x01,0x00,0xb5,0x83,0x01,0x01, + 0x01,0xb6,0x03,0x02,0x01,0x01,0xb7,0x01,0x01,0x01,0xb7,0x02,0x01,0x01,0xb7,0x01,0x01,0x01,0xb7,0x83,0x02,0x01,0x01,0xb7,0x82,0x02,0x01,0x01,0xb8,0x85,0x02,0x02, + 0x01,0xb9,0x85,0x03,0x02,0x01,0xba,0x82,0x03,0x02,0x02,0xbb,0x83,0x03,0x02,0x02,0xbc,0x82,0x04,0x02,0x02,0xbc,0x85,0x04,0x03,0x02,0xbd,0x81,0x04,0x03,0x02,0xbe, + 0x83,0x04,0x03,0x02,0xbf,0x00,0x05,0x03,0x02,0xbf,0x81,0x05,0x03,0x02,0xc0,0x01,0x05,0x03,0x03,0xc0,0x05,0x04,0x03,0xc0,0x86,0x05,0x04,0x03,0xc1,0x83,0x06,0x04, + 0x03,0xc2,0x81,0x06,0x04,0x03,0xc3,0x00,0x06,0x05,0x02,0xc3,0x83,0x06,0x04,0x03,0xc3,0x82,0x06,0x04,0x03,0xc4,0x81,0x07,0x04,0x03,0xc5,0x89,0x07,0x05,0x02,0xc5, + 0x04,0x07,0x05,0x02,0xc6,0x07,0x05,0x04,0xc6,0x07,0x05,0x02,0xc6,0x07,0x05,0x02,0xc7,0x07,0x05,0x04,0xc7,0x82,0x08,0x05,0x04,0xc7,0x00,0x08,0x05,0x02,0xc7,0x86, + 0x08,0x05,0x04,0xc7,0x86,0x08,0x05,0x04,0xc8,0x00,0x08,0x05,0x02,0xc8,0x8f,0x08,0x05,0x04,0xc8,0x81,0x08,0x05,0x04,0xc9,0xff,0x08,0x06,0x03,0xc9,0x9d,0x08,0x06, + 0x03,0xc9,0x81,0x08,0x05,0x04,0xc9,0x84,0x08,0x05,0x04,0xc8,0x00,0x08,0x06,0x03,0xc8,0x91,0x08,0x05,0x04,0xc8,0x89,0x08,0x05,0x04,0xc7,0x82,0x07,0x05,0x04,0xc7, + 0x02,0x07,0x05,0x02,0xc6,0x07,0x05,0x04,0xc6,0x07,0x05,0x02,0xc6,0x89,0x07,0x05,0x02,0xc5,0x81,0x07,0x04,0x03,0xc5,0x82,0x06,0x04,0x03,0xc4,0x86,0x06,0x04,0x03, + 0xc3,0x83,0x06,0x04,0x03,0xc2,0x00,0x05,0x04,0x03,0xc1,0x81,0x06,0x04,0x03,0xc1,0x01,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc1,0x01,0x05, + 0x04,0x03,0xc0,0x05,0x03,0x03,0xc0,0x81,0x05,0x03,0x02,0xc0,0x83,0x05,0x03,0x02,0xbf,0x00,0x04,0x03,0x02,0xbf,0x81,0x04,0x03,0x02,0xbe,0x85,0x04,0x03,0x02,0xbd, + 0x82,0x04,0x02,0x02,0xbc,0x81,0x03,0x02,0x02,0xbc,0x01,0x04,0x02,0x02,0xbc,0x03,0x02,0x02,0xbc,0x82,0x03,0x02,0x02,0xbb,0x85,0x03,0x02,0x01,0xba,0x85,0x02,0x02, + 0x01,0xb9,0x82,0x02,0x01,0x01,0xb8,0x84,0x02,0x01,0x01,0xb7,0x82,0x01,0x01,0x01,0xb7,0x83,0x01,0x01,0x01,0xb6,0x82,0x01,0x01,0x00,0xb5,0x87,0x01,0x00,0x00,0xb5, + 0x81,0x01,0x00,0x00,0xb4,0x91,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x87,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0x99,0x00,0x00,0x00,0xb3,0x8d,0x00,0x00,0x00,0xb4,0x85,0x01,0x00,0x00,0xb4,0x87,0x01,0x00,0x00,0xb5,0x00,0x01,0x01,0x00,0xb5,0x87,0x01,0x01,0x01, + 0xb6,0x00,0x01,0x01,0x01,0xb7,0x82,0x02,0x01,0x01,0xb7,0x83,0x02,0x01,0x01,0xb8,0x00,0x02,0x02,0x01,0xb9,0x84,0x03,0x02,0x01,0xb9,0x84,0x03,0x02,0x01,0xba,0x02, + 0x03,0x02,0x02,0xbb,0x03,0x02,0x01,0xbb,0x03,0x02,0x02,0xbb,0x81,0x04,0x02,0x02,0xbc,0x01,0x04,0x03,0x02,0xbc,0x04,0x02,0x02,0xbc,0x85,0x04,0x03,0x02,0xbd,0x02, + 0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbf,0x83,0x05,0x03,0x02,0xbf,0x81,0x05,0x03,0x02,0xc0,0x81,0x05,0x03,0x03,0xc0,0x81,0x05,0x04,0x03,0xc0, + 0x81,0x05,0x04,0x03,0xc1,0x86,0x06,0x04,0x03,0xc2,0x81,0x06,0x04,0x03,0xc3,0x00,0x07,0x04,0x03,0xc4,0x81,0x06,0x04,0x03,0xc4,0x81,0x07,0x04,0x03,0xc4,0x82,0x06, + 0x04,0x03,0xc4,0x00,0x07,0x04,0x03,0xc5,0x84,0x07,0x05,0x02,0xc5,0x81,0x07,0x05,0x04,0xc6,0x02,0x07,0x05,0x04,0xc7,0x08,0x05,0x04,0xc7,0x07,0x05,0x02,0xc7,0x81, + 0x08,0x05,0x04,0xc7,0x81,0x07,0x05,0x04,0xc7,0x82,0x08,0x05,0x04,0xc7,0x87,0x08,0x05,0x04,0xc8,0x00,0x08,0x05,0x04,0xc9,0x89,0x08,0x06,0x03,0xc9,0x00,0x09,0x06, + 0x03,0xca,0x88,0x08,0x06,0x03,0xca,0x02,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x85,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0xff,0x09, + 0x06,0x03,0xcb,0xa1,0x09,0x06,0x03,0xcb,0x01,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x86,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x82,0x08,0x06,0x03,0xca, + 0x02,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x83,0x08,0x06,0x03,0xca,0x89,0x08,0x06,0x03,0xc9,0x00,0x08,0x05,0x04,0xc9,0x83,0x08,0x05,0x04, + 0xc8,0x00,0x08,0x06,0x03,0xc8,0x82,0x08,0x05,0x04,0xc8,0x81,0x08,0x05,0x04,0xc7,0x81,0x07,0x05,0x04,0xc7,0x02,0x08,0x05,0x04,0xc7,0x07,0x05,0x04,0xc7,0x08,0x05, + 0x04,0xc7,0x82,0x07,0x05,0x04,0xc7,0x81,0x07,0x05,0x04,0xc6,0x84,0x07,0x05,0x02,0xc5,0x00,0x07,0x04,0x03,0xc5,0x81,0x06,0x04,0x03,0xc4,0x03,0x07,0x04,0x03,0xc4, + 0x06,0x04,0x03,0xc4,0x07,0x05,0x02,0xc4,0x07,0x04,0x03,0xc4,0x81,0x06,0x04,0x03,0xc4,0x81,0x06,0x04,0x03,0xc3,0x86,0x06,0x04,0x03,0xc2,0x81,0x05,0x04,0x03,0xc1, + 0x81,0x05,0x04,0x03,0xc0,0x81,0x05,0x03,0x03,0xc0,0x81,0x05,0x03,0x02,0xc0,0x83,0x05,0x03,0x02,0xbf,0x02,0x04,0x03,0x02,0xbf,0x05,0x03,0x02,0xbe,0x04,0x03,0x02, + 0xbe,0x85,0x04,0x03,0x02,0xbd,0x82,0x04,0x02,0x02,0xbc,0x00,0x03,0x02,0x02,0xbc,0x82,0x03,0x02,0x02,0xbb,0x84,0x03,0x02,0x01,0xba,0x83,0x03,0x02,0x01,0xb9,0x81, + 0x02,0x02,0x01,0xb9,0x83,0x02,0x01,0x01,0xb8,0x82,0x02,0x01,0x01,0xb7,0x00,0x01,0x01,0x01,0xb7,0x87,0x01,0x01,0x01,0xb6,0x00,0x01,0x01,0x00,0xb5,0x87,0x01,0x00, + 0x00,0xb5,0x85,0x01,0x00,0x00,0xb4,0x8d,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x87,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0x99,0x00,0x00,0x00,0xb3,0x91,0x00,0x00,0x00,0xb4,0x81,0x01,0x00,0x00,0xb4,0x87,0x01,0x00,0x00,0xb5,0x00,0x01,0x01,0x00,0xb5,0x87,0x01, + 0x01,0x01,0xb6,0x00,0x01,0x01,0x01,0xb7,0x82,0x02,0x01,0x01,0xb7,0x83,0x02,0x01,0x01,0xb8,0x00,0x02,0x02,0x01,0xb9,0x84,0x03,0x02,0x01,0xb9,0x84,0x03,0x02,0x01, + 0xba,0x82,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x02,0xbc,0x82,0x04,0x02,0x02,0xbc,0x85,0x04,0x03,0x02,0xbd,0x01,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x82,0x04, + 0x03,0x02,0xbf,0x81,0x05,0x03,0x02,0xbf,0x02,0x05,0x04,0x01,0xc0,0x05,0x03,0x02,0xc0,0x05,0x03,0x03,0xc0,0x82,0x05,0x04,0x03,0xc0,0x81,0x06,0x04,0x03,0xc1,0x86, + 0x06,0x04,0x03,0xc2,0x81,0x06,0x04,0x03,0xc3,0x84,0x06,0x04,0x03,0xc4,0x03,0x07,0x04,0x03,0xc4,0x06,0x04,0x03,0xc4,0x07,0x04,0x03,0xc4,0x07,0x05,0x02,0xc4,0x82, + 0x07,0x05,0x02,0xc5,0x00,0x07,0x05,0x02,0xc6,0x81,0x07,0x05,0x04,0xc6,0x00,0x08,0x05,0x04,0xc6,0x81,0x07,0x05,0x04,0xc7,0x87,0x08,0x05,0x04,0xc7,0x83,0x08,0x05, + 0x04,0xc8,0x8b,0x08,0x06,0x03,0xc9,0x01,0x09,0x06,0x03,0xc9,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x84,0x08,0x06,0x03,0xca,0x81, + 0x09,0x06,0x03,0xca,0x85,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0xff,0x09,0x06,0x03,0xcb,0xa7,0x09,0x06,0x03,0xcb,0x81,0x09,0x06,0x03,0xca,0x81,0x08,0x06, + 0x03,0xca,0x06,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x81, + 0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x02,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x8c,0x08,0x06,0x03,0xc9, + 0x83,0x08,0x05,0x04,0xc8,0x87,0x08,0x05,0x04,0xc7,0x81,0x07,0x05,0x04,0xc7,0x82,0x07,0x05,0x04,0xc6,0x00,0x07,0x05,0x02,0xc6,0x82,0x07,0x05,0x02,0xc5,0x83,0x06, + 0x04,0x03,0xc4,0x02,0x07,0x05,0x02,0xc4,0x07,0x04,0x03,0xc4,0x06,0x04,0x03,0xc4,0x81,0x07,0x04,0x03,0xc4,0x81,0x06,0x04,0x03,0xc3,0x86,0x06,0x04,0x03,0xc2,0x81, + 0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc0,0x81,0x05,0x03,0x03,0xc0,0x81,0x05,0x03,0x02,0xc0,0x81,0x05,0x03,0x02,0xbf,0x82,0x04,0x03,0x02,0xbf,0x01,0x04,0x03, + 0x02,0xbe,0x05,0x03,0x02,0xbe,0x85,0x04,0x03,0x02,0xbd,0x82,0x04,0x02,0x02,0xbc,0x00,0x03,0x02,0x02,0xbc,0x81,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0x84, + 0x03,0x02,0x01,0xba,0x83,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x83,0x02,0x01,0x01,0xb8,0x82,0x02,0x01,0x01,0xb7,0x00,0x01,0x01,0x01,0xb7,0x87,0x01,0x01, + 0x01,0xb6,0x00,0x01,0x01,0x00,0xb5,0x87,0x01,0x00,0x00,0xb5,0x81,0x01,0x00,0x00,0xb4,0x91,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0x87,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x9b,0x00,0x00,0x00,0xb3,0x8f,0x00,0x00,0x00,0xb4,0x81,0x01,0x00,0x00,0xb4,0x85,0x01, + 0x00,0x00,0xb5,0x01,0x01,0x01,0x00,0xb5,0x01,0x00,0x00,0xb5,0x82,0x01,0x01,0x00,0xb5,0x86,0x01,0x01,0x01,0xb6,0x00,0x01,0x01,0x01,0xb7,0x84,0x02,0x01,0x01,0xb7, + 0x81,0x02,0x01,0x01,0xb8,0x86,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x83,0x03,0x02,0x01,0xba,0x81,0x03,0x02,0x02,0xbb,0x86,0x04,0x02,0x02,0xbc,0x82,0x04, + 0x03,0x02,0xbd,0x00,0x04,0x03,0x02,0xbe,0x82,0x05,0x03,0x02,0xbe,0x00,0x04,0x03,0x02,0xbf,0x81,0x05,0x03,0x02,0xbf,0x84,0x05,0x03,0x02,0xc0,0x01,0x05,0x03,0x03, + 0xc0,0x05,0x04,0x03,0xc0,0x81,0x05,0x04,0x03,0xc1,0x87,0x06,0x04,0x03,0xc2,0x82,0x06,0x04,0x03,0xc3,0x81,0x07,0x04,0x03,0xc4,0x00,0x06,0x04,0x03,0xc4,0x84,0x07, + 0x04,0x03,0xc5,0x81,0x07,0x05,0x02,0xc5,0x82,0x07,0x05,0x02,0xc6,0x83,0x07,0x05,0x04,0xc6,0x00,0x08,0x05,0x04,0xc6,0x81,0x07,0x05,0x04,0xc7,0x00,0x08,0x05,0x04, + 0xc7,0x83,0x07,0x05,0x04,0xc7,0x00,0x08,0x05,0x04,0xc7,0x8e,0x08,0x05,0x04,0xc8,0x02,0x08,0x06,0x03,0xc8,0x08,0x05,0x04,0xc8,0x08,0x05,0x04,0xc9,0x87,0x08,0x06, + 0x03,0xc9,0x00,0x08,0x06,0x03,0xca,0x82,0x09,0x06,0x03,0xca,0x04,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x08,0x06,0x03, + 0xca,0x81,0x09,0x06,0x03,0xca,0x85,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x03,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06, + 0x03,0xca,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0x84,0x08,0x06,0x03,0xca,0x06,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x08,0x06,0x03, + 0xca,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x87,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0x82,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03, + 0xca,0x81,0x08,0x06,0x03,0xca,0x02,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x84,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0x88,0x08,0x06, + 0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca, + 0x81,0x09,0x06,0x03,0xca,0x84,0x08,0x06,0x03,0xca,0x01,0x09,0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x00,0x09,0x06, + 0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x82,0x09,0x06,0x03,0xca,0x84,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca, + 0x81,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0x01,0x08,0x06,0x03,0xca,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x82,0x08,0x06, + 0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x84,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x85,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x81,0x08,0x06,0x03,0xca, + 0x00,0x09,0x06,0x03,0xca,0x8a,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x83,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x84,0x08,0x06,0x03,0xca,0x01,0x09, + 0x06,0x03,0xca,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca,0x82,0x08,0x06,0x03,0xca,0x00,0x09,0x06,0x03,0xca,0x83,0x08,0x06,0x03,0xca,0x81,0x09,0x06,0x03,0xca, + 0x82,0x08,0x06,0x03,0xca,0x01,0x08,0x06,0x03,0xc9,0x09,0x06,0x03,0xc9,0x85,0x08,0x06,0x03,0xc9,0x00,0x08,0x05,0x04,0xc9,0x90,0x08,0x05,0x04,0xc8,0x05,0x08,0x05, + 0x04,0xc7,0x07,0x05,0x04,0xc7,0x08,0x05,0x04,0xc7,0x07,0x05,0x04,0xc7,0x07,0x05,0x02,0xc7,0x07,0x05,0x04,0xc7,0x81,0x08,0x05,0x04,0xc7,0x00,0x08,0x05,0x04,0xc6, + 0x83,0x07,0x05,0x04,0xc6,0x82,0x07,0x05,0x02,0xc6,0x81,0x07,0x05,0x02,0xc5,0x84,0x07,0x04,0x03,0xc5,0x00,0x07,0x04,0x03,0xc4,0x81,0x06,0x04,0x03,0xc4,0x82,0x06, + 0x04,0x03,0xc3,0x87,0x06,0x04,0x03,0xc2,0x03,0x06,0x04,0x03,0xc1,0x05,0x04,0x03,0xc1,0x05,0x04,0x03,0xc0,0x05,0x03,0x03,0xc0,0x84,0x05,0x03,0x02,0xc0,0x81,0x05, + 0x03,0x02,0xbf,0x00,0x04,0x03,0x02,0xbf,0x81,0x04,0x03,0x02,0xbe,0x01,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x82,0x04,0x03,0x02,0xbd,0x84,0x04,0x02,0x02,0xbc, + 0x01,0x04,0x03,0x02,0xbc,0x03,0x02,0x02,0xbc,0x81,0x03,0x02,0x02,0xbb,0x83,0x03,0x02,0x01,0xba,0x81,0x03,0x02,0x01,0xb9,0x85,0x02,0x02,0x01,0xb9,0x81,0x02,0x01, + 0x01,0xb8,0x85,0x02,0x01,0x01,0xb7,0x86,0x01,0x01,0x01,0xb6,0x82,0x01,0x01,0x00,0xb5,0x87,0x01,0x00,0x00,0xb5,0x81,0x01,0x00,0x00,0xb4,0x8f,0x00,0x00,0x00,0xb4, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x89,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x9b,0x00,0x00,0x00,0xb3,0x91,0x00, + 0x00,0x00,0xb4,0x81,0x01,0x00,0x00,0xb4,0x85,0x01,0x00,0x00,0xb5,0x85,0x01,0x01,0x00,0xb5,0x83,0x01,0x01,0x01,0xb6,0x00,0x01,0x01,0x01,0xb7,0x84,0x02,0x01,0x01, + 0xb7,0x87,0x02,0x01,0x01,0xb8,0x81,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0x83,0x03,0x02,0x01,0xba,0x84,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x02,0xbc,0x84, + 0x04,0x02,0x02,0xbc,0x82,0x04,0x03,0x02,0xbd,0x83,0x04,0x03,0x02,0xbe,0x01,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x82,0x05,0x03,0x02,0xbf,0x83,0x05,0x03,0x02, + 0xc0,0x81,0x05,0x03,0x03,0xc0,0x82,0x05,0x04,0x03,0xc0,0x81,0x05,0x04,0x03,0xc1,0x86,0x06,0x04,0x03,0xc2,0x81,0x06,0x04,0x03,0xc3,0x00,0x07,0x05,0x02,0xc4,0x82, + 0x06,0x04,0x03,0xc4,0x02,0x07,0x04,0x03,0xc4,0x06,0x04,0x03,0xc4,0x07,0x04,0x03,0xc4,0x81,0x06,0x04,0x03,0xc4,0x89,0x07,0x05,0x02,0xc5,0x00,0x07,0x05,0x02,0xc6, + 0x89,0x07,0x05,0x04,0xc6,0x00,0x07,0x05,0x02,0xc7,0x81,0x07,0x05,0x04,0xc7,0x02,0x07,0x05,0x02,0xc7,0x08,0x05,0x04,0xc7,0x07,0x05,0x02,0xc7,0x81,0x07,0x05,0x04, + 0xc7,0x85,0x08,0x05,0x04,0xc7,0x88,0x08,0x05,0x04,0xc8,0x00,0x08,0x05,0x02,0xc8,0xb5,0x08,0x05,0x04,0xc8,0x00,0x08,0x06,0x03,0xc8,0x81,0x08,0x05,0x04,0xc8,0x00, + 0x08,0x06,0x03,0xc8,0xbd,0x08,0x05,0x04,0xc8,0x00,0x08,0x06,0x03,0xc8,0xa7,0x08,0x05,0x04,0xc8,0x00,0x08,0x05,0x02,0xc8,0x83,0x08,0x05,0x04,0xc8,0x00,0x08,0x05, + 0x02,0xc8,0x84,0x08,0x05,0x04,0xc8,0x01,0x08,0x05,0x02,0xc8,0x08,0x05,0x04,0xc8,0x85,0x08,0x05,0x04,0xc7,0x85,0x07,0x05,0x04,0xc7,0x81,0x08,0x05,0x04,0xc7,0x81, + 0x07,0x05,0x04,0xc6,0x00,0x07,0x05,0x02,0xc6,0x86,0x07,0x05,0x04,0xc6,0x00,0x07,0x05,0x02,0xc6,0x88,0x07,0x05,0x02,0xc5,0x01,0x07,0x04,0x03,0xc5,0x07,0x04,0x03, + 0xc4,0x87,0x06,0x04,0x03,0xc4,0x81,0x06,0x04,0x03,0xc3,0x86,0x06,0x04,0x03,0xc2,0x81,0x05,0x04,0x03,0xc1,0x82,0x05,0x04,0x03,0xc0,0x81,0x05,0x03,0x03,0xc0,0x83, + 0x05,0x03,0x02,0xc0,0x81,0x05,0x03,0x02,0xbf,0x00,0x04,0x03,0x02,0xbf,0x85,0x04,0x03,0x02,0xbe,0x82,0x04,0x03,0x02,0xbd,0x83,0x04,0x02,0x02,0xbc,0x01,0x03,0x02, + 0x02,0xbc,0x04,0x02,0x02,0xbc,0x84,0x03,0x02,0x02,0xbb,0x83,0x03,0x02,0x01,0xba,0x00,0x03,0x02,0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x87,0x02,0x01,0x01,0xb8,0x85, + 0x02,0x01,0x01,0xb7,0x83,0x01,0x01,0x01,0xb6,0x85,0x01,0x01,0x00,0xb5,0x85,0x01,0x00,0x00,0xb5,0x81,0x01,0x00,0x00,0xb4,0x91,0x00,0x00,0x00,0xb4,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x89,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x9d,0x00,0x00,0x00,0xb3,0x8f,0x00,0x00,0x00,0xb4, + 0x87,0x01,0x00,0x00,0xb4,0x83,0x01,0x00,0x00,0xb5,0x86,0x01,0x01,0x00,0xb5,0x84,0x01,0x01,0x01,0xb6,0x00,0x01,0x01,0x01,0xb7,0x86,0x02,0x01,0x01,0xb7,0x84,0x02, + 0x01,0x01,0xb8,0x01,0x02,0x02,0x01,0xb9,0x03,0x02,0x01,0xb9,0x83,0x03,0x02,0x01,0xba,0x85,0x03,0x02,0x02,0xbb,0x01,0x03,0x02,0x02,0xbc,0x04,0x03,0x02,0xbc,0x81, + 0x04,0x02,0x02,0xbc,0x01,0x04,0x03,0x02,0xbc,0x04,0x02,0x02,0xbc,0x85,0x04,0x03,0x02,0xbd,0x88,0x04,0x03,0x02,0xbe,0x82,0x05,0x03,0x02,0xbf,0x81,0x05,0x03,0x02, + 0xc0,0x03,0x05,0x03,0x03,0xc0,0x05,0x04,0x03,0xc0,0x05,0x04,0x03,0xc1,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc1,0x00,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03, + 0xc1,0x8a,0x06,0x04,0x03,0xc2,0x87,0x06,0x04,0x03,0xc3,0x84,0x06,0x04,0x03,0xc4,0x00,0x07,0x04,0x03,0xc4,0x81,0x06,0x04,0x03,0xc4,0x89,0x07,0x04,0x03,0xc5,0x9f, + 0x07,0x05,0x02,0xc5,0xff,0x07,0x05,0x02,0xc6,0x83,0x07,0x05,0x02,0xc6,0x9f,0x07,0x05,0x02,0xc5,0x83,0x07,0x04,0x03,0xc5,0x00,0x07,0x05,0x02,0xc5,0x84,0x07,0x04, + 0x03,0xc5,0x87,0x06,0x04,0x03,0xc4,0x00,0x06,0x05,0x02,0xc3,0x86,0x06,0x04,0x03,0xc3,0x8a,0x06,0x04,0x03,0xc2,0x00,0x06,0x04,0x03,0xc1,0x83,0x05,0x04,0x03,0xc1, + 0x81,0x06,0x04,0x03,0xc1,0x01,0x05,0x04,0x03,0xc0,0x05,0x03,0x03,0xc0,0x81,0x05,0x03,0x02,0xc0,0x81,0x05,0x03,0x02,0xbf,0x00,0x04,0x03,0x02,0xbf,0x83,0x04,0x03, + 0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x83,0x04,0x03,0x02,0xbe,0x85,0x04,0x03,0x02,0xbd,0x85,0x04,0x02,0x02,0xbc,0x85,0x03,0x02,0x02,0xbb,0x83,0x03,0x02,0x01,0xba, + 0x01,0x03,0x02,0x01,0xb9,0x02,0x02,0x01,0xb9,0x84,0x02,0x01,0x01,0xb8,0x86,0x02,0x01,0x01,0xb7,0x00,0x01,0x01,0x01,0xb7,0x84,0x01,0x01,0x01,0xb6,0x86,0x01,0x01, + 0x00,0xb5,0x83,0x01,0x00,0x00,0xb5,0x87,0x01,0x00,0x00,0xb4,0x8f,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x8b,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa2,0x00,0x00,0x00,0xb3,0x92,0x00,0x00,0x00,0xb4,0x83,0x01,0x00,0x00,0xb4,0x00,0x01,0x00,0x00,0xb5,0x85,0x01, + 0x01,0x00,0xb5,0x88,0x01,0x01,0x01,0xb6,0x83,0x01,0x01,0x01,0xb7,0x85,0x02,0x01,0x01,0xb7,0x82,0x02,0x01,0x01,0xb8,0x82,0x02,0x02,0x01,0xb9,0x82,0x03,0x02,0x01, + 0xb9,0x82,0x03,0x02,0x01,0xba,0x88,0x03,0x02,0x02,0xbb,0x83,0x04,0x02,0x02,0xbc,0x8a,0x04,0x03,0x02,0xbd,0x00,0x04,0x03,0x02,0xbe,0x81,0x05,0x03,0x02,0xbe,0x00, + 0x04,0x03,0x02,0xbe,0x87,0x05,0x03,0x02,0xbf,0x81,0x05,0x03,0x02,0xc0,0x86,0x05,0x03,0x03,0xc0,0x00,0x05,0x04,0x03,0xc0,0x81,0x05,0x04,0x03,0xc1,0x00,0x05,0x04, + 0x01,0xc1,0x82,0x05,0x04,0x03,0xc1,0x00,0x06,0x04,0x03,0xc1,0x81,0x05,0x04,0x03,0xc1,0xa0,0x06,0x04,0x03,0xc2,0xcf,0x06,0x04,0x03,0xc3,0x00,0x06,0x05,0x02,0xc3, + 0xd0,0x06,0x04,0x03,0xc3,0xa0,0x06,0x04,0x03,0xc2,0x83,0x05,0x04,0x03,0xc1,0x00,0x06,0x04,0x03,0xc1,0x83,0x05,0x04,0x03,0xc1,0x00,0x05,0x04,0x01,0xc0,0x86,0x05, + 0x03,0x03,0xc0,0x81,0x05,0x03,0x02,0xc0,0x86,0x05,0x03,0x02,0xbf,0x00,0x04,0x03,0x02,0xbf,0x83,0x04,0x03,0x02,0xbe,0x8a,0x04,0x03,0x02,0xbd,0x82,0x04,0x02,0x02, + 0xbc,0x00,0x03,0x02,0x02,0xbc,0x85,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0x81,0x03,0x02,0x02,0xbb,0x82,0x03,0x02,0x01,0xba,0x83,0x03,0x02,0x01,0xb9,0x81, + 0x02,0x02,0x01,0xb9,0x82,0x02,0x01,0x01,0xb8,0x86,0x02,0x01,0x01,0xb7,0x82,0x01,0x01,0x01,0xb7,0x88,0x01,0x01,0x01,0xb6,0x85,0x01,0x01,0x00,0xb5,0x00,0x01,0x00, + 0x00,0xb5,0x83,0x01,0x00,0x00,0xb4,0x92,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x90,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xa6,0x00,0x00,0x00,0xb3,0x8e,0x00,0x00,0x00,0xb4,0x82,0x01,0x00,0x00,0xb4,0x87,0x01,0x00,0x00,0xb5,0x86,0x01,0x01,0x00,0xb5,0x87,0x01, + 0x01,0x01,0xb6,0x86,0x02,0x01,0x01,0xb7,0x86,0x02,0x01,0x01,0xb8,0x01,0x02,0x02,0x01,0xb8,0x02,0x01,0x01,0xb8,0x81,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9, + 0x88,0x03,0x02,0x01,0xba,0x85,0x03,0x02,0x02,0xbb,0x02,0x03,0x02,0x01,0xbb,0x04,0x02,0x02,0xbc,0x03,0x02,0x02,0xbc,0x85,0x04,0x02,0x02,0xbc,0x89,0x04,0x03,0x02, + 0xbd,0x8d,0x04,0x03,0x02,0xbe,0x00,0x04,0x03,0x02,0xbf,0x89,0x05,0x03,0x02,0xbf,0x8c,0x05,0x03,0x02,0xc0,0x90,0x05,0x03,0x03,0xc0,0x00,0x05,0x04,0x03,0xc0,0x87, + 0x05,0x03,0x03,0xc0,0x83,0x05,0x04,0x03,0xc0,0x02,0x05,0x04,0x01,0xc0,0x05,0x04,0x03,0xc0,0x05,0x04,0x01,0xc0,0x88,0x05,0x04,0x03,0xc0,0x00,0x05,0x04,0x01,0xc0, + 0x86,0x05,0x04,0x03,0xc0,0x00,0x05,0x04,0x01,0xc0,0x8e,0x05,0x04,0x03,0xc0,0x00,0x05,0x04,0x01,0xc0,0xa1,0x05,0x04,0x03,0xc0,0x00,0x05,0x04,0x01,0xc0,0x98,0x05, + 0x04,0x03,0xc0,0x00,0x05,0x04,0x01,0xc0,0x92,0x05,0x04,0x03,0xc0,0x00,0x05,0x04,0x01,0xc0,0x8d,0x05,0x04,0x03,0xc0,0x99,0x05,0x03,0x03,0xc0,0x8c,0x05,0x03,0x02, + 0xc0,0x8a,0x05,0x03,0x02,0xbf,0x02,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x81,0x05,0x03,0x02,0xbe,0x00,0x04,0x03,0x02,0xbe,0x83,0x05,0x03, + 0x02,0xbe,0x01,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x81,0x04,0x03,0x02,0xbe,0x89,0x04,0x03,0x02,0xbd,0x85,0x04,0x02,0x02,0xbc,0x81,0x03,0x02,0x02,0xbc,0x86, + 0x03,0x02,0x02,0xbb,0x88,0x03,0x02,0x01,0xba,0x81,0x03,0x02,0x01,0xb9,0x00,0x02,0x02,0x01,0xb9,0x88,0x02,0x01,0x01,0xb8,0x85,0x02,0x01,0x01,0xb7,0x00,0x01,0x01, + 0x01,0xb7,0x87,0x01,0x01,0x01,0xb6,0x86,0x01,0x01,0x00,0xb5,0x87,0x01,0x00,0x00,0xb5,0x82,0x01,0x00,0x00,0xb4,0x8e,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0x94,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa6,0x00,0x00,0x00,0xb3,0x91,0x00,0x00,0x00,0xb4,0x85,0x01, + 0x00,0x00,0xb4,0x88,0x01,0x00,0x00,0xb5,0x81,0x01,0x01,0x00,0xb5,0x8c,0x01,0x01,0x01,0xb6,0x00,0x01,0x01,0x01,0xb7,0x87,0x02,0x01,0x01,0xb7,0x89,0x02,0x01,0x01, + 0xb8,0x85,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x8b,0x03,0x02,0x01,0xba,0x89,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x02,0xbc,0x8c,0x04,0x02,0x02,0xbc,0xaf, + 0x04,0x03,0x02,0xbd,0x83,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x88,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x83,0x04,0x03,0x02,0xbe,0x02,0x05,0x03, + 0x02,0xbe,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x84,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x81,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x83,0x04, + 0x03,0x02,0xbe,0x04,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x88,0x04,0x03,0x02,0xbe,0x00,0x05,0x03, + 0x02,0xbe,0x82,0x04,0x03,0x02,0xbe,0x04,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x81,0x04,0x03,0x02, + 0xbe,0x00,0x05,0x03,0x02,0xbe,0x82,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x82,0x04,0x03,0x02,0xbe,0x81,0x05,0x03,0x02,0xbe,0x82,0x04,0x03,0x02,0xbe,0x81, + 0x05,0x03,0x02,0xbe,0x81,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x82,0x04,0x03,0x02,0xbe,0x81,0x05,0x03,0x02,0xbe,0x81,0x04,0x03,0x02,0xbe,0x81,0x05,0x03, + 0x02,0xbe,0x85,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x82,0x04,0x03,0x02,0xbe,0x81,0x05,0x03,0x02,0xbe,0x85,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe, + 0x86,0x04,0x03,0x02,0xbe,0x02,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x81,0x04,0x03,0x02,0xbe,0x00,0x05,0x03,0x02,0xbe,0x85,0x04,0x03,0x02, + 0xbe,0x81,0x05,0x03,0x02,0xbe,0x03,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x04,0x03,0x02,0xbe,0x05,0x03,0x02,0xbe,0x84,0x04,0x03,0x02,0xbe,0xaf,0x04,0x03,0x02, + 0xbd,0x8a,0x04,0x02,0x02,0xbc,0x00,0x04,0x03,0x02,0xbc,0x81,0x04,0x02,0x02,0xbc,0x86,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0x81,0x03,0x02,0x02,0xbb,0x8b, + 0x03,0x02,0x01,0xba,0x00,0x03,0x02,0x01,0xb9,0x85,0x02,0x02,0x01,0xb9,0x89,0x02,0x01,0x01,0xb8,0x87,0x02,0x01,0x01,0xb7,0x00,0x01,0x01,0x01,0xb7,0x8c,0x01,0x01, + 0x01,0xb6,0x81,0x01,0x01,0x00,0xb5,0x88,0x01,0x00,0x00,0xb5,0x85,0x01,0x00,0x00,0xb4,0x91,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0x94,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa8,0x00,0x00,0x00,0xb3,0x95,0x00,0x00,0x00,0xb4,0x83,0x01,0x00,0x00,0xb4,0x81,0x00, + 0x00,0x00,0xb4,0x81,0x01,0x00,0x00,0xb4,0x00,0x01,0x00,0x00,0xb5,0x8c,0x01,0x01,0x00,0xb5,0x87,0x01,0x01,0x01,0xb6,0x01,0x02,0x01,0x01,0xb7,0x01,0x01,0x01,0xb7, + 0x8c,0x02,0x01,0x01,0xb7,0x83,0x02,0x01,0x01,0xb8,0x00,0x02,0x02,0x01,0xb8,0x87,0x02,0x01,0x01,0xb8,0x83,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x9b,0x03, + 0x02,0x01,0xba,0xa0,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0x8f,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0x8c,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x02, + 0xbc,0x96,0x04,0x02,0x02,0xbc,0x00,0x04,0x03,0x02,0xbc,0xb0,0x04,0x02,0x02,0xbc,0x00,0x04,0x03,0x02,0xbc,0x92,0x04,0x02,0x02,0xbc,0x82,0x03,0x02,0x02,0xbb,0x00, + 0x03,0x02,0x01,0xbb,0x8e,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0x82,0x03,0x02,0x02,0xbb,0x00,0x03,0x02,0x01,0xbb,0xa2,0x03,0x02,0x02,0xbb,0x00,0x03,0x02, + 0x01,0xbb,0x83,0x03,0x02,0x02,0xbb,0x9b,0x03,0x02,0x01,0xba,0x00,0x03,0x02,0x01,0xb9,0x83,0x02,0x02,0x01,0xb9,0x8c,0x02,0x01,0x01,0xb8,0x8e,0x02,0x01,0x01,0xb7, + 0x87,0x01,0x01,0x01,0xb6,0x8c,0x01,0x01,0x00,0xb5,0x00,0x01,0x00,0x00,0xb5,0x81,0x01,0x00,0x00,0xb4,0x81,0x00,0x00,0x00,0xb4,0x83,0x01,0x00,0x00,0xb4,0x95,0x00, + 0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x96,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb1,0x00,0x00,0x00, + 0xb3,0x99,0x00,0x00,0x00,0xb4,0x87,0x01,0x00,0x00,0xb4,0x86,0x01,0x00,0x00,0xb5,0x81,0x01,0x01,0x00,0xb5,0x8e,0x01,0x01,0x01,0xb6,0x81,0x01,0x01,0x01,0xb7,0x01, + 0x02,0x01,0x01,0xb7,0x01,0x01,0x01,0xb7,0x8a,0x02,0x01,0x01,0xb7,0x92,0x02,0x01,0x01,0xb8,0x02,0x02,0x02,0x01,0xb8,0x02,0x01,0x01,0xb8,0x02,0x02,0x01,0xb8,0x89, + 0x02,0x01,0x01,0xb8,0x82,0x02,0x02,0x01,0xb9,0x00,0x03,0x02,0x01,0xb9,0x89,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0xff,0x03,0x02,0x01,0xba,0xbb,0x03,0x02, + 0x01,0xba,0x81,0x03,0x02,0x01,0xb9,0x82,0x02,0x02,0x01,0xb9,0x81,0x03,0x02,0x01,0xb9,0x01,0x02,0x02,0x01,0xb9,0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x82, + 0x03,0x02,0x01,0xb9,0x81,0x02,0x02,0x01,0xb9,0x9f,0x02,0x01,0x01,0xb8,0x8a,0x02,0x01,0x01,0xb7,0x03,0x01,0x01,0x01,0xb7,0x02,0x01,0x01,0xb7,0x01,0x01,0x01,0xb7, + 0x02,0x01,0x01,0xb7,0x8e,0x01,0x01,0x01,0xb6,0x81,0x01,0x01,0x00,0xb5,0x86,0x01,0x00,0x00,0xb5,0x87,0x01,0x00,0x00,0xb4,0x99,0x00,0x00,0x00,0xb4,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x9f,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb9,0x00,0x00,0x00,0xb3,0x99,0x00,0x00,0x00,0xb4, + 0x88,0x01,0x00,0x00,0xb4,0x87,0x01,0x00,0x00,0xb5,0x89,0x01,0x01,0x00,0xb5,0x96,0x01,0x01,0x01,0xb6,0x01,0x02,0x01,0x01,0xb7,0x01,0x01,0x01,0xb7,0x9f,0x02,0x01, + 0x01,0xb7,0xff,0x02,0x01,0x01,0xb8,0xc1,0x02,0x01,0x01,0xb8,0x9f,0x02,0x01,0x01,0xb7,0x01,0x01,0x01,0x01,0xb7,0x02,0x01,0x01,0xb7,0x96,0x01,0x01,0x01,0xb6,0x89, + 0x01,0x01,0x00,0xb5,0x87,0x01,0x00,0x00,0xb5,0x88,0x01,0x00,0x00,0xb4,0x99,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa7,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x9c,0x00,0x00,0x00,0xb4,0x8c,0x01,0x00,0x00,0xb4,0x8f,0x01,0x00,0x00,0xb5, + 0x89,0x01,0x01,0x00,0xb5,0xd1,0x01,0x01,0x01,0xb6,0x81,0x01,0x01,0x01,0xb7,0xe1,0x02,0x01,0x01,0xb7,0x81,0x01,0x01,0x01,0xb7,0xd1,0x01,0x01,0x01,0xb6,0x89,0x01, + 0x01,0x00,0xb5,0x88,0x01,0x00,0x00,0xb5,0x02,0x01,0x01,0x00,0xb5,0x01,0x00,0x00,0xb5,0x01,0x01,0x00,0xb5,0x83,0x01,0x00,0x00,0xb5,0x8c,0x01,0x00,0x00,0xb4,0x9c, + 0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xad,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc7,0x00,0x00, + 0x00,0xb3,0xa1,0x00,0x00,0x00,0xb4,0x93,0x01,0x00,0x00,0xb4,0x86,0x01,0x00,0x00,0xb5,0x00,0x01,0x01,0x00,0xb5,0x9e,0x01,0x00,0x00,0xb5,0xff,0x01,0x01,0x00,0xb5, + 0xc7,0x01,0x01,0x00,0xb5,0x87,0x01,0x00,0x00,0xb5,0x00,0x01,0x01,0x00,0xb5,0x81,0x01,0x00,0x00,0xb5,0x00,0x01,0x01,0x00,0xb5,0x9a,0x01,0x00,0x00,0xb5,0x93,0x01, + 0x00,0x00,0xb4,0xa1,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xd2,0x00,0x00,0x00,0xb3,0x87,0x00,0x00,0x00,0xb4,0x83,0x00,0x00,0x00,0xb3,0x9e,0x00,0x00,0x00,0xb4,0x91,0x01,0x00,0x00,0xb4,0x94,0x00,0x00,0x00,0xb4,0x8e, + 0x01,0x00,0x00,0xb4,0x87,0x01,0x00,0x00,0xb5,0x00,0x01,0x01,0x00,0xb5,0x9a,0x01,0x00,0x00,0xb5,0xe1,0x01,0x00,0x00,0xb4,0x01,0x01,0x00,0x00,0xb5,0x01,0x01,0x00, + 0xb5,0x9b,0x01,0x00,0x00,0xb5,0x00,0x01,0x01,0x00,0xb5,0x84,0x01,0x00,0x00,0xb5,0x8e,0x01,0x00,0x00,0xb4,0x94,0x00,0x00,0x00,0xb4,0x91,0x01,0x00,0x00,0xb4,0x9e, + 0x00,0x00,0x00,0xb4,0x83,0x00,0x00,0x00,0xb3,0x87,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc0,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xeb,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb4,0xb9,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xd9,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb4,0xff,0x00, + 0x00,0x00,0xb4,0x93,0x00,0x00,0x00,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xec,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfc,0x00,0x00,0x00,0xb3, + 0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfa,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5, + 0x83,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf9,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x85, + 0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfb,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfa,0x00,0x00,0x00,0xb3,0x02,0xa0,0xa0,0xa0,0xd1,0xff,0xff,0xff,0xff,0xbb,0xbb, + 0xbb,0xdc,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xfb,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x86,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e, + 0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x8d,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0xc2,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52, + 0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e, + 0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x8b,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x86,0x00,0x00,0x00,0xb3,0x00,0x52, + 0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x8b,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x84, + 0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x92,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc, + 0xeb,0x52,0x52,0x52,0xbd,0x95,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0xa7,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x02,0xef, + 0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x82,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e, + 0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xc7,0xc7, + 0xc7,0xe1,0x83,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84, + 0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3, + 0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x88,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a, + 0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81, + 0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00, + 0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff, + 0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a, + 0xc2,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2, + 0xe6,0x82,0xff,0xff,0xff,0xff,0x04,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff, + 0x01,0xc7,0xc7,0xc7,0xe1,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00, + 0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x00, + 0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x06,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x52,0x52,0x52, + 0xbd,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff, + 0x04,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x83,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33, + 0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0xdc,0xdc,0xdc,0xeb,0xff,0xff, + 0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff, + 0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x05,0x90,0x90,0x90,0xcc,0xe6, + 0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a, + 0xc2,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xdc, + 0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x87,0x00, + 0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff, + 0x03,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x85,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3, + 0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x03,0x00, + 0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00, + 0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0xff,0xff,0xff,0xff,0x03, + 0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x85,0x00,0x00, + 0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7, + 0xe1,0x82,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00, + 0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x87,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xb3, + 0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6, + 0xe6,0xf0,0x81,0x90,0x90,0x90,0xcc,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb, + 0xdc,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3, + 0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52, + 0xbd,0x82,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff, + 0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x6a, + 0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x07,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33, + 0xb8,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81, + 0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x05,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xa0, + 0xa0,0xa0,0xd1,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc,0xaf,0xaf,0xaf, + 0xd6,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff, + 0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xa0, + 0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x06,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xd2, + 0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x90,0x90,0x90,0xcc,0x00,0xe6, + 0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0x7e,0x7e, + 0x7e,0xc7,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0x90,0x90,0x90,0xcc,0x84,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff, + 0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x83,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x83,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00, + 0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x06,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x82, + 0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x06,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xff, + 0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff, + 0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x06,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0xff, + 0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff, + 0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xf7, + 0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x82, + 0x00,0x00,0x00,0xb3,0x02,0xa0,0xa0,0xa0,0xd1,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3, + 0x01,0x52,0x52,0x52,0xbd,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00, + 0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff, + 0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xc7,0xc7, + 0xc7,0xe1,0xff,0xff,0xff,0xff,0xd2,0xd2,0xd2,0xe6,0x84,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x0e,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff, + 0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x02,0xa0,0xa0,0xa0,0xd1,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5,0x81,0xff,0xff, + 0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff, + 0x81,0xf7,0xf7,0xf7,0xfa,0x03,0xff,0xff,0xff,0xff,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7, + 0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8b,0x00,0x00,0x00,0xb3,0x00,0x90,0x90, + 0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x09,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff, + 0xbb,0xbb,0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x09, + 0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xbb,0xbb,0xbb,0xdc,0xd2,0xd2,0xd2,0xe6, + 0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x09,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0, + 0xff,0xff,0xff,0xff,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xbb,0xbb,0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0, + 0x85,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x01,0xaf, + 0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x83,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x85,0x00,0x00, + 0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02, + 0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc, + 0x81,0xff,0xff,0xff,0xff,0x09,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xbb,0xbb, + 0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xf7,0xf7,0xf7,0xfa,0x85,0xff,0xff,0xff, + 0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x83,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0, + 0xd1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x81,0xc7,0xc7,0xc7,0xe1,0x03,0xff,0xff,0xff, + 0xff,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81, + 0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00, + 0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef, + 0xf5,0x82,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x87,0x00, + 0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0x52,0x52,0x52,0xbd,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff, + 0xff,0xff,0xff,0x03,0x52,0x52,0x52,0xbd,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0, + 0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0x52,0x52,0x52,0xbd,0xbb,0xbb, + 0xbb,0xdc,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a, + 0x6a,0xc2,0x84,0x00,0x00,0x00,0xb3,0x03,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x05,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8, + 0x81,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00, + 0xb3,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xa0,0xa0,0xa0,0xd1,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff, + 0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x02,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xaf, + 0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0x52,0x52,0x52,0xbd,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x82,0xff,0xff, + 0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x6a, + 0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00, + 0xb3,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xa0,0xa0,0xa0,0xd1,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf3,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6, + 0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xbb,0xbb,0xbb, + 0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x04,0xf7,0xf7, + 0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x05,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc, + 0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff, + 0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x81,0xff, + 0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x33,0x33, + 0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e, + 0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03, + 0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x05,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7, + 0xc7,0xe1,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7, + 0xfa,0x81,0xff,0xff,0xff,0xff,0x05,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00, + 0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc, + 0xeb,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff, + 0xff,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x82,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00, + 0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x82, + 0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xaf,0xaf,0xaf,0xd6,0x01,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb, + 0xdc,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xf3,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x03,0xef,0xef,0xef,0xf5,0xff,0xff,0xff, + 0xff,0xd2,0xd2,0xd2,0xe6,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x85,0xff,0xff, + 0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff, + 0x02,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x82,0xff,0xff,0xff,0xff,0x85,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x82, + 0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x03,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xa0,0xa0,0xa0,0xd1,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x03,0xe6,0xe6, + 0xe6,0xf0,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff, + 0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x02,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0x00,0x00,0x00,0xb3,0x01,0x33, + 0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff, + 0x01,0xe6,0xe6,0xe6,0xf0,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0xff,0xff, + 0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x86,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x85,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0xc7, + 0xc7,0xc7,0xe1,0x85,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7, + 0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81, + 0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83, + 0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x84,0xff, + 0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7, + 0xe1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb, + 0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1, + 0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc, + 0xeb,0x0b,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef, + 0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff, + 0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb, + 0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00, + 0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6, + 0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7, + 0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff, + 0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x06,0x6a,0x6a,0x6a,0xc2,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff, + 0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01, + 0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x06,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6, + 0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a, + 0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x04,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc, + 0xeb,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x03,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02, + 0xef,0xef,0xef,0xf5,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x05,0xbb,0xbb,0xbb,0xdc,0x90,0x90,0x90,0xcc,0xef, + 0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0xa0,0xa0,0xa0,0xd1,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff, + 0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0x6a,0x6a, + 0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0xa0,0xa0,0xa0,0xd1,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x82,0x00, + 0x00,0x00,0xb3,0x05,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc, + 0xeb,0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff, + 0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xf6,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0xbe,0x00,0x00,0x00,0xb3,0x03,0x90,0x90,0x90,0xcc,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0xab,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33, + 0xb8,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x91,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6, + 0xf0,0x83,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xf6,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0xb3,0x02, + 0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xa0,0xa0,0xa0,0xd1,0xaa,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc, + 0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x90,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xf2,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xf6,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf, + 0xd6,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0xaa,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x90,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2, + 0x83,0xdc,0xdc,0xdc,0xeb,0x00,0x52,0x52,0x52,0xbd,0x83,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x83,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0xf6,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0xaa,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0x90,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf9,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1, + 0x81,0xaf,0xaf,0xaf,0xd6,0xc0,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0x90,0x90,0x90,0xcc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x03,0x00, + 0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x8a,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52, + 0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81, + 0x7e,0x7e,0x7e,0xc7,0x9e,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd,0x8d,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e, + 0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x88,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x9e,0x00,0x00,0x00,0xb3, + 0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x84,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x8b,0x00,0x00,0x00, + 0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x9a,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a, + 0x6a,0xc2,0x85,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e, + 0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x84,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00, + 0x52,0x52,0x52,0xbd,0x8f,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0x85,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xe6,0xe6,0xe6,0xf0,0x81, + 0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x83,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0x82, + 0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x04,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x6a, + 0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3, + 0x01,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x01, + 0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x83,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82, + 0xff,0xff,0xff,0xff,0x04,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x05,0xdc, + 0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e, + 0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x84,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x81,0x00,0x00, + 0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00, + 0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00, + 0xb3,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x03,0x90,0x90,0x90,0xcc,0xf7,0xf7,0xf7, + 0xfa,0xef,0xef,0xef,0xf5,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e, + 0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x05,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x84,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa, + 0x6a,0x6a,0x6a,0xc2,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x85,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x85,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff, + 0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x84,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x85, + 0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc, + 0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x84,0xff,0xff,0xff, + 0xff,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc, + 0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x09,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xef,0xef, + 0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x83,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc, + 0xdc,0xeb,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x85,0xff,0xff,0xff,0xff,0x03, + 0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5, + 0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00, + 0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x06,0xf7,0xf7,0xf7,0xfa,0xa0, + 0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2, + 0xe6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff, + 0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff, + 0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x90,0x90,0x90,0xcc,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc, + 0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3, + 0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x07,0xef,0xef,0xef,0xf5,0xff,0xff, + 0xff,0xff,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xbb,0xbb,0xbb,0xdc,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xd2, + 0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x03,0xa0,0xa0,0xa0,0xd1,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3, + 0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x04,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00, + 0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0x7e,0x7e,0x7e,0xc7,0xbb,0xbb,0xbb,0xdc,0xe6, + 0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00,0x00,0xb3, + 0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf, + 0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x04,0xef, + 0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00, + 0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff, + 0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6, + 0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x7e,0x7e,0x7e,0xc7,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff, + 0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3, + 0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0xaf,0xaf,0xaf,0xd6,0x05,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc, + 0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x6a,0x6a,0x6a,0xc2, + 0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82, + 0x00,0x00,0x00,0xb3,0x04,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6, + 0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0x52,0x52,0x52,0xbd, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x04,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e, + 0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x84,0xff,0xff,0xff,0xff,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00, + 0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x87,0xff,0xff,0xff, + 0xff,0x02,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x85,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf, + 0xaf,0xd6,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5, + 0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x82,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8, + 0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0, + 0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x03,0xef,0xef,0xef,0xf5, + 0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1, + 0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00, + 0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x05,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb, + 0xbb,0xbb,0xdc,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7, + 0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x88,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81, + 0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x7e,0x7e,0x7e,0xc7,0x02,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x82,0x00,0x00,0x00,0xb3, + 0x01,0x52,0x52,0x52,0xbd,0x90,0x90,0x90,0xcc,0x81,0xaf,0xaf,0xaf,0xd6,0x04,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82, + 0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff, + 0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00, + 0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52,0xbd,0x81,0xff,0xff, + 0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0x90,0x90,0x90,0xcc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x84,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc, + 0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6, + 0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x06, + 0x52,0x52,0x52,0xbd,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff, + 0xff,0x05,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02, + 0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xbb,0xbb, + 0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x03,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x04,0xdc,0xdc, + 0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6, + 0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x04,0xc7,0xc7,0xc7,0xe1, + 0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x85, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff, + 0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0, + 0xd1,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff, + 0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x09,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00, + 0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e, + 0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x86, + 0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xaf,0xaf,0xaf,0xd6,0x06,0x52,0x52,0x52,0xbd,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff, + 0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x01, + 0x6a,0x6a,0x6a,0xc2,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x06,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0xaf,0xaf, + 0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x03,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6, + 0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc, + 0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1, + 0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x83,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x84,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6, + 0xe6,0xf0,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x85,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0, + 0x85,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x82,0xff, + 0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x85,0xff,0xff,0xff,0xff,0x02, + 0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3, + 0x00,0xc7,0xc7,0xc7,0xe1,0x85,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xe6, + 0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7, + 0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52, + 0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x04,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff, + 0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0xff,0xff,0xff,0xff,0x01,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x86,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa, + 0x84,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x04,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff, + 0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff, + 0xff,0x00,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x82,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00, + 0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x0a, + 0x6a,0x6a,0x6a,0xc2,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3, + 0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00, + 0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x06,0x6a,0x6a,0x6a,0xc2,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x33,0x33, + 0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x04,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0, + 0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6, + 0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc, + 0xeb,0x02,0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef, + 0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xa0, + 0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x03,0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xdc, + 0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x04,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef, + 0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a, + 0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x7e, + 0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0x81, + 0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf, + 0xd6,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x0b,0xbb,0xbb,0xbb,0xdc, + 0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa, + 0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x06,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0xff,0xff, + 0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xd2,0xd2,0xd2,0xe6,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x08,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5, + 0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6, + 0xe6,0xf0,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e, + 0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a, + 0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0xa0,0xa0,0xa0,0xd1,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x81,0x00, + 0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x82,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52, + 0xbd,0x6a,0x6a,0x6a,0xc2,0xad,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x94,0x00,0x00,0x00,0xb3,0x00,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x9f,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x9a,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xaf,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa1,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x83,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0xac,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x94,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x9f,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x9a,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xaf,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff, + 0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa0,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x83, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0xac,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xaf,0xaf,0xaf,0xd6,0x92,0x00, + 0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd,0x9f,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x9a,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e, + 0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xaf,0x00,0x00,0x00,0xb3, + 0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa0,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x05,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xef,0xef,0xef, + 0xf5,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc,0xad,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xb6,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x9a,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7, + 0x87,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xb6,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff, + 0xff,0xff,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa0,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x83,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0xb2,0x00,0x00, + 0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0xb6,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81, + 0xaf,0xaf,0xaf,0xd6,0x9a,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0x87,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e, + 0x7e,0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xda,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa7,0x00,0x00,0x00, + 0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0x97,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e, + 0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb8,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xe4,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xbe,0x00,0x00,0x00,0xb3,0x00,0xf7, + 0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0xb4,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xdd,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb6,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xe4,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff, + 0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xbe,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xb3,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xdd,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xe4,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xbe,0x00,0x00,0x00,0xb3,0x05,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a, + 0xc2,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xd2,0xd2,0xd2,0xe6,0xb3,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xdd,0x00,0x00,0x00, + 0xb3,0x81,0x33,0x33,0x33,0xb8,0x01,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xaa,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7, + 0x52,0x52,0x52,0xbd,0x97,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x90,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7, + 0x00,0x33,0x33,0x33,0xb8,0x94,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x91,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33, + 0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x88,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x9c,0x00,0x00,0x00,0xb3,0x04,0x21,0x21, + 0x21,0xba,0x43,0x43,0x43,0xc2,0x4d,0x4d,0x4d,0xc5,0x41,0x41,0x41,0xc2,0x13,0x13,0x13,0xb7,0x91,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e, + 0xc7,0x00,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x83,0x00,0x00,0x00,0xb3,0x00, + 0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00, + 0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x8a,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x86,0x00,0x00,0x00,0xb3,0x00,0x52,0x52, + 0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x9b,0x00,0x00,0x00,0xb3, + 0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd,0x85,0x00, + 0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x8d,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x8e, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x04,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x86,0x00, + 0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x92,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x91, + 0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x85,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8, + 0x8a,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x91,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa8,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf, + 0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf, + 0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff, + 0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7, + 0xe1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x87,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02, + 0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff, + 0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xd7,0xd7,0xd7,0xf0,0x86,0xff,0xff,0xff, + 0xff,0x00,0x89,0x89,0x89,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0x9e,0x9e,0x9e,0xdc,0xec,0xec,0xec,0xf8,0x83,0xff,0xff,0xff,0xff,0x02,0xfd,0xfd,0xfd,0xff,0xca,0xca, + 0xca,0xeb,0x3c,0x3c,0x3c,0xc1,0x83,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a, + 0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff, + 0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x82, + 0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef, + 0xf5,0x6a,0x6a,0x6a,0xc2,0x87,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33, + 0xb8,0x81,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33, + 0xb8,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00, + 0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf, + 0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7, + 0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x87,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2, + 0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x07,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff, + 0xff,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00, + 0xb3,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x83,0x00,0x00,0x00,0xb3,0x01,0x7e, + 0x7e,0x7e,0xc7,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0x52,0x52, + 0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e, + 0xc7,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x05,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7, + 0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81, + 0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0x52, + 0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xa7,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7, + 0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x86, + 0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x86,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0xff, + 0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81, + 0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3, + 0x00,0xd7,0xd7,0xd7,0xf0,0x86,0xff,0xff,0xff,0xff,0x00,0x89,0x89,0x89,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xe1,0xe1,0xe1,0xf3,0x86,0xff,0xff,0xff,0xff,0x01,0xf6, + 0xf6,0xf6,0xfc,0x41,0x41,0x41,0xc2,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8, + 0xe6,0xe6,0xe6,0xf0,0x86,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x84,0xff,0xff,0xff,0xff,0x02,0x00,0x00, + 0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x85,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff, + 0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xb3, + 0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00, + 0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x83,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x85,0xff, + 0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3, + 0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e, + 0xc7,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x07,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e, + 0xc7,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff, + 0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00, + 0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa6,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x06,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e, + 0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf, + 0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff, + 0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0, + 0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff, + 0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7, + 0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x02,0x28,0x28,0x28,0xbc,0x34,0x34,0x34,0xbf,0x63,0x63,0x63,0xcb, + 0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf9,0x81,0x34,0x34,0x34,0xbf,0x00,0x17,0x17,0x17,0xb8,0x81,0x00,0x00,0x00,0xb3,0x06,0xe0,0xe0,0xe0,0xf3,0xce,0xce, + 0xce,0xec,0x7d,0x7d,0x7d,0xd2,0x46,0x46,0x46,0xc3,0x44,0x44,0x44,0xc3,0x7e,0x7e,0x7e,0xd2,0xef,0xef,0xef,0xf9,0x81,0xff,0xff,0xff,0xff,0x00,0xc3,0xc3,0xc3,0xe8, + 0x82,0x00,0x00,0x00,0xb3,0x03,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x05,0x52,0x52,0x52,0xbd, + 0xf7,0xf7,0xf7,0xfa,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xc7,0xc7, + 0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52, + 0x52,0xbd,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x90,0x90, + 0x90,0xcc,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6, + 0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6, + 0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc, + 0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00, + 0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x04,0xbb,0xbb,0xbb,0xdc,0xef, + 0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0, + 0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0x00,0x00,0x00,0xb3,0x07,0xef,0xef,0xef,0xf5,0xff,0xff, + 0xff,0xff,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x05,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xbb,0xbb,0xbb,0xdc,0xa0,0xa0,0xa0,0xd1, + 0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6, + 0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa6,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e, + 0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02, + 0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e, + 0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00, + 0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff, + 0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf,0xd6,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0x00,0x00,0x00,0xb3,0x00,0x3e,0x3e,0x3e,0xc1,0x81,0xff,0xff,0xff,0xff,0x00, + 0xed,0xed,0xed,0xf8,0x84,0x00,0x00,0x00,0xb3,0x00,0x2b,0x2b,0x2b,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0x7c,0x7c,0x7c,0xd2,0x81,0xff,0xff,0xff,0xff,0x00,0xe9,0xe9, + 0xe9,0xf7,0x83,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0x33,0x33,0x33,0xb8,0x82,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x82,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff, + 0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52, + 0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x02,0xa0,0xa0,0xa0,0xd1,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5, + 0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00, + 0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88, + 0x00,0x00,0x00,0xb3,0x01,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x01,0xff,0xff,0xff,0xff,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x04,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7, + 0xfa,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff, + 0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00, + 0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0, + 0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x81,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84, + 0xaf,0xaf,0xaf,0xd6,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf,0xd6,0x02, + 0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2, + 0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6, + 0xf0,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0, + 0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xb3,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa6,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00, + 0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x87,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0x00,0x00,0x00,0xb3,0x00,0x3e,0x3e,0x3e,0xc1,0x81,0xff,0xff,0xff,0xff,0x00, + 0xed,0xed,0xed,0xf8,0x8a,0x00,0x00,0x00,0xb3,0x00,0x92,0x92,0x92,0xd8,0x81,0xff,0xff,0xff,0xff,0x00,0xdb,0xdb,0xdb,0xf1,0x91,0x00,0x00,0x00,0xb3,0x00,0x90,0x90, + 0x90,0xcc,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00, + 0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x83,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb, + 0x87,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x02,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00, + 0xb3,0x00,0x52,0x52,0x52,0xbd,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82, + 0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x81,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xf7,0xf7,0xf7,0xfa,0x85,0xff,0xff,0xff, + 0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x06,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0xf7,0xf7, + 0xf7,0xfa,0xff,0xff,0xff,0xff,0xbb,0xbb,0xbb,0xdc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb3,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xa6,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33, + 0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff, + 0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x7e,0x7e,0x7e,0xc7,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7, + 0xf7,0xfa,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff, + 0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef, + 0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x89,0x00,0x00,0x00, + 0xb3,0x00,0x3e,0x3e,0x3e,0xc1,0x81,0xff,0xff,0xff,0xff,0x00,0xed,0xed,0xed,0xf8,0x87,0x00,0x00,0x00,0xb3,0x02,0xb0,0xb0,0xb0,0xe1,0xba,0xba,0xba,0xe5,0xd2,0xd2, + 0xd2,0xee,0x81,0xff,0xff,0xff,0xff,0x01,0xf8,0xf8,0xf8,0xfd,0x58,0x58,0x58,0xc8,0x8e,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0xbb,0xbb,0xbb,0xdc,0xef,0xef, + 0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0x00,0x00,0x00,0xb3,0x03,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x05,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x02, + 0xc7,0xc7,0xc7,0xe1,0xa0,0xa0,0xa0,0xd1,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc, + 0x81,0x7e,0x7e,0x7e,0xc7,0x02,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x04,0xdc,0xdc,0xdc,0xeb,0xff, + 0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0, + 0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef, + 0xf5,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xd2, + 0xd2,0xd2,0xe6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x6a,0x6a,0x6a,0xc2,0x52,0x52, + 0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6, + 0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81, + 0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3, + 0x00,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x7e,0x7e,0x7e,0xc7,0x02,0xe6, + 0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x88,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xc7,0xc7,0xc7,0xe1,0x81, + 0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7, + 0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb3,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xa6,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x05,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf, + 0xaf,0xd6,0xef,0xef,0xef,0xf5,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6, + 0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6, + 0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02, + 0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff, + 0x03,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc,0xd2, + 0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb, + 0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02, + 0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x3e,0x3e,0x3e,0xc1,0x81,0xff,0xff,0xff,0xff,0x00,0xed,0xed, + 0xed,0xf8,0x87,0x00,0x00,0x00,0xb3,0x00,0xf5,0xf5,0xf5,0xfc,0x82,0xff,0xff,0xff,0xff,0x01,0xca,0xca,0xca,0xeb,0x2b,0x2b,0x2b,0xbd,0x8e,0x00,0x00,0x00,0xb3,0x00, + 0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x04,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5, + 0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x03,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7, + 0xc7,0xe1,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7, + 0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x05,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7, + 0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x86,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00, + 0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff, + 0xe6,0xe6,0xe6,0xf0,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x05,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x33,0x33,0x33,0xb8,0xd2, + 0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xbb, + 0xbb,0xbb,0xdc,0xaf,0xaf,0xaf,0xd6,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x05,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0xc7,0xc7,0xc7,0xe1,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7, + 0xc7,0xe1,0x87,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa7,0x00,0x00,0x00,0xb3,0x00,0x90, + 0x90,0x90,0xcc,0x85,0xff,0xff,0xff,0xff,0x01,0x90,0x90,0x90,0xcc,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff, + 0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff, + 0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff, + 0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff, + 0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xe6,0xe6, + 0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0, + 0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x3e,0x3e,0x3e,0xc1,0x81,0xff,0xff,0xff,0xff,0x00,0xed,0xed,0xed,0xf8,0x87,0x00,0x00,0x00,0xb3,0x02,0xa2, + 0xa2,0xa2,0xdd,0xac,0xac,0xac,0xe1,0xcf,0xcf,0xcf,0xed,0x81,0xff,0xff,0xff,0xff,0x01,0xc5,0xc5,0xc5,0xe9,0x04,0x04,0x04,0xb4,0x8c,0x00,0x00,0x00,0xb3,0x00,0xaf, + 0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xbb,0xbb,0xbb,0xdc,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x86,0xff,0xff,0xff,0xff,0x02, + 0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb, + 0xdc,0x84,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52, + 0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7, + 0x84,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x86, + 0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33, + 0xb8,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0x6a,0x6a,0x6a,0xc2,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2, + 0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6, + 0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33, + 0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00, + 0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff, + 0xff,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff, + 0x00,0xd2,0xd2,0xd2,0xe6,0x82,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xd2,0xd2,0xd2,0xe6,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xb2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa8,0x00,0x00,0x00,0xb3,0x07,0x6a,0x6a,0x6a,0xc2,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7, + 0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6, + 0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x02, + 0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x05,0x90,0x90,0x90,0xcc, + 0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0, + 0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x03,0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0, + 0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81, + 0xdc,0xdc,0xdc,0xeb,0x01,0xa0,0xa0,0xa0,0xd1,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3, + 0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00, + 0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0xa0,0xa0,0xa0,0xd1,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33, + 0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x05,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7, + 0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x03,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0xf7, + 0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x02,0x50,0x50,0x50,0xc6,0x63,0x63,0x63,0xcb,0x86,0x86,0x86,0xd5,0x81,0xff,0xff,0xff,0xff,0x00,0xed, + 0xed,0xed,0xf8,0x8a,0x00,0x00,0x00,0xb3,0x00,0xba,0xba,0xba,0xe5,0x81,0xff,0xff,0xff,0xff,0x00,0x72,0x72,0x72,0xcf,0x8c,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x85,0x00,0x00,0x00,0xb3,0x01,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xef, + 0xef,0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01, + 0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x05,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb, + 0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00, + 0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef, + 0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff, + 0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x87,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x03,0xbb,0xbb,0xbb,0xdc,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc, + 0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x00,0x33,0x33, + 0x33,0xb8,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc, + 0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7, + 0xe1,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7, + 0xc7,0xc7,0xe1,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x05,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0xf7, + 0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x05,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7, + 0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x04,0x6a,0x6a,0x6a, + 0xc2,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3, + 0x06,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x04,0x7e,0x7e,0x7e,0xc7,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf, + 0xd6,0x83,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52, + 0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x88, + 0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x81, + 0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x07,0xbb,0xbb,0xbb,0xdc,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a, + 0x6a,0xc2,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc, + 0xdc,0xdc,0xeb,0x00,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb1,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xaf,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0x6a, + 0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0xbd,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x97,0x00,0x00,0x00,0xb3,0x00,0xd7,0xd7,0xd7,0xf0,0x83, + 0xff,0xff,0xff,0xff,0x00,0xed,0xed,0xed,0xf8,0x84,0x00,0x00,0x00,0xb3,0x02,0x7b,0x7b,0x7b,0xd1,0xa2,0xa2,0xa2,0xdd,0x2c,0x2c,0x2c,0xbd,0x81,0x00,0x00,0x00,0xb3, + 0x01,0x07,0x07,0x07,0xb5,0xcd,0xcd,0xcd,0xec,0x81,0xff,0xff,0xff,0xff,0x00,0xa3,0xa3,0xa3,0xdd,0x8c,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0xc0,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff, + 0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xdd,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xaf,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e, + 0x7e,0xc7,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xbd,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x97,0x00,0x00,0x00,0xb3,0x01,0xa7,0xa7,0xa7,0xdf,0xdc,0xdc,0xdc,0xf2,0x82,0xff,0xff,0xff,0xff,0x00,0xed,0xed,0xed,0xf8,0x84,0x00, + 0x00,0x00,0xb3,0x00,0x91,0x91,0x91,0xd8,0x81,0xff,0xff,0xff,0xff,0x02,0xe8,0xe8,0xe8,0xf6,0xdc,0xdc,0xdc,0xf1,0xf4,0xf4,0xf4,0xfb,0x82,0xff,0xff,0xff,0xff,0x00, + 0x79,0x79,0x79,0xd1,0x8c,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x05,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0xaf,0xaf,0xaf,0xd6, + 0xef,0xef,0xef,0xf5,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0xbf,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xdc,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xaf,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0xbd,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x99,0x00,0x00,0x00,0xb3,0x00,0x53,0x53,0x53,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xed, + 0xed,0xed,0xf8,0x84,0x00,0x00,0x00,0xb3,0x00,0x87,0x87,0x87,0xd5,0x86,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xe5,0x03,0x03,0x03,0xb4,0x8d,0x00,0x00,0x00,0xb3, + 0x00,0xdc,0xdc,0xdc,0xeb,0x85,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52, + 0x52,0x52,0xbd,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff, + 0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0x90,0x90,0x90,0xcc,0xda,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xaf,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0x00,0x00,0x00,0xb3,0x05,0x52,0x52,0x52,0xbd,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7, + 0xfa,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0xbd,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x9a,0x00,0x00,0x00,0xb3,0x02,0x6e,0x6e,0x6e,0xce,0x79, + 0x79,0x79,0xd1,0x6e,0x6e,0x6e,0xce,0x85,0x00,0x00,0x00,0xb3,0x06,0x2f,0x2f,0x2f,0xbe,0x74,0x74,0x74,0xcf,0x9e,0x9e,0x9e,0xdc,0xae,0xae,0xae,0xe1,0xa9,0xa9,0xa9, + 0xdf,0x89,0x89,0x89,0xd6,0x3c,0x3c,0x3c,0xc1,0x90,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef, + 0xf5,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0xc6,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0xda,0x00,0x00,0x00,0xb3,0x03,0x52,0x52,0x52,0xbd,0xef,0xef,0xef, + 0xf5,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xaf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0x8a,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0xbd,0x00,0x00,0x00,0xb3,0x00,0xa0, + 0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00,0xb3,0x8f,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb, + 0x00,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xdc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc9,0x00,0x00,0x00,0xb3,0x02, + 0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc8,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff, + 0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb0,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc8,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb0,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc8,0x00,0x00,0x00,0xb3,0x81,0x33,0x33,0x33,0xb8,0x01,0x00,0x00,0x00,0xb3,0xc7, + 0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xaf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xae,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x6a,0x6a,0x6a,0xc2,0x90,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81, + 0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x8c,0x00,0x00,0x00,0xb3, + 0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x8e,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x87, + 0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x8b,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2, + 0x83,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x92,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7, + 0x33,0x33,0x33,0xb8,0x8c,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33, + 0x33,0xb8,0x83,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52, + 0x52,0x52,0xbd,0x94,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x94,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00, + 0x33,0x33,0x33,0xb8,0x84,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x88,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7, + 0x00,0x33,0x33,0x33,0xb8,0x92,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x86,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a, + 0xc2,0x81,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0xa5,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00, + 0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x90,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e, + 0xc7,0x6a,0x6a,0x6a,0xc2,0x92,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a, + 0xc2,0x81,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x8d,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e, + 0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xaf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xac,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7, + 0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7, + 0xe1,0x83,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x00,0xa0, + 0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x03,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff, + 0x01,0xd2,0xd2,0xd2,0xe6,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff, + 0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x03,0xef,0xef,0xef, + 0xf5,0x90,0x90,0x90,0xcc,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x05,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc, + 0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00, + 0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xf7, + 0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00, + 0xb3,0x01,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x03,0xbb,0xbb,0xbb,0xdc,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb, + 0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x82,0xff,0xff, + 0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00,0xb3,0x02, + 0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x04,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33, + 0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00, + 0xb3,0x02,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x01,0xa0, + 0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x90, + 0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7, + 0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x03,0x52,0x52,0x52,0xbd,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00, + 0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2, + 0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3, + 0x01,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x03, + 0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x01, + 0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x01,0xbb,0xbb,0xbb,0xdc,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff, + 0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xaf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xac,0x00,0x00,0x00,0xb3,0x04,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02, + 0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a, + 0x6a,0x6a,0xc2,0x86,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00, + 0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x01,0xa0,0xa0,0xa0,0xd1,0xc7,0xc7,0xc7,0xe1,0x81, + 0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81, + 0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x52, + 0x52,0x52,0xbd,0x84,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef, + 0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x86,0xff,0xff,0xff,0xff,0x00, + 0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0xc7, + 0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x84, + 0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x6a,0x6a, + 0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x85,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0, + 0xa0,0xa0,0xd1,0x83,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00, + 0xb3,0x00,0x90,0x90,0x90,0xcc,0x86,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x88, + 0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x86,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff, + 0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81, + 0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xae,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xad,0x00,0x00,0x00,0xb3,0x03,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33, + 0xb8,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff, + 0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x90,0x90,0x90,0xcc,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6, + 0xe6,0xf0,0x90,0x90,0x90,0xcc,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a, + 0x6a,0xc2,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf, + 0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x07,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xbb,0xbb,0xbb,0xdc,0xa0,0xa0, + 0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5, + 0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e, + 0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7, + 0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xc7,0xc7, + 0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00, + 0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff, + 0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x81,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x88,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00, + 0xb3,0x05,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00, + 0xe6,0xe6,0xe6,0xf0,0x81,0x90,0x90,0x90,0xcc,0x03,0xd2,0xd2,0xd2,0xe6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff, + 0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x03,0xa0,0xa0,0xa0,0xd1,0x6a,0x6a, + 0x6a,0xc2,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00, + 0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff, + 0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33, + 0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff, + 0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x7e,0x7e,0x7e,0xc7,0xc7, + 0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x03,0xa0,0xa0,0xa0,0xd1,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x33, + 0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81, + 0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1, + 0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x82,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa, + 0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xae,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xad,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00, + 0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6, + 0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff, + 0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8, + 0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6, + 0x86,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff, + 0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a, + 0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc, + 0x81,0x7e,0x7e,0x7e,0xc7,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00, + 0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82, + 0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00, + 0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf,0xd6,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x02,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x88,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x7e,0x7e,0x7e,0xc7,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xd2, + 0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00, + 0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf, + 0xd6,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff, + 0x85,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52, + 0x52,0xbd,0x6a,0x6a,0x6a,0xc2,0x87,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x84, + 0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3, + 0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x88,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00, + 0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0x33,0x33, + 0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7, + 0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x04,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf, + 0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81, + 0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff, + 0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xad,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xac,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e, + 0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x02,0xdc, + 0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00, + 0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x87,0xff,0xff,0xff,0xff,0x85,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6, + 0x85,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90, + 0xcc,0xf7,0xf7,0xf7,0xfa,0x85,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x82,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e, + 0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x88,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x87,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x85,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00, + 0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff, + 0xff,0x03,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x87,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8c,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x52, + 0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff, + 0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6, + 0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0x00,0x00,0x00,0xb3,0x06,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xbb, + 0xbb,0xbb,0xdc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xad,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xac,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02, + 0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81, + 0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86, + 0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x7e,0x7e,0x7e,0xc7,0x02,0xe6,0xe6,0xe6, + 0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x85,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00, + 0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x83,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0x90,0x90,0x90,0xcc,0x81,0xaf,0xaf,0xaf,0xd6,0x04,0xef,0xef,0xef,0xf5,0xff, + 0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x01,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xaf, + 0xaf,0xaf,0xd6,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc, + 0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52, + 0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x52,0x52,0x52,0xbd, + 0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90, + 0x90,0xcc,0x81,0x7e,0x7e,0x7e,0xc7,0x02,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0x90,0x90, + 0x90,0xcc,0x81,0xaf,0xaf,0xaf,0xd6,0x04,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff, + 0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02, + 0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e, + 0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff, + 0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x7e,0x7e,0x7e,0xc7,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x7e,0x7e, + 0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x8c,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff, + 0xff,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x81,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x87,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc, + 0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3, + 0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x86,0x00,0x00,0x00, + 0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00, + 0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7, + 0xfa,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xad,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xac,0x00,0x00,0x00,0xb3,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1, + 0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff, + 0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x90,0x90,0x90, + 0xcc,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff, + 0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0xaf, + 0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x09,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00, + 0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xaf,0xaf, + 0xaf,0xd6,0x03,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff, + 0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x01,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0, + 0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0xef,0xef,0xef,0xf5,0xaf, + 0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xaf,0xaf,0xaf,0xd6,0x00, + 0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x09,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3, + 0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7, + 0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x03,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6, + 0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3, + 0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf, + 0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x04,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf, + 0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5, + 0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1,0x00, + 0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x86,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1, + 0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xac,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xac,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x83, + 0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83, + 0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x85,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb, + 0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00, + 0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa, + 0x84,0xff,0xff,0xff,0xff,0x06,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7, + 0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x01,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff, + 0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x86,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x84,0xff, + 0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff, + 0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff, + 0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x81, + 0x00,0x00,0x00,0xb3,0x04,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x52, + 0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0, + 0x84,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x52,0x52, + 0x52,0xbd,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6, + 0xf0,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0xff,0xff, + 0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a, + 0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x03,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6, + 0xf0,0x84,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x87,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x52,0x52, + 0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xd2,0xd2,0xd2,0xe6,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xac,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xad,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a, + 0xc2,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x04,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x04,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x01,0xa0, + 0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81, + 0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff, + 0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x04,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1, + 0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x88,0x00,0x00,0x00,0xb3,0x0a,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1, + 0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1, + 0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x05,0xdc,0xdc,0xdc,0xeb,0xaf, + 0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x07,0xbb,0xbb, + 0xbb,0xdc,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x05,0xef,0xef,0xef,0xf5,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff, + 0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff, + 0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x83,0x00,0x00,0x00,0xb3,0x04,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef, + 0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x06,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xf7, + 0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x04,0xbb,0xbb, + 0xbb,0xdc,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0, + 0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5, + 0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x03,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x04,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5, + 0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x86,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7, + 0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81, + 0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x03,0xa0,0xa0,0xa0, + 0xd1,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb, + 0xdc,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82, + 0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x06,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00, + 0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb, + 0xdc,0x84,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb, + 0xdc,0x81,0x00,0x00,0x00,0xb3,0x06,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52, + 0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x04,0xbb,0xbb,0xbb,0xdc,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x7e,0x7e, + 0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb, + 0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7, + 0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7, + 0xfa,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x05,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa, + 0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x7e,0x7e,0x7e,0xc7, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xab,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x9b,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa9,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x98, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x93,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xb6,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0xb9,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8c,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00, + 0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xbc,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xbd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x9b,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa9,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x04,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x98,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x93,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xb6,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xb9,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb, + 0xdc,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8c,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xbc,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xb5,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x9b,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0xa9,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff, + 0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x98,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e, + 0xc7,0x00,0x52,0x52,0x52,0xbd,0x93,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81, + 0xff,0xff,0xff,0xff,0x81,0xbb,0xbb,0xbb,0xdc,0xb4,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xb9,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x8c,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x88,0x00,0x00,0x00,0xb3,0x00,0xef,0xef, + 0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x81,0xbb,0xbb,0xbb,0xdc,0xba,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xbd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x9b,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa9,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xb0,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x00,0xaf, + 0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0xb4,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xb9,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb, + 0xdc,0x82,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x99, + 0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0xba,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb5,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1, + 0x81,0xaf,0xaf,0xaf,0xd6,0x9b,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0x52, + 0x52,0x52,0xbd,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0xa9,0x00,0x00,0x00, + 0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0xb0,0x00,0x00,0x00,0xb3,0x81, + 0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0x88,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xd2,0xd2,0xd2,0xe6,0x81,0xdc,0xdc,0xdc,0xeb,0xb4,0x00,0x00,0x00, + 0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0xe1,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xd2,0xd2,0xd2,0xe6,0x81,0xdc,0xdc,0xdc,0xeb,0xba,0x00, + 0x00,0x00,0xb3,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc9,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00, + 0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x87,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a, + 0xc2,0x88,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33, + 0x33,0xb8,0xa0,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x92,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd, + 0x81,0x7e,0x7e,0x7e,0xc7,0x8f,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x99,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e, + 0x7e,0xc7,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x87,0x00,0x00,0x00,0xb3,0x02,0x52,0x52, + 0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0x33, + 0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x8a,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33, + 0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x87,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x8c,0x00,0x00,0x00,0xb3, + 0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x8e,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x8a,0x00, + 0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00, + 0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x9f,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7, + 0x00,0x33,0x33,0x33,0xb8,0x84,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x87,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a, + 0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x6a,0x6a,0x6a,0xc2,0x86,0x00,0x00,0x00,0xb3,0x02,0x52,0x52, + 0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x86,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff, + 0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xaf, + 0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff, + 0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x01,0xdc, + 0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01, + 0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa, + 0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x88,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a, + 0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6, + 0x82,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff, + 0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff, + 0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xd2,0xd2, + 0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x06,0xbb,0xbb,0xbb,0xdc,0xdc, + 0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb, + 0xdc,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00, + 0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x01,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf, + 0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x83,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33, + 0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33, + 0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33, + 0xb8,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33, + 0xb8,0xc7,0xc7,0xc7,0xe1,0x83,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef, + 0xf5,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x03,0x90,0x90,0x90,0xcc,0xf7,0xf7,0xf7,0xfa,0xef,0xef,0xef, + 0xf5,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x04, + 0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6, + 0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7, + 0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff, + 0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef, + 0xef,0xf5,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x86,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff, + 0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa, + 0x86,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x84,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x83,0xff,0xff,0xff, + 0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6, + 0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00, + 0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x83,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86, + 0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef, + 0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x05,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff, + 0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8, + 0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x06,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc, + 0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x05,0xf7,0xf7, + 0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1, + 0x83,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff, + 0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc, + 0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0, + 0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81, + 0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6, + 0xf0,0x90,0x90,0x90,0xcc,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb, + 0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xd2,0xd2,0xd2,0xe6, + 0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0, + 0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3, + 0x04,0x6a,0x6a,0x6a,0xc2,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00, + 0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1, + 0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x03,0xa0,0xa0,0xa0,0xd1,0x6a,0x6a,0x6a,0xc2, + 0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00, + 0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff, + 0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2, + 0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd, + 0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00, + 0xe6,0xe6,0xe6,0xf0,0x81,0x90,0x90,0x90,0xcc,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1, + 0x7e,0x7e,0x7e,0xc7,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6, + 0x81,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0xbb,0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff, + 0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3, + 0x05,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xe6, + 0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x03,0xaf, + 0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x09,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xef,0xef,0xef, + 0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x82,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xb6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04, + 0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x85,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc, + 0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff, + 0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0, + 0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x02,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf,0xd6,0x02, + 0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5, + 0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x06, + 0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2, + 0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1, + 0x84,0xaf,0xaf,0xaf,0xd6,0x01,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x90,0x90,0x90,0xcc,0x7e,0x7e,0x7e,0xc7, + 0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00, + 0xb3,0x02,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xd2,0xd2,0xd2,0xe6, + 0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x04,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x84,0xaf, + 0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00, + 0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc, + 0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xaf,0xaf,0xaf,0xd6,0x02,0x52,0x52,0x52,0xbd,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00, + 0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6, + 0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6,0x86,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0x7e,0x7e,0x7e,0xc7,0xbb,0xbb,0xbb,0xdc,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0x52,0x52,0x52,0xbd, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a, + 0x6a,0xc2,0x52,0x52,0x52,0xbd,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x85,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x7e,0x7e,0x7e,0xc7,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb, + 0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff, + 0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xa0,0xa0,0xa0,0xd1, + 0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0xaf,0xaf,0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb9,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xb7,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb, + 0x85,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb, + 0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86, + 0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x09,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0x90,0x90,0x90,0xcc,0xef, + 0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xbb,0xbb,0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00, + 0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x87,0xff,0xff,0xff, + 0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02, + 0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x86,0xff, + 0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6, + 0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2, + 0x00,0x00,0x00,0xb3,0x87,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e, + 0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc, + 0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x87,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x84,0xff,0xff,0xff,0xff,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0xaf, + 0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x8b,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x87,0xff,0xff,0xff,0xff,0x02,0x00,0x00, + 0x00,0xb3,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x85,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff, + 0xff,0x83,0x00,0x00,0x00,0xb3,0x05,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x83, + 0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb9,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef, + 0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x05,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff, + 0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc, + 0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc, + 0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33, + 0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0x52,0x52,0x52, + 0xbd,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff, + 0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0, + 0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff, + 0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x7e,0x7e,0x7e,0xc7,0x02,0xe6,0xe6, + 0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0xaf,0xaf,0xaf,0xd6,0x00,0xc7, + 0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0x7e,0x7e,0x7e,0xc7,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e, + 0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x04,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef, + 0xf5,0x82,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00, + 0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x03,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x7e,0x7e,0x7e,0xc7,0x02,0xe6,0xe6,0xe6,0xf0,0xff,0xff, + 0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x52, + 0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xc7,0xc7,0xc7, + 0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x8b,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x84,0xaf,0xaf,0xaf,0xd6,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc, + 0x81,0x7e,0x7e,0x7e,0xc7,0x02,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0x90,0x90,0x90,0xcc, + 0x81,0xaf,0xaf,0xaf,0xd6,0x04,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf, + 0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff, + 0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb9,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2, + 0xd2,0xe6,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x05,0xef,0xef, + 0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb, + 0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff, + 0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0xaf,0xaf, + 0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02, + 0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff, + 0xff,0xff,0xff,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7, + 0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02, + 0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd, + 0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x04,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7, + 0xc7,0xe1,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0xff,0xff,0xff,0xff,0x0a,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7, + 0xf7,0xfa,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x00, + 0x00,0x00,0xb3,0x08,0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb, + 0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02, + 0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0, + 0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x03,0xa0,0xa0,0xa0,0xd1,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf, + 0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xbb,0xbb, + 0xbb,0xdc,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x0d,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff, + 0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6, + 0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7, + 0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff, + 0xff,0xff,0x03,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00, + 0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x0d, + 0x52,0x52,0x52,0xbd,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff, + 0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x8c,0x00,0x00,0x00,0xb3,0x8a,0xff,0xff, + 0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x09,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00, + 0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x03,0xf7, + 0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x05,0xdc,0xdc,0xdc, + 0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x03,0x52,0x52,0x52,0xbd,0x7e, + 0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xb6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3, + 0x00,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00, + 0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff, + 0x00,0xe6,0xe6,0xe6,0xf0,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0xa0, + 0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00, + 0xb3,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xb3, + 0x86,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52, + 0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff, + 0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff, + 0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x03,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3, + 0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0, + 0xa0,0xd1,0x85,0xff,0xff,0xff,0xff,0x01,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0x85,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xc7,0xc7, + 0xc7,0xe1,0x85,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0, + 0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd, + 0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf, + 0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x84,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0, + 0xd1,0x85,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x8c,0x00,0x00,0x00,0xb3,0x8a,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xc7,0xc7,0xc7,0xe1,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x04,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff, + 0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x86,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x04,0xf7,0xf7,0xf7,0xfa, + 0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0xaf,0xaf, + 0xaf,0xd6,0x85,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x05,0xbb, + 0xbb,0xbb,0xdc,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf, + 0xd6,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc, + 0xeb,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xbb,0xbb, + 0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x05,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x06,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7, + 0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc, + 0xeb,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x52, + 0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0, + 0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0x52,0x52,0x52,0xbd,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x02,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6, + 0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x04,0x90, + 0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x85,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc, + 0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x04,0xe6,0xe6,0xe6,0xf0,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x04,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x01,0xa0, + 0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x87,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e, + 0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xaf,0xaf, + 0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x04,0xaf,0xaf,0xaf,0xd6,0xef,0xef, + 0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x06,0x33,0x33, + 0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x0a, + 0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3, + 0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x85,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x05,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7, + 0xc7,0xe1,0x33,0x33,0x33,0xb8,0x83,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x90,0x90, + 0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x01,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0xa0,0xa0, + 0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x82,0x00, + 0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x03,0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00, + 0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x87,0x00,0x00,0x00,0xb3,0x00, + 0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00, + 0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x01,0x7e, + 0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x8d,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0, + 0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0xc7,0xc7, + 0xc7,0xe1,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xc7,0xc7, + 0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00, + 0xb3,0x05,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02, + 0xa0,0xa0,0xa0,0xd1,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xb6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb8,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0x33,0x33, + 0x33,0xb8,0x94,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x91,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x91,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x96,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0x33,0x33, + 0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x8c,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x96,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x9b,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x94,0x00,0x00,0x00,0xb3,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e, + 0x7e,0xc7,0x91,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0xcb,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x9a,0x00,0x00,0x00,0xb3,0x00,0x7e, + 0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x94,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xb9,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x03,0xdc,0xdc,0xdc,0xeb,0xff, + 0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x93,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x91,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x91,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x95,0x00,0x00, + 0x00,0xb3,0x05,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x8c,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x96,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x9b,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x94,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00, + 0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x91,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0xcb,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x9a,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x94,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb9,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x93,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x91,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x91,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x95,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e, + 0xc7,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x8c,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81, + 0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x96,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x9b,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x94,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0x87,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x91,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff, + 0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xaf,0xaf,0xaf,0xd6,0xc9,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x9a,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0x94,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb9,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xb7,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x94,0x00,0x00,0x00, + 0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x91,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x91,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x95,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb, + 0x88,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x93,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x96,0x00, + 0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0, + 0xd1,0x9b,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xa0,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00, + 0x7e,0x7e,0x7e,0xc7,0x92,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xc9,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc, + 0xdc,0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x9a,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd1,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcf,0x00,0x00,0x00,0xb3,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0x91,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0, + 0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x91,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0xa1,0x00,0x00,0x00,0xb3,0x00, + 0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x93,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0xbe,0x00,0x00,0x00,0xb3,0x81,0xaf,0xaf, + 0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0xa0,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0x92,0x00,0x00,0x00,0xb3, + 0x01,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0xf0,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xaf,0xaf, + 0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd1,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa3,0x00,0x00,0x00,0xb3,0x82,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd8,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xa0,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x84,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xa0,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd5,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xa1,0x00,0x00,0x00,0xb3,0x05,0xef,0xef,0xef,0xf5,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff, + 0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xce,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x85,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a, + 0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x8c,0x00,0x00,0x00, + 0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0x91,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd, + 0x94,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x90,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e,0x7e, + 0xc7,0x9a,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0xa3,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e, + 0xc7,0x52,0x52,0x52,0xbd,0xa6,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x6a,0x6a,0x6a,0xc2,0x8a,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7, + 0x33,0x33,0x33,0xb8,0x91,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0x9a,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2, + 0x81,0x7e,0x7e,0x7e,0xc7,0x86,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x52,0x52,0x52,0xbd,0x8a,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x88,0x00, + 0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33, + 0xb8,0x88,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x8f,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0x7e,0x7e, + 0x7e,0xc7,0x00,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xc1,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5, + 0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x81,0xff, + 0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x05,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0xff, + 0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x03,0xbb,0xbb,0xbb,0xdc, + 0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3, + 0x01,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a, + 0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff, + 0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x87,0x00,0x00,0x00, + 0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x00, + 0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef, + 0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x05,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0xff,0xff, + 0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa, + 0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7, + 0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x86,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xef,0xef,0xef,0xf5,0x82,0xff, + 0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xe6,0xe6, + 0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb, + 0xdc,0x82,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xbb,0xbb,0xbb,0xdc,0x81, + 0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7, + 0xfa,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x82,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e, + 0xc7,0x6a,0x6a,0x6a,0xc2,0xdc,0xdc,0xdc,0xeb,0x83,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xbf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x09,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33, + 0x33,0xb8,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff, + 0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x87,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff, + 0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00, + 0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x86,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb, + 0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x85,0xff, + 0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7, + 0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff, + 0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81, + 0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e, + 0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x86,0xff,0xff,0xff,0xff,0x06,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0xff, + 0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0x00,0x00,0x00,0xb3,0x02,0xef, + 0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x81,0xbb,0xbb,0xbb,0xdc,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00, + 0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e, + 0xc7,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x86,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x81,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x86,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x33,0x33, + 0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0x84,0xff,0xff,0xff,0xff,0x01,0x00,0x00, + 0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x86,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e, + 0x7e,0xc7,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0x81,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00, + 0x00,0x00,0xb3,0x07,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1, + 0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff, + 0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0, + 0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00, + 0xb3,0x05,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff, + 0x03,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e, + 0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0xd2, + 0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb, + 0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x86, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf, + 0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00, + 0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x83,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00, + 0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8, + 0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf, + 0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff, + 0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x03,0xaf,0xaf, + 0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00, + 0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x03,0xa0,0xa0,0xa0,0xd1,0x6a, + 0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x04, + 0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00, + 0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x90,0x90,0x90,0xcc,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02, + 0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0xc7,0xc7, + 0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x04,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x00,0x00, + 0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x7e, + 0x7e,0x7e,0xc7,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3, + 0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x84,0xaf,0xaf,0xaf,0xd6,0x05,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6, + 0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00, + 0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc, + 0x81,0x7e,0x7e,0x7e,0xc7,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff, + 0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x02,0xc7,0xc7,0xc7,0xe1,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00,0xb3,0x00, + 0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x82,0x00, + 0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff, + 0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x06,0x33,0x33,0x33,0xb8,0xbb,0xbb,0xbb,0xdc,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xf7,0xf7,0xf7,0xfa,0xff,0xff, + 0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x03,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x81,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xbb, + 0xbb,0xbb,0xdc,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x7e,0x7e,0x7e,0xc7,0x04,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00, + 0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff, + 0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff, + 0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x03,0x33, + 0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc, + 0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0x00,0x00,0x00,0xb3,0x03,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf, + 0xd6,0x81,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00, + 0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff, + 0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb, + 0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x04,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x85,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01, + 0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff, + 0xff,0x01,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x02,0xa0,0xa0,0xa0,0xd1,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00, + 0xef,0xef,0xef,0xf5,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00, + 0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x6a, + 0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xe6, + 0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x85,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc, + 0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf, + 0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff, + 0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6, + 0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x09,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0x90,0x90,0x90,0xcc,0xef,0xef, + 0xef,0xf5,0xff,0xff,0xff,0xff,0xbb,0xbb,0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0x86,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2, + 0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x06,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc, + 0xff,0xff,0xff,0xff,0xe6,0xe6,0xe6,0xf0,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x03,0x90,0x90,0x90,0xcc, + 0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xd2,0xd2,0xd2,0xe6,0x85,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00, + 0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x05,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a, + 0xc2,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x83,0x00, + 0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00, + 0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf, + 0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xbb,0xbb,0xbb,0xdc, + 0x83,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x81, + 0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01, + 0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff, + 0xff,0x88,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0x90,0x90,0x90,0xcc,0x81,0xaf,0xaf,0xaf,0xd6,0x04,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc, + 0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff, + 0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x02,0xdc,0xdc,0xdc, + 0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52, + 0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x52,0x52,0x52,0xbd, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x05,0x7e,0x7e,0x7e,0xc7, + 0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff, + 0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x03,0x52,0x52,0x52,0xbd,0xbb,0xbb,0xbb,0xdc,0xff,0xff, + 0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x87,0x00, + 0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52, + 0xbd,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x06,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc, + 0xeb,0x00,0x00,0x00,0xb3,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xd2,0xd2,0xd2,0xe6,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0x90,0x90,0x90,0xcc,0x81, + 0xaf,0xaf,0xaf,0xd6,0x04,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xbb, + 0xbb,0xbb,0xdc,0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81, + 0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00, + 0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff, + 0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0x6a,0x6a,0x6a, + 0xc2,0x89,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7, + 0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa, + 0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x05,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xef,0xef,0xef, + 0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0x52, + 0x52,0x52,0xbd,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x01,0x52,0x52,0x52, + 0xbd,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0x7e, + 0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xa0,0xa0,0xa0,0xd1,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xc0,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x05,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x33,0x33,0x33,0xb8, + 0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc, + 0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x87,0x00,0x00,0x00,0xb3,0x09,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33, + 0xb8,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x33,0x33,0x33, + 0xb8,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00, + 0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x04,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00, + 0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e, + 0x7e,0xc7,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff, + 0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff, + 0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x86,0x00,0x00,0x00,0xb3,0x01,0x6a, + 0x6a,0x6a,0xc2,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb, + 0xdc,0x81,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00, + 0xb3,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x0b,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0x33,0x33,0x33,0xb8,0x00, + 0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff, + 0x04,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xaf, + 0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e, + 0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff, + 0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x02,0xc7,0xc7,0xc7,0xe1,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef, + 0xf5,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00, + 0xb3,0xaf,0xaf,0xaf,0xd6,0x6a,0x6a,0x6a,0xc2,0x87,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90, + 0xcc,0x81,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff, + 0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xbb,0xbb,0xbb,0xdc,0xaf,0xaf,0xaf, + 0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x06,0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3, + 0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xaf,0xaf,0xaf,0xd6,0x01,0x52,0x52,0x52,0xbd,0x7e,0x7e,0x7e,0xc7, + 0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x06, + 0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x01,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81, + 0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x01,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x03,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xc0,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x03,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xf7, + 0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x04,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef, + 0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff, + 0x87,0x00,0x00,0x00,0xb3,0x04,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02, + 0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0xff, + 0xff,0xff,0xff,0x03,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a, + 0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x03,0x7e, + 0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0, + 0xd1,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x02, + 0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x85,0x00,0x00,0x00,0xb3,0x04,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef, + 0xef,0xf5,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x02,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff, + 0xff,0x06,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xf7,0xf7,0xf7,0xfa,0x81,0xff, + 0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x02, + 0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd, + 0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00, + 0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7, + 0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7, + 0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x85,0x00,0x00,0x00,0xb3,0x04,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xef, + 0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff, + 0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7, + 0xc7,0xe1,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x01,0xa0,0xa0,0xa0,0xd1,0xdc,0xdc,0xdc,0xeb,0x85,0xff,0xff,0xff,0xff,0x81, + 0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0, + 0x84,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x86,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00, + 0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x81,0xff, + 0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0xff,0xff,0xff, + 0xff,0x00,0xc7,0xc7,0xc7,0xe1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x05,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xef,0xef,0xef, + 0xf5,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x06,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xd2, + 0xd2,0xd2,0xe6,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x05,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf, + 0xd6,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x87,0x00,0x00,0x00,0xb3,0x02,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff, + 0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x04,0x6a,0x6a,0x6a,0xc2,0xef,0xef, + 0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x04,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff, + 0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb,0xdc,0xdc,0xdc,0xdc,0xeb, + 0x81,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xdc,0xdc,0xdc,0xeb,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x06,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1, + 0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc, + 0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xaf, + 0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81, + 0xdc,0xdc,0xdc,0xeb,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x52,0x52,0x52,0xbd,0x85,0x00,0x00,0x00,0xb3,0x06,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0xf7, + 0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xd2,0xd2,0xd2,0xe6,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff, + 0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xdc,0xdc,0xdc,0xeb, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0x00,0x00,0x00,0xb3,0x81,0xdc, + 0xdc,0xdc,0xeb,0x04,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc, + 0xdc,0xeb,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x05,0x7e,0x7e,0x7e,0xc7,0xc7,0xc7,0xc7,0xe1,0xff,0xff, + 0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x04,0x6a,0x6a,0x6a,0xc2,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff, + 0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3, + 0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x04,0x6a,0x6a,0x6a,0xc2,0xef,0xef,0xef,0xf5,0xff,0xff,0xff,0xff,0xef,0xef,0xef,0xf5,0x90,0x90,0x90,0xcc,0x82,0x00, + 0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x00, + 0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0xaf,0xaf,0xaf,0xd6, + 0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x06,0x7e,0x7e,0x7e,0xc7,0xd2,0xd2,0xd2,0xe6,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xd2,0xd2, + 0xd2,0xe6,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x05,0xbb,0xbb,0xbb,0xdc,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff, + 0xff,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x05,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc, + 0xdc,0xdc,0xeb,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x02,0xbb,0xbb,0xbb,0xdc, + 0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0xa0,0xa0,0xa0,0xd1,0xbb,0xbb,0xbb,0xdc,0x81,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1, + 0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x08,0x33,0x33,0x33,0xb8,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7, + 0xc7,0xe1,0x52,0x52,0x52,0xbd,0xbb,0xbb,0xbb,0xdc,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xdc,0xdc,0xdc,0xeb,0x81,0x6a,0x6a, + 0x6a,0xc2,0x81,0xdc,0xdc,0xdc,0xeb,0x04,0xa0,0xa0,0xa0,0xd1,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xb3,0x81,0xdc,0xdc,0xdc, + 0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x01, + 0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x03,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0x81,0xff, + 0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x01,0x00,0x00,0x00,0xb3,0xbb,0xbb,0xbb,0xdc,0x81,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3, + 0x06,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x52,0x52,0x52,0xbd,0x82,0x00,0x00, + 0x00,0xb3,0x81,0xdc,0xdc,0xdc,0xeb,0x05,0xbb,0xbb,0xbb,0xdc,0xa0,0xa0,0xa0,0xd1,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x6a,0x6a,0x6a,0xc2, + 0x82,0x00,0x00,0x00,0xb3,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x9a,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa1,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3, + 0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xa9,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xb1,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0x52,0x52,0x52,0xbd,0xbe,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0x7e,0x7e,0x7e,0xc7,0x95,0x00,0x00,0x00,0xb3,0x81,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x9d,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00, + 0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xdd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xef,0xef,0xef, + 0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x9a,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa1,0x00,0x00,0x00,0xb3,0x81, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x81,0xff,0xff, + 0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xa9,0x00,0x00,0x00,0xb3,0x00,0xdc, + 0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xb0,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf, + 0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xbd,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85, + 0x00,0x00,0x00,0xb3,0x03,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb,0x94,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x9d,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x03,0xdc,0xdc, + 0xdc,0xeb,0xff,0xff,0xff,0xff,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xdc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x9b,0x00,0x00,0x00,0xb3, + 0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa1,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x00,0xef, + 0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x81,0xbb,0xbb,0xbb,0xdc,0x8b,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3, + 0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xa9,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0x00,0x00, + 0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xb0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0xbd,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff, + 0xff,0xff,0xff,0x94,0x00,0x00,0x00,0xb3,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x6a,0x6a,0x6a,0xc2,0x9d,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x81,0x7e,0x7e,0x7e, + 0xc7,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xdc, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbf,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x85,0xdc,0xdc,0xdc,0xeb,0x01,0xbb,0xbb, + 0xbb,0xdc,0x7e,0x7e,0x7e,0xc7,0x9c,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0xa1,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x8b,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc, + 0xdc,0xeb,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x81,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xa9,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff, + 0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x81,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xb0,0x00,0x00,0x00,0xb3,0x03,0x90,0x90,0x90,0xcc,0xf7,0xf7,0xf7,0xfa, + 0xef,0xef,0xef,0xf5,0x52,0x52,0x52,0xbd,0xbd,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00, + 0xb3,0x02,0xdc,0xdc,0xdc,0xeb,0xff,0xff,0xff,0xff,0xaf,0xaf,0xaf,0xd6,0xbc,0x00,0x00,0x00,0xb3,0x02,0xaf,0xaf,0xaf,0xd6,0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0xeb, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xdd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xe5,0x00,0x00,0x00,0xb3,0x00,0xa0, + 0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0xa1,0x00,0x00,0x00,0xb3,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0x88,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0, + 0xd1,0xd2,0xd2,0xd2,0xe6,0x81,0xdc,0xdc,0xdc,0xeb,0x8b,0x00,0x00,0x00,0xb3,0x81,0xaf,0xaf,0xaf,0xd6,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e, + 0xc7,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0xa9,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x81, + 0xaf,0xaf,0xaf,0xd6,0x00,0xa0,0xa0,0xa0,0xd1,0xf2,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x81,0xaf,0xaf,0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xa7,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbb,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a, + 0x6a,0xc2,0x82,0xaf,0xaf,0xaf,0xd6,0x01,0x90,0x90,0x90,0xcc,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x89,0x00,0x00,0x00,0xb3,0x01, + 0x6a,0x6a,0x6a,0xc2,0xa0,0xa0,0xa0,0xd1,0x82,0xaf,0xaf,0xaf,0xd6,0x00,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xcb,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33, + 0xb8,0x7e,0x7e,0x7e,0xc7,0x83,0xaf,0xaf,0xaf,0xd6,0x01,0x7e,0x7e,0x7e,0xc7,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x8b,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00, + 0x00,0xb3,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x01, + 0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0x8a,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a, + 0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xef,0xef,0xef,0xf5,0x84,0xff,0xff,0xff,0xff,0x04,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x6a, + 0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x88,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xe6,0xe6,0xe6,0xf0,0x85, + 0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff, + 0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x8b,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x91,0x00,0x00,0x00,0xb3,0x82,0xff, + 0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x86,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0x00,0x00,0x00, + 0xb3,0x00,0x90,0x90,0x90,0xcc,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x88,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x02, + 0xc7,0xc7,0xc7,0xe1,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8, + 0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x02,0xd2,0xd2,0xd2,0xe6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x85,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e, + 0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x84,0xff,0xff,0xff,0xff,0x85,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xc7,0xc7,0xc7,0xe1,0x87,0xff,0xff,0xff,0xff,0x02,0xef,0xef, + 0xef,0xf5,0xbb,0xbb,0xbb,0xdc,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x8b,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff, + 0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x87,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3, + 0x8a,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff, + 0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90, + 0xcc,0x88,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf, + 0xaf,0xaf,0xd6,0x89,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6, + 0xf0,0x87,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82, + 0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x8b,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e, + 0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x90,0x00,0x00,0x00,0xb3, + 0x00,0x90,0x90,0x90,0xcc,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x85,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x00,0x52, + 0x52,0x52,0xbd,0x83,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x86,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52, + 0xbd,0x83,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00, + 0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x85,0x00, + 0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x8c,0xff,0xff,0xff,0xff, + 0x00,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x82,0x00,0x00,0x00,0xb3,0x8b,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00, + 0x6a,0x6a,0x6a,0xc2,0x85,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00, + 0xb3,0x8a,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82, + 0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x88,0x00,0x00,0x00,0xb3,0x01,0x33,0x33, + 0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xe6,0xe6,0xe6,0xf0,0x86,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x33,0x33, + 0x33,0xb8,0x88,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x88,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x85,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa, + 0x82,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00, + 0x00,0x00,0xb3,0x8b,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x90,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x83,0xff,0xff,0xff,0xff,0x00, + 0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x83,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf, + 0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x83,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00, + 0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x85,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x85,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x85,0xff,0xff, + 0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x8d,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef, + 0xf5,0x87,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x85, + 0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef, + 0xef,0xf5,0x86,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x88,0x00,0x00,0x00,0xb3,0x00,0xa0, + 0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xef,0xef,0xef,0xf5,0x83, + 0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x8a,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0xf7,0xf7,0xf7,0xfa,0x04,0xa0,0xa0,0xa0, + 0xd1,0x33,0x33,0x33,0xb8,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x85,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xef, + 0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff, + 0xff,0x00,0xef,0xef,0xef,0xf5,0x87,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x90,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x83,0xff,0xff, + 0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x83,0x00,0x00,0x00,0xb3, + 0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x85,0x7e,0x7e,0x7e,0xc7,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff, + 0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3, + 0x00,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x84,0x00,0x00,0x00,0xb3,0x00, + 0x90,0x90,0x90,0xcc,0x86,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x02,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf, + 0xd6,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x02,0x6a,0x6a,0x6a,0xc2,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00, + 0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8a,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x8d,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xe6, + 0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8c,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3, + 0x00,0x33,0x33,0x33,0xb8,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x8d,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff, + 0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x8f,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x84,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x83,0x00,0x00, + 0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x84,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x84,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x8c,0xff,0xff,0xff,0xff, + 0x00,0xf7,0xf7,0xf7,0xfa,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a, + 0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x01,0x33,0x33, + 0x33,0xb8,0xef,0xef,0xef,0xf5,0x86,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x33, + 0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x8b,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x8b,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x82, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x88,0x00,0x00,0x00,0xb3, + 0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x85,0xff,0xff,0xff,0xff,0x00,0x7e, + 0x7e,0x7e,0xc7,0x91,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7, + 0xe1,0x8b,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e, + 0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x8f,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x85, + 0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00, + 0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x8c,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e, + 0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff, + 0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff, + 0xff,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x83,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x86, + 0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcc,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8b,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x8b,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x83,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x88,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff, + 0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff, + 0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x8f,0x00,0x00,0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xd2, + 0xd2,0xd2,0xe6,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x8b,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf, + 0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x00, + 0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x8f,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x81,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3, + 0x00,0xe6,0xe6,0xe6,0xf0,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8b,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff, + 0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x83,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7, + 0xf7,0xf7,0xfa,0x90,0x90,0x90,0xcc,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff, + 0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x83,0xff, + 0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff, + 0x00,0xc7,0xc7,0xc7,0xe1,0x87,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff, + 0xff,0x86,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00, + 0xf7,0xf7,0xf7,0xfa,0x86,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x84,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0x52,0x52, + 0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x83,0x00,0x00,0x00,0xb3,0x82, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0x00,0x00,0x00,0xb3, + 0x00,0xd2,0xd2,0xd2,0xe6,0x83,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0xff,0xff,0xff,0xff,0x01,0xa0,0xa0,0xa0,0xd1,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff, + 0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x8c,0x00,0x00,0x00,0xb3,0x02,0x90,0x90,0x90,0xcc,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x00,0xa0, + 0xa0,0xa0,0xd1,0x83,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33, + 0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x83,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x86,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x85,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00, + 0x33,0x33,0x33,0xb8,0x8d,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x82,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0xc7,0xc7,0xc7,0xe1,0x81,0xff,0xff,0xff, + 0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x82,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0xd2,0xd2,0xd2,0xe6,0x81,0xff, + 0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x84,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x88,0xff,0xff,0xff,0xff,0x01, + 0xe6,0xe6,0xe6,0xf0,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00, + 0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff, + 0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x02,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff, + 0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb, + 0x85,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x8a,0xff,0xff,0xff, + 0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x84,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x89,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xe6,0xe6,0xe6,0xf0,0x86,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6, + 0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0x00,0x00,0x00,0xb3,0x01,0x90,0x90,0x90,0xcc,0xef,0xef,0xef,0xf5,0x86,0xff,0xff,0xff,0xff,0x00, + 0xc7,0xc7,0xc7,0xe1,0x84,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0, + 0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0x00,0x00,0x00,0xb3,0x8a,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x89,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x83,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x8d,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0, + 0xd1,0x82,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x90,0x90,0x90,0xcc,0x82,0xff,0xff,0xff,0xff,0x02,0x52,0x52,0x52,0xbd,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf, + 0xd6,0x82,0xff,0xff,0xff,0xff,0x01,0x52,0x52,0x52,0xbd,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0xef, + 0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff, + 0x00,0x6a,0x6a,0x6a,0xc2,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x8a,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0x33,0x33,0x33,0xb8,0x81,0x00,0x00, + 0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x33,0x33,0x33,0xb8,0xef,0xef,0xef,0xf5,0x82,0xff,0xff, + 0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e, + 0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00, + 0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x02,0x90,0x90,0x90,0xcc,0x00,0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0xff,0xff,0xff,0xff, + 0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x8a,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e, + 0xc7,0x84,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6, + 0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8b, + 0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52, + 0xbd,0x83,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xaf,0xaf,0xaf,0xd6,0x85,0x00, + 0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x81,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0, + 0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x89,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00, + 0x00,0x00,0xb3,0x8a,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x88,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x84,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x8c,0x00,0x00,0x00,0xb3,0x00,0xc7, + 0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00, + 0x00,0x00,0xb3,0xdc,0xdc,0xdc,0xeb,0x81,0xff,0xff,0xff,0xff,0x02,0xe6,0xe6,0xe6,0xf0,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00,0x00,0xb3,0x90,0x90,0x90,0xcc,0x82, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x8b,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00, + 0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff,0xff,0x02,0x6a, + 0x6a,0x6a,0xc2,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82, + 0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xb3,0x33,0x33,0x33, + 0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x81,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0xff,0xff,0xff, + 0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7, + 0xf7,0xfa,0x86,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x85,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7, + 0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x85,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00, + 0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x8b,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x8d,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x84,0xff, + 0xff,0xff,0xff,0x03,0xf7,0xf7,0xf7,0xfa,0xc7,0xc7,0xc7,0xe1,0x90,0x90,0x90,0xcc,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff, + 0xff,0xff,0xff,0x01,0x7e,0x7e,0x7e,0xc7,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x85,0xaf,0xaf,0xaf,0xd6,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xf7, + 0xf7,0xf7,0xfa,0x86,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x88,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x85,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x8b,0x00,0x00,0x00,0xb3,0x00,0xf7, + 0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6, + 0xf0,0x33,0x33,0x33,0xb8,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xd2, + 0xd2,0xd2,0xe6,0x84,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x82,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0xd2,0xd2,0xd2,0xe6,0x82, + 0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0x7e,0x7e, + 0x7e,0xc7,0x01,0x90,0x90,0x90,0xcc,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82, + 0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0x52,0x52,0x52,0xbd,0x83,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e, + 0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xb3,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7, + 0xfa,0x52,0x52,0x52,0xbd,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0xaf,0xaf,0xaf,0xd6,0x00,0x52,0x52,0x52,0xbd,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xcc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82, + 0xff,0xff,0xff,0xff,0x86,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff, + 0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x82,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xbb,0xbb,0xbb,0xdc,0x82, + 0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x7e,0x7e,0x7e,0xc7,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x01,0xbb,0xbb,0xbb,0xdc,0xf7,0xf7, + 0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x8c,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa, + 0xaf,0xaf,0xaf,0xd6,0x8b,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x82,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff, + 0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x82, + 0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00, + 0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a, + 0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x81,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff, + 0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff, + 0x85,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x85,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff, + 0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x01,0xaf,0xaf,0xaf,0xd6,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff, + 0xff,0x01,0xef,0xef,0xef,0xf5,0x33,0x33,0x33,0xb8,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff, + 0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd9,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8e,0x00, + 0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8, + 0x85,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xc7,0xc7,0xc7,0xe1,0x82,0xff,0xff,0xff,0xff,0x03,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7, + 0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x8c,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x8d, + 0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33, + 0xb8,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00, + 0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x01,0x33,0x33, + 0x33,0xb8,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x02,0xa0,0xa0,0xa0,0xd1,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a, + 0x6a,0xc2,0x89,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8, + 0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff, + 0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x84,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff, + 0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00, + 0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x02,0x7e,0x7e,0x7e,0xc7,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5, + 0x83,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff, + 0xff,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x81, + 0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x83,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd8,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3, + 0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8e,0x00, + 0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x86,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc, + 0xeb,0x89,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff, + 0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x8c,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff, + 0x00,0xc7,0xc7,0xc7,0xe1,0x83,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff, + 0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0x00,0x00,0x00,0xb3, + 0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x8d,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00, + 0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff, + 0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x89,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0x00,0x00,0x00,0xb3,0x00, + 0xd2,0xd2,0xd2,0xe6,0x84,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb, + 0xbb,0xdc,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0xff,0xff,0xff,0xff,0x00,0x33,0x33,0x33,0xb8,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x83,0x00,0x00,0x00,0xb3,0x01,0x6a,0x6a,0x6a,0xc2,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x02,0x6a,0x6a, + 0x6a,0xc2,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x86,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff, + 0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00, + 0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x83,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x82, + 0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x7e,0x7e,0x7e,0xc7,0x85,0x00,0x00,0x00,0xb3,0x01,0xbb,0xbb,0xbb, + 0xdc,0xa0,0xa0,0xa0,0xd1,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcf,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf, + 0xd6,0x82,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x86,0xdc,0xdc,0xdc,0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0x87,0x00,0x00,0x00,0xb3,0x00, + 0xef,0xef,0xef,0xf5,0x84,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x86,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00, + 0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x83,0xdc,0xdc,0xdc,0xeb,0x00,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x84,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3, + 0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00, + 0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff, + 0xff,0x8c,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x83,0xff,0xff,0xff,0xff,0x06,0xc7,0xc7,0xc7,0xe1,0x90,0x90,0x90,0xcc,0x7e,0x7e,0x7e,0xc7,0xaf,0xaf,0xaf, + 0xd6,0xef,0xef,0xef,0xf5,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x87,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x84,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52, + 0xbd,0x86,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xe6,0xe6,0xe6,0xf0,0x86,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x81, + 0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x86,0xdc,0xdc,0xdc,0xeb,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2, + 0x83,0xdc,0xdc,0xdc,0xeb,0x00,0xe6,0xe6,0xe6,0xf0,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x83,0xdc,0xdc,0xdc,0xeb,0x02,0xa0,0xa0,0xa0,0xd1,0x00,0x00, + 0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x83,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0x00,0x00,0x00,0xb3,0x00,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00, + 0xaf,0xaf,0xaf,0xd6,0x87,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x82,0xff,0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x83,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0, + 0xa0,0xd1,0x84,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0x83,0x00,0x00,0x00,0xb3,0x00,0xf7,0xf7,0xf7,0xfa,0x81,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5, + 0x85,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x84,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7,0xc7,0xe1,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff, + 0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xaf,0xaf,0xaf,0xd6,0x01,0xc7,0xc7,0xc7,0xe1,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5, + 0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x52,0x52,0x52,0xbd,0x83,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e, + 0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x85,0xff,0xff,0xff,0xff,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff, + 0xff,0xff,0xff,0x82,0x00,0x00,0x00,0xb3,0x01,0x52,0x52,0x52,0xbd,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x01,0xc7,0xc7,0xc7,0xe1,0xa0,0xa0,0xa0,0xd1,0x81, + 0x7e,0x7e,0x7e,0xc7,0x01,0xaf,0xaf,0xaf,0xd6,0xef,0xef,0xef,0xf5,0x81,0xff,0xff,0xff,0xff,0x00,0x90,0x90,0x90,0xcc,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xce,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86, + 0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3,0x8a,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc, + 0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x83,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x87,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff, + 0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8c,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff, + 0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0, + 0xd1,0x83,0xff,0xff,0xff,0xff,0x01,0xdc,0xdc,0xdc,0xeb,0xef,0xef,0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x8d,0x00,0x00,0x00,0xb3,0x00,0xbb, + 0xbb,0xbb,0xdc,0x88,0xff,0xff,0xff,0xff,0x01,0xe6,0xe6,0xe6,0xf0,0x33,0x33,0x33,0xb8,0x86,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x83,0xff,0xff,0xff,0xff, + 0x00,0xd2,0xd2,0xd2,0xe6,0x87,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3,0x8a,0xff, + 0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x8c,0xff,0xff,0xff,0xff,0x02,0xaf,0xaf,0xaf,0xd6,0x00,0x00,0x00,0xb3,0xef,0xef, + 0xef,0xf5,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x83,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x83,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd, + 0x86,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0xff,0xff,0xff,0xff,0x00,0xd2,0xd2,0xd2,0xe6,0x83,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x83,0xff, + 0xff,0xff,0xff,0x00,0xf7,0xf7,0xf7,0xfa,0x84,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0x52,0x52,0x52,0xbd,0x85,0x00,0x00,0x00, + 0xb3,0x00,0xef,0xef,0xef,0xf5,0x83,0xff,0xff,0xff,0xff,0x00,0x6a,0x6a,0x6a,0xc2,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x8b,0xff,0xff,0xff,0xff,0x00, + 0x90,0x90,0x90,0xcc,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x85,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e, + 0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x33,0x33,0x33,0xb8,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x8b,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x7e,0x7e,0x7e,0xc7,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc, + 0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00,0x00,0x00,0xb3, + 0x8a,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e, + 0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x8c,0xff,0xff,0xff,0xff, + 0x81,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf, + 0xaf,0xaf,0xd6,0x8b,0x00,0x00,0x00,0xb3,0x00,0xe6,0xe6,0xe6,0xf0,0x86,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0x6a,0x6a,0x6a,0xc2,0x8e,0x00,0x00,0x00,0xb3, + 0x00,0xd2,0xd2,0xd2,0xe6,0x88,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x86,0x00,0x00,0x00,0xb3,0x01,0x33,0x33,0x33,0xb8,0xf7,0xf7,0xf7,0xfa,0x82,0xff,0xff, + 0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x87,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x8a,0xff,0xff,0xff,0xff,0x00,0x7e,0x7e,0x7e,0xc7,0x81,0x00,0x00,0x00,0xb3, + 0x8a,0xff,0xff,0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0x00,0x00,0x00,0xb3,0x7e,0x7e,0x7e,0xc7,0x8c,0xff,0xff,0xff,0xff,0x81,0xaf,0xaf,0xaf,0xd6,0x83,0xff,0xff,0xff, + 0xff,0x00,0x52,0x52,0x52,0xbd,0x84,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x00, + 0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x84,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xff,0xff,0xff,0xff,0x00,0xc7,0xc7, + 0xc7,0xe1,0x84,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6, + 0x82,0xff,0xff,0xff,0xff,0x00,0xdc,0xdc,0xdc,0xeb,0x87,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x89,0xff,0xff,0xff,0xff,0x01,0xf7,0xf7,0xf7,0xfa,0xa0,0xa0, + 0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0xff,0xff,0xff,0xff,0x00,0xef,0xef,0xef,0xf5,0x85,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7, + 0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0x00,0x00,0x00,0xb3,0x00,0x7e,0x7e,0x7e,0xc7,0x82,0xff,0xff,0xff,0xff,0x00,0xaf,0xaf,0xaf,0xd6,0x82,0x00, + 0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x84,0xff,0xff,0xff,0xff,0x00,0xa0,0xa0,0xa0,0xd1,0x85,0x00,0x00,0x00,0xb3,0x00,0xdc,0xdc,0xdc,0xeb,0x82,0xff,0xff,0xff, + 0xff,0x84,0x00,0x00,0x00,0xb3,0x01,0x7e,0x7e,0x7e,0xc7,0xef,0xef,0xef,0xf5,0x89,0xff,0xff,0xff,0xff,0x01,0xef,0xef,0xef,0xf5,0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xcd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd0,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc, + 0x82,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x8a,0xdc, + 0xdc,0xdc,0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf,0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xd2,0xd2,0xd2,0xe6,0x88,0x00,0x00,0x00, + 0xb3,0x82,0xdc,0xdc,0xdc,0xeb,0x00,0xbb,0xbb,0xbb,0xdc,0x84,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x8c,0xdc,0xdc,0xdc,0xeb,0x81,0x00,0x00,0x00,0xb3,0x00, + 0xbb,0xbb,0xbb,0xdc,0x82,0xdc,0xdc,0xdc,0xeb,0x86,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x8b,0x00,0x00, + 0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xf7,0xf7,0xf7,0xfa,0x83,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x6a,0x6a,0x6a,0xc2,0x90,0x00,0x00, + 0x00,0xb3,0x01,0xa0,0xa0,0xa0,0xd1,0xe6,0xe6,0xe6,0xf0,0x84,0xff,0xff,0xff,0xff,0x01,0xd2,0xd2,0xd2,0xe6,0x7e,0x7e,0x7e,0xc7,0x88,0x00,0x00,0x00,0xb3,0x00,0xaf, + 0xaf,0xaf,0xd6,0x81,0xdc,0xdc,0xdc,0xeb,0x00,0xd2,0xd2,0xd2,0xe6,0x88,0x00,0x00,0x00,0xb3,0x00,0xa0,0xa0,0xa0,0xd1,0x8a,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a, + 0xc2,0x81,0x00,0x00,0x00,0xb3,0x8a,0xdc,0xdc,0xdc,0xeb,0x02,0xbb,0xbb,0xbb,0xdc,0x00,0x00,0x00,0xb3,0x6a,0x6a,0x6a,0xc2,0x8c,0xdc,0xdc,0xdc,0xeb,0x00,0xaf,0xaf, + 0xaf,0xd6,0x83,0xdc,0xdc,0xdc,0xeb,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00,0xb3,0x00,0x52,0x52,0x52,0xbd,0x83,0xdc,0xdc,0xdc,0xeb,0x00,0x7e,0x7e,0x7e,0xc7, + 0x85,0x00,0x00,0x00,0xb3,0x00,0xd2,0xd2,0xd2,0xe6,0x82,0xdc,0xdc,0xdc,0xeb,0x00,0x6a,0x6a,0x6a,0xc2,0x84,0x00,0x00,0x00,0xb3,0x00,0x90,0x90,0x90,0xcc,0x82,0xdc, + 0xdc,0xdc,0xeb,0x00,0x7e,0x7e,0x7e,0xc7,0x84,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xdc,0xdc,0xdc,0xeb,0x00,0xaf,0xaf,0xaf,0xd6,0x85,0x00,0x00,0x00, + 0xb3,0x00,0x33,0x33,0x33,0xb8,0x82,0xdc,0xdc,0xdc,0xeb,0x00,0x90,0x90,0x90,0xcc,0x87,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x87,0xdc,0xdc,0xdc,0xeb,0x02, + 0xbb,0xbb,0xbb,0xdc,0xa0,0xa0,0xa0,0xd1,0x33,0x33,0x33,0xb8,0x83,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x84,0xdc,0xdc,0xdc,0xeb,0x00,0x7e,0x7e,0x7e,0xc7, + 0x85,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xdc,0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x81,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x82,0xdc, + 0xdc,0xdc,0xeb,0x00,0xa0,0xa0,0xa0,0xd1,0x82,0x00,0x00,0x00,0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x83,0xdc,0xdc,0xdc,0xeb,0x00,0xc7,0xc7,0xc7,0xe1,0x86,0x00,0x00,0x00, + 0xb3,0x00,0xbb,0xbb,0xbb,0xdc,0x82,0xdc,0xdc,0xdc,0xeb,0x85,0x00,0x00,0x00,0xb3,0x02,0x33,0x33,0x33,0xb8,0xaf,0xaf,0xaf,0xd6,0xe6,0xe6,0xe6,0xf0,0x85,0xff,0xff, + 0xff,0xff,0x02,0xdc,0xdc,0xdc,0xeb,0xa0,0xa0,0xa0,0xd1,0x33,0x33,0x33,0xb8,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xce,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xbd,0x00,0x00,0x00,0xb3,0x00,0x6a,0x6a,0x6a,0xc2,0x81,0x7e,0x7e,0x7e,0xc7,0x00,0x33,0x33,0x33, + 0xb8,0x94,0x00,0x00,0x00,0xb3,0x00,0x33,0x33,0x33,0xb8,0x82,0x7e,0x7e,0x7e,0xc7,0xff,0x00,0x00,0x00,0xb3,0xcd,0x00,0x00,0x00,0xb3,0x82,0x7e,0x7e,0x7e,0xc7,0x00, + 0x6a,0x6a,0x6a,0xc2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xd2,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x02,0x04,0x04,0x13,0xb7,0x20,0x24,0xa9,0xdf,0x26,0x2e,0xd7,0xef,0x91,0x28,0x2f,0xd9,0xf0,0x02,0x26,0x2e,0xd7,0xef,0x1f,0x25, + 0xa8,0xde,0x04,0x04,0x13,0xb7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x23,0x28,0xbb,0xe5,0x95,0x2e,0x37,0xff,0xff,0x00,0x22,0x27,0xb6,0xe4,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xf2,0x00,0x00,0x00,0xb3,0x00,0x2d,0x35,0xf7,0xfb,0x88,0x2e,0x37,0xff,0xff,0x00,0x26,0x2b,0xcb,0xea,0x81,0x20,0x25,0xad,0xe1,0x00,0x26,0x2b,0xcc,0xea,0x88,0x2e, + 0x37,0xff,0xff,0x00,0x2c,0x34,0xf2,0xf9,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x28,0x30,0xde,0xf1,0x87,0x2e,0x37,0xff,0xff,0x00,0x24,0x2b,0xc4,0xe8,0x83, + 0x00,0x00,0x00,0xb3,0x00,0x25,0x2a,0xc7,0xea,0x87,0x2e,0x37,0xff,0xff,0x00,0x26,0x2e,0xd7,0xef,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xf4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf2,0x00,0x00,0x00,0xb3,0x00,0x13,0x17,0x68,0xcb, + 0x87,0x2e,0x37,0xff,0xff,0x00,0x1f,0x25,0xab,0xe0,0x83,0x00,0x00,0x00,0xb3,0x00,0x1f,0x25,0xab,0xe0,0x87,0x2e,0x37,0xff,0xff,0x00,0x13,0x16,0x61,0xca,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf4,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xf3,0x00,0x00,0x00,0xb3,0x00,0x25,0x2c,0xcd,0xec,0x86,0x2e,0x37,0xff,0xff,0x01,0x26,0x2d,0xd2,0xed,0x01,0x01,0x05,0xb4,0x81,0x00,0x00,0x00,0xb3,0x01,0x01, + 0x01,0x06,0xb4,0x27,0x2e,0xd6,0xef,0x86,0x2e,0x37,0xff,0xff,0x00,0x26,0x2b,0xcb,0xea,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xf5,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf3,0x00,0x00,0x00,0xb3,0x01,0x0d,0x0e,0x40,0xc1,0x2e,0x37, + 0xfd,0xfe,0x86,0x2e,0x37,0xff,0xff,0x00,0x2b,0x31,0xe9,0xf5,0x81,0x28,0x2f,0xd9,0xf0,0x00,0x2b,0x31,0xe9,0xf6,0x86,0x2e,0x37,0xff,0xff,0x01,0x2d,0x36,0xfc,0xfe, + 0x0c,0x0d,0x3b,0xc0,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf5,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf4,0x00,0x00,0x00,0xb3,0x00,0x20,0x26,0xb0,0xe1,0x91,0x2e,0x37,0xff,0xff,0x00,0x20,0x24,0xa9,0xdf,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf4,0x00, + 0x00,0x00,0xb3,0x01,0x06,0x07,0x1e,0xb9,0x2c,0x34,0xf4,0xfb,0x84,0x2e,0x37,0xff,0xff,0x01,0x2e,0x37,0xfe,0xff,0x24,0x2b,0xc5,0xe8,0x81,0x20,0x25,0xad,0xe1,0x00, + 0x25,0x2a,0xc6,0xe9,0x85,0x2e,0x37,0xff,0xff,0x01,0x2c,0x34,0xf2,0xfa,0x05,0x06,0x1b,0xb9,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xf6,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf5,0x00,0x00,0x00,0xb3,0x00,0x19,0x1f,0x8b,0xd5,0x84, + 0x2e,0x37,0xff,0xff,0x00,0x24,0x2a,0xc4,0xe8,0x83,0x00,0x00,0x00,0xb3,0x00,0x25,0x2a,0xc7,0xe9,0x84,0x2e,0x37,0xff,0xff,0x00,0x19,0x1d,0x85,0xd4,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf7,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xf5,0x00,0x00,0x00,0xb3,0x01,0x02,0x02,0x09,0xb5,0x2a,0x30,0xe4,0xf4,0x83,0x2e,0x37,0xff,0xff,0x00,0x1f,0x25,0xab,0xe0,0x83,0x00,0x00,0x00,0xb3,0x00,0x1f,0x25, + 0xab,0xe0,0x83,0x2e,0x37,0xff,0xff,0x01,0x29,0x31,0xe2,0xf3,0x01,0x01,0x06,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf7, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf6,0x00,0x00,0x00,0xb3,0x00,0x13,0x16,0x62,0xca,0x83,0x2e,0x37, + 0xff,0xff,0x00,0x1f,0x25,0xab,0xe0,0x83,0x00,0x00,0x00,0xb3,0x00,0x1f,0x25,0xab,0xe0,0x83,0x2e,0x37,0xff,0xff,0x00,0x11,0x14,0x5c,0xc8,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf8,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf7,0x00, + 0x00,0x00,0xb3,0x00,0x26,0x2b,0xcc,0xea,0x82,0x2e,0x37,0xff,0xff,0x00,0x1f,0x25,0xab,0xe0,0x83,0x00,0x00,0x00,0xb3,0x00,0x1f,0x25,0xab,0xe0,0x82,0x2e,0x37,0xff, + 0xff,0x00,0x24,0x2b,0xc5,0xe9,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf9,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf7,0x00,0x00,0x00,0xb3,0x01,0x0c,0x0d,0x3b,0xc0,0x2d,0x36,0xfc,0xfe,0x81,0x2e,0x37,0xff,0xff,0x00,0x1f,0x25,0xab, + 0xe0,0x83,0x00,0x00,0x00,0xb3,0x00,0x1f,0x25,0xab,0xe0,0x81,0x2e,0x37,0xff,0xff,0x01,0x2d,0x36,0xfb,0xfe,0x0a,0x0c,0x36,0xbf,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf9,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf8,0x00,0x00,0x00, + 0xb3,0x00,0x20,0x24,0xa9,0xdf,0x81,0x2e,0x37,0xff,0xff,0x00,0x21,0x26,0xb2,0xe2,0x83,0x00,0x00,0x00,0xb3,0x00,0x21,0x26,0xb2,0xe2,0x81,0x2e,0x37,0xff,0xff,0x00, + 0x1f,0x24,0xa4,0xde,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfa,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf8,0x00,0x00,0x00,0xb3,0x04,0x05,0x06,0x1b,0xb9,0x2c,0x34,0xf3,0xfa,0x2e,0x37,0xff,0xff,0x2c,0x34,0xf3,0xfa,0x14,0x16,0x65, + 0xcb,0x81,0x0d,0x0f,0x44,0xc2,0x04,0x14,0x17,0x67,0xcb,0x2c,0x34,0xf4,0xfb,0x2e,0x37,0xff,0xff,0x2b,0x33,0xf1,0xf9,0x05,0x05,0x17,0xb8,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfa,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf9,0x00, + 0x00,0x00,0xb3,0x00,0x19,0x1d,0x85,0xd4,0x87,0x2e,0x37,0xff,0xff,0x00,0x18,0x1c,0x81,0xd2,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xfb,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xf9,0x00,0x00,0x00,0xb3,0x01,0x02,0x02,0x07,0xb4,0x29, + 0x31,0xe2,0xf3,0x85,0x2e,0x37,0xff,0xff,0x01,0x28,0x30,0xdf,0xf2,0x01,0x01,0x05,0xb4,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xfb,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfa,0x00,0x00,0x00,0xb3,0x00,0x12,0x14,0x5d,0xc8,0x85,0x2e, + 0x37,0xff,0xff,0x00,0x10,0x13,0x56,0xc7,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfc,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfb,0x00,0x00,0x00,0xb3,0x00,0x25,0x2a,0xc6,0xe9,0x83,0x2e,0x37,0xff,0xff,0x00,0x23,0x2a,0xc2,0xe7,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xfb,0x00,0x00,0x00,0xb3,0x01,0x0a,0x0c,0x36,0xbf,0x2e,0x36,0xf9,0xfc,0x81,0x2e,0x37,0xff,0xff,0x01,0x2c,0x35,0xf8,0xfc,0x09,0x0a,0x30,0xbd,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xfd,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xfc,0x00,0x00,0x00,0xb3,0x03,0x10,0x12,0x52,0xc6,0x25,0x2a,0xc7,0xe9,0x25,0x2a,0xc6,0xe9,0x0f,0x10,0x4d,0xc5,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xfe,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff, + 0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00, + 0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3, + 0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00, + 0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00, + 0xb3,0xff,0x00,0x00,0x00,0xb3,0xff,0x00,0x00,0x00,0xb3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x52,0x55,0x45,0x56,0x49,0x53,0x49,0x4f,0x4e,0x2d,0x58,0x46, + 0x49,0x4c,0x45,0x2e,0x00 +}; diff --git a/LibOVR/Src/Displays/OVR_Display.cpp b/LibOVR/Src/Displays/OVR_Display.cpp new file mode 100644 index 0000000..55eb8a9 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Display.cpp @@ -0,0 +1,36 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_Display.cpp +Content : Common implementation for display device +Created : May 6, 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_Display.h" + +namespace OVR { + + +// Place platform-independent code here + + +} // namespace OVR diff --git a/LibOVR/Src/Displays/OVR_Display.h b/LibOVR/Src/Displays/OVR_Display.h new file mode 100644 index 0000000..46e9f13 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Display.h @@ -0,0 +1,203 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_Display.h +Content : Contains platform independent display management +Created : May 6, 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_Display_h +#define OVR_Display_h + +#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" + +namespace OVR { + + +class DisplaySearchHandle : virtual public RefCountBaseV +{ +public: + DisplaySearchHandle() {} + + virtual ~DisplaySearchHandle() {} + + void operator= (const DisplaySearchHandle&) {} +}; + +//------------------------------------------------------------------------------------- +// ***** Display + +// Display object describes an Oculus HMD screen in LibOVR, providing information such +// as EDID serial number and resolution in platform-independent manner. +// +// Display is an abstract base class to support OS and driver specific implementations. +// It support HMD screen enumeration through GetDisplayCount/GetDisplay static functions. +// +// Examples of implementations of Display are the following: +// Display_Win32_Generic - Compatibly mode implementation that maintains operation on +// systems without drivers. +// Display_Win32_Driver - Driver-Based display +// Display_OSX_Generic - Additional compatibility mode implementation for OS X + +class Display : public RefCountBase +{ +protected: + enum MirrorMode + { + MirrorEnabled = 0, + MirrorDisabled = 1 + }; + + MirrorMode mirrorMode; + + Display( + HmdTypeEnum deviceTypeGuess, +#ifdef OVR_OS_MAC + uint32_t displayID, +#else + const String& displayID, +#endif + const String& modelName, + const String& editSerial, + const Sizei& logicalRes, + const Sizei& nativeRes, + const Vector2i& displayOffset, + const uint64_t devNumber, + const uint32_t rotation, + const bool appExclusive): + mirrorMode(MirrorDisabled), + DeviceTypeGuess(deviceTypeGuess), + DisplayID(displayID), + ModelName(modelName), + EdidSerialNumber(editSerial), + LogicalResolutionInPixels(logicalRes), + NativeResolutionInPixels(nativeRes), + DesktopDisplayOffset(displayOffset), + DeviceNumber(devNumber), + Rotation(rotation), + ApplicationExclusive(appExclusive) + { + } + + void operator = (const Display&) { } // Quiet warning. + +public: + virtual ~Display() { } + + // ----- Platform specific static Display functionality ----- + + // Mandatory function that sets up the display environment with + // 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(); + + // Returns a count of the detected displays. These are Rift displays + // attached directly to an active display port + static int GetDisplayCount( DisplaySearchHandle* handle = NULL, bool extended = true, bool applicationOnly = true, bool extendedEDIDSerials = false ); + // Returns a specific index of a display. Displays are sorted in no particular order. + static Ptr GetDisplay( int index = 0, DisplaySearchHandle* handle = NULL ); + + + // 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); + } + + + // ----- Device independent instance based Display functionality ----- + + // Device type guess based on display info. + const HmdTypeEnum DeviceTypeGuess; +#if defined(OVR_OS_MAC) + // CGDirectDisplayID for the rift. + const uint32_t DisplayID; +#else + // A string denoting the display device name so that apps can recognize the monitor + const String DisplayID; +#endif + // A literal string containing the name of the model, i.e. Rift DK2 + const String ModelName; + // Part of the serial number encoded in Edid, used for monitor <-> sensor matching. + const String EdidSerialNumber; + // Logical resolution is the display resolution in presentation terms. + // That is to say, the resolution that represents the orientation the + // display is projected to the user. For DK2, while being a portrait display + // the display is held in landscape and therefore the logical resolution + // is 1920x1080 + const Sizei LogicalResolutionInPixels; + // Native resolution is the resolution reported by the EDID and represents the + // exact hardware resolution of the Rift. For example, on DK2 + // this is 1080x1920 + // In theory, an OS rotated Rift's native and logical resolutions should match + const Sizei NativeResolutionInPixels; + // For displays that are attached to the desktop, this return value has meaning. + // Otherwise it should always return origin + const Vector2i DesktopDisplayOffset; + // For Windows machines this value stores the ChildUid used to identify this display + const uint64_t DeviceNumber; + // Stores the device specific default rotation of the screen + // E.g. DK2 is rotated 90 degrees as it is a portrait display + const uint32_t Rotation; + // Is set if the Display is capable in Application-Only mode + const bool ApplicationExclusive; + + // Functionality for rendering within the window + virtual MirrorMode SetMirrorMode( MirrorMode newMode ) = 0; + + // Functionality for enabling/disabling display + virtual bool SetDisplaySleep(bool off) + { + // Override to implement if supported + OVR_UNUSED(off); + return false; + } + + // Check if right now the current rendering application should be in compatibility mode + static bool InCompatibilityMode( bool displaySearch = true ); + + // Get/set the mode for all applications + static bool GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode); + static bool SetDriverMode(bool compatMode, bool hideDK1Mode); + + static DisplaySearchHandle* GetDisplaySearchHandle(); +}; + + +} // namespace OVR + +#endif diff --git a/LibOVR/Src/Displays/OVR_Linux_Display.cpp b/LibOVR/Src/Displays/OVR_Linux_Display.cpp new file mode 100644 index 0000000..4b840dd --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Linux_Display.cpp @@ -0,0 +1,494 @@ +/************************************************************************************ + +Filename : OVR_Linux_Display.cpp +Content : Linux-specific Display declarations +Created : July 2, 2014 +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 +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_Display.h" +#include "../Kernel/OVR_Log.h" + +#include "../../../3rdParty/EDID/edid.h" + +#include +#include +#include +#include + +//------------------------------------------------------------------------------------- +// ***** Display enumeration Helpers + +namespace OVR { + +static const uint8_t edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00 }; + +static const uint8_t edid_v1_descriptor_flag[] = { 0x00, 0x00 }; + +static const int DESCRIPTOR_DATA = 5; +static const int UNKNOWN_DESCRIPTOR = -1; +static const int DETAILED_TIMING_BLOCK = -2; + +// The following three functions were pulled from OVR_Linux_Display.cpp +// and modified slightly. +static int blockType(uint8_t* block) +{ + if (!strncmp((const char*)edid_v1_descriptor_flag, (const char*)block, 2)) + { + if (block[2] != 0) + { + return UNKNOWN_DESCRIPTOR; + } + else + { + return block[3]; + } + } + else + { + return DETAILED_TIMING_BLOCK; + } +} + +static char* getMonitorName(const uint8_t* block) +{ + static char name[13]; + uint8_t const* ptr = block + DESCRIPTOR_DATA; + + for (int i = 0; i < 13; i++, ptr++) + { + if (*ptr == 0xa) + { + name[i] = 0; + return name; + } + + name[i] = *ptr; + } + + return name; +} + +// Returns -1 on failure, 0 otherwise. +static int parseEdid(uint8_t* edid, Linux::DisplayEDID& edidResult) +{ + const int EDID_LENGTH = 0x80; + const int EDID_HEADER = 0x00; + const int EDID_HEADER_END = 0x07; + + // const int EDID_STRUCT_VERSION = 0x12; + // const int EDID_STRUCT_REVISION = 0x13; + + const int MONITOR_NAME = 0xfc; + // const int MONITOR_LIMITS = 0xfd; + const int MONITOR_SERIAL = 0xff; + + // const int ESTABLISHED_TIMING_1 = 0x23; + // const int ESTABLISHED_TIMING_2 = 0x24; + // const int MANUFACTURERS_TIMINGS = 0x25; + + const int DETAILED_TIMING_DESCRIPTIONS_START = 0x36; + const int DETAILED_TIMING_DESCRIPTION_SIZE = 18; + const int NO_DETAILED_TIMING_DESCRIPTIONS = 4; + + // const int DETAILED_TIMING_DESCRIPTION_1 = 0x36; + // const int DETAILED_TIMING_DESCRIPTION_2 = 0x48; + // const int DETAILED_TIMING_DESCRIPTION_3 = 0x5a; + // const int DETAILED_TIMING_DESCRIPTION_4 = 0x6c; + + const char* monitorName = "Unknown"; + uint8_t* block = NULL; + uint8_t checksum = 0; + + for (int i = 0; i < EDID_LENGTH; i++) + { + checksum += edid[i]; + } + + // Bad checksum, fail EDID + if (checksum != 0) + { + return -1; + } + + 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 -1; + } + + // Monitor name and timings + char serialNumber[14]; + memset(serialNumber, 0, 14); + + block = edid + DETAILED_TIMING_DESCRIPTIONS_START; + + for (int i = 0; i < NO_DETAILED_TIMING_DESCRIPTIONS; + i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) + { + + if (blockType(block) == MONITOR_NAME) + { + monitorName = getMonitorName(block); + } + + if (blockType(block) == MONITOR_SERIAL) + { + memcpy(serialNumber, block + 5, 13); + break; + } + } + + uint8_t 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_t*)&edid[10]; + edidResult.MonitorName = monitorName; + edidResult.VendorName = reinterpret_cast(vendorString); + edidResult.SerialNumber = serialNumber; + + // FIXME: Get timings as well + + // std::cout << "# EDID version " << static_cast(edid[EDID_STRUCT_VERSION]) + // << " revision " << static_cast(edid[EDID_STRUCT_REVISION]) + // << std::endl; + + return 0; +} + + +// Returns -1 in the case of failure, 0 otherwise. +// Parameters: +// 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, + uint8_t** data, int* dataLen) +{ + unsigned long nitems; + unsigned long bytesAfter; + int actualFormat; + Atom actualType; + + int ret = XRRGetOutputProperty(display, output, atom, 0, 100, + False, False, AnyPropertyType, + &actualType, &actualFormat, &nitems, + &bytesAfter, data); + + if (None != ret) + { + *dataLen = nitems; + return 0; + } + else + { + return -1; + } +} + +static XRRModeInfo* findModeByXID(XRRScreenResources* screen, RRMode xid) +{ + for (int m = 0; m < screen->nmode; ++m) + { + XRRModeInfo* mode = &screen->modes[m]; + if (xid == mode->id) + { + return mode; + } + } + return NULL; +} + +static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int inputArraySize, bool /*edidInfo*/) +{ + int result = 0; + + struct _XDisplay* display = XOpenDisplay(NULL); + + if (display == 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); + for (int i = 0; i < numScreens; ++i) + { + Window sr = XRootWindow(display, i); + XRRScreenResources* screen = XRRGetScreenResources(display, sr); + + for (int ii = 0; ii < screen->ncrtc; ++ii) + { + XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(display, screen, screen->crtcs[ii]); + + if (0 == crtcInfo->noutput) + { + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + bool foundOutput = false; + RROutput output = crtcInfo->outputs[0]; + for (int k = 0; k < crtcInfo->noutput; ++k) + { + XRROutputInfo* outputInfo = + XRRGetOutputInfo(display, screen, crtcInfo->outputs[k]); + + for (int kk = 0; kk < outputInfo->nmode; ++kk) + { + if (outputInfo->modes[kk] == crtcInfo->mode) + { + output = crtcInfo->outputs[k]; + foundOutput = true; + break; + } + } + XRRFreeOutputInfo(outputInfo); + if (foundOutput) + { + break; + } + } + + if (!foundOutput) + { + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + XRROutputInfo* outputInfo = XRRGetOutputInfo(display, screen, output); + if (RR_Connected != outputInfo->connection) + { + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + // Read EDID associated with crtc. + uint8_t* data = NULL; + int dataLen = 0; + if (getXRRProperty(display, output, EDIDAtom, &data, &dataLen) != 0) + { + // Identify rifts based on EDID. + Linux::DisplayEDID edid; + parseEdid(data, edid); + XFree(data); + data = NULL; + + // 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); + if (mi == NULL) + { + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + if (edid.VendorName == "OVR") + { + if( result >= inputArraySize ) + { + delete mi; + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); + return result; + } + + XRRModeInfo* modeInfo = findModeByXID(screen, crtcInfo->mode); + + 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; + + // Generate a device ID string similar Windows does it + char device_id[32]; + OVR_sprintf(device_id, 32, "%s%04d-%d", + 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); + desc.DesktopDisplayOffset = Vector2i(x, y); + + switch (mi->product_code) + { + 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; + } + + // Hard-coded defaults in case the device doesn't have the + // data itself. DK2 prototypes (0003) or DK HD Prototypes (0002). + if ( desc.DeviceTypeGuess == HmdType_DK2 + || desc.DeviceTypeGuess == HmdType_DKHDProto) + { + desc.LogicalResolutionInPixels = Sizei(1920, 1080); + desc.NativeResolutionInPixels = Sizei(1080, 1920); + } + else + { + desc.LogicalResolutionInPixels = Sizei(width, height); + desc.NativeResolutionInPixels = Sizei(width, height); + } + } + + delete mi; + mi = NULL; + } + + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); + } + + XRRFreeScreenResources(screen); + } + + XCloseDisplay(display); + + return result; +} + + +//------------------------------------------------------------------------------------- +// ***** Display + +bool Display::Initialize() +{ + // Nothing to initialize. OS X only supports compatibility mode. + return true; +} + +bool Display::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) +{ + driverInstalled = false; + compatMode = true; + hideDK1Mode = false; + return true; +} + +bool Display::SetDriverMode(bool /*compatMode*/, bool /*hideDK1Mode*/) +{ + return false; +} + +DisplaySearchHandle* Display::GetDisplaySearchHandle() +{ + return new Linux::LinuxDisplaySearchHandle(); +} + +bool Display::InCompatibilityMode( bool displaySearch ) +{ + OVR_UNUSED( displaySearch ); + return true; +} + +int Display::GetDisplayCount(DisplaySearchHandle* handle, bool extended, bool applicationOnly, bool edidInfo) +{ + OVR_UNUSED4(handle, extended, applicationOnly, edidInfo); + + static int extendedCount = -1; + + 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 (extendedCount == -1 || extended) + { + extendedCount = discoverExtendedRifts(localHandle->cachedDescriptorArray, Linux::LinuxDisplaySearchHandle::DescArraySize, edidInfo); + } + + localHandle->extended = true; + localHandle->extendedDisplayCount = extendedCount; + int totalCount = extendedCount; + + /// FIXME: Implement application mode for OS X. + localHandle->application = false; + localHandle->applicationDisplayCount = 0; + + localHandle->displayCount = totalCount; + + return totalCount; +} + + +Ptr Display::GetDisplay( int index, DisplaySearchHandle* handle ) +{ + Ptr result = NULL; + + if (index < 0) + { + OVR::LogError("[Linux Display] Invalid index given to GetDisplay."); + return NULL; + } + + Linux::LinuxDisplaySearchHandle* localHandle = (Linux::LinuxDisplaySearchHandle*)handle; + if (localHandle == NULL) + { + OVR::LogError("[Linux Display] No search handle passed into GetDisplay. Return 0 rifts."); + return NULL; + } + + if (localHandle->extended) + { + if (index >= 0 && index < (int)localHandle->extendedDisplayCount) + { + return *new Linux::LinuxDisplayGeneric(localHandle->cachedDescriptorArray[index]); + } + + index -= localHandle->extendedDisplayCount; + } + + if (localHandle->application) + { + OVR::LogError("[Linux Display] Mac does not support application displays."); + } + + return result; +} + + +} // namespace OVR diff --git a/LibOVR/Src/Displays/OVR_Linux_Display.h b/LibOVR/Src/Displays/OVR_Linux_Display.h new file mode 100644 index 0000000..f685e6b --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Linux_Display.h @@ -0,0 +1,133 @@ +/************************************************************************************ + +Filename : OVR_Linux_Display.h +Content : Linux-specific Display declarations +Created : July 2, 2014 +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 +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_Display_h +#define OVR_Linux_Display_h + +#include "OVR_Display.h" + +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 + +// Describes EDID information as reported from our display driver. +struct DisplayEDID +{ + DisplayEDID() : + ModelNumber(0) + {} + + String MonitorName; + UInt16 ModelNumber; + String VendorName; + String SerialNumber; +}; + + +//------------------------------------------------------------------------------------- +// Linux Display Search Handle +class LinuxDisplaySearchHandle : public DisplaySearchHandle +{ +public: + LinuxDisplaySearchHandle() : + extended(false), + application(false), + extendedDisplayCount(0), + applicationDisplayCount(0), + displayCount(0) + {} + virtual ~LinuxDisplaySearchHandle() {} + + static const int DescArraySize = 16; + + Linux::DisplayDesc cachedDescriptorArray[DescArraySize]; + bool extended; + bool application; + int extendedDisplayCount; + int applicationDisplayCount; + int displayCount; +}; + +//------------------------------------------------------------------------------------- +// LinuxDisplayGeneric + +// Describes Linux display in Compatibility mode, containing basic data +class LinuxDisplayGeneric : public Display +{ +public: + LinuxDisplayGeneric( const DisplayDesc& dd ) : + Display(dd.DeviceTypeGuess, + dd.DisplayID, + dd.ModelName, + dd.EdidSerialNumber, + dd.LogicalResolutionInPixels, + dd.NativeResolutionInPixels, + dd.DesktopDisplayOffset, + 0, + 0, + false) + { + } + + virtual ~LinuxDisplayGeneric() + { + } + + virtual bool InCompatibilityMode() const + { + return true; + } + + // Generic displays are not capable of mirroring + virtual MirrorMode SetMirrorMode( MirrorMode newMode ) + { + OVR_UNUSED( newMode ); + return MirrorDisabled; + } +}; + +}} // namespace OVR::Linux + +#endif // OVR_Linux_Display_h diff --git a/LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp b/LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp new file mode 100644 index 0000000..3d76f69 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp @@ -0,0 +1,649 @@ +/******************************************************************************* + +Filename : OVR_Linux_SDKWindow.cpp +Content : SDK generated Linux window. +Created : October 1, 2014 +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 +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_SDKWindow.h" +#include "../Kernel/OVR_Log.h" +#include "../Kernel/OVR_Log.h" +#include "../../../3rdParty/EDID/edid.h" + +namespace OVR { + +// Forward declarations +static Window constructWindow(struct _XDisplay* display, int xscreen, + XVisualInfo* xvisual, + const LinuxDeviceScreen& screen); + +static XRRModeInfo* findModeByXID(XRRScreenResources* screen, RRMode xid) +{ + for (int m = 0; m < screen->nmode; ++m) + { + XRRModeInfo* mode = &screen->modes[m]; + if (xid == mode->id) + { + return mode; + } + } + return NULL; +} + +/// Retrieves a list of available device screens on which we can build +/// SDK windows. Returns number of devices found. +/// screens Array which this function will populate. +/// maxNumScreens Maximum number of screens to store in screens. +static int getDeviceScreens(LinuxDeviceScreen* screens, int maxNumDevices) +{ + struct _XDisplay* disp = XOpenDisplay(NULL); + if (!disp) + { + OVR::LogError("[SDKWindow] Unable to open X Display."); + return 0; + } + + int numDevices = 0; + int numScreens = XScreenCount(disp); + for (int i = 0; i < numScreens; ++i) + { + // Screen root is used to detect what video output the crtc is using. + Window sr = XRootWindow(disp, i); + XRRScreenResources* screen = XRRGetScreenResources(disp, sr); + + for (int ii = 0; ii < screen->ncrtc; ++ii) + { + XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(disp, screen, screen->crtcs[ii]); + + if (0 == crtcInfo->noutput) + { + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + bool foundOutput = false; + RROutput output = crtcInfo->outputs[0]; + for (int k = 0; k < crtcInfo->noutput; ++k) + { + XRROutputInfo* outputInfo = + XRRGetOutputInfo(disp, screen, crtcInfo->outputs[k]); + for (int kk = 0 ; kk < outputInfo->nmode; ++kk) + { + if (outputInfo->modes[kk] == crtcInfo->mode) + { + output = crtcInfo->outputs[k]; + foundOutput = true; + break; + } + } + XRRFreeOutputInfo(outputInfo); + if (foundOutput) { break; } + } + + if (!foundOutput) + { + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + XRROutputInfo* outputInfo = XRRGetOutputInfo(disp, screen, output); + if (RR_Connected != outputInfo->connection) + { + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + // Read EDID associated with crtc. + MonitorInfo* mi = read_edid_data(disp, output); + if (mi == NULL) + { + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + if (strcmp(mi->manufacturer_code, "OVR") == 0) + { + XRRModeInfo* modeInfo = findModeByXID(screen, crtcInfo->mode); + + DistortionRotation desiredRot = DistRotateNone; + if (mi->product_code == 3) + { + // This is a DK2, we may have to rotate our output. + // If we don't have to, we should alert the user that + // rotating the display using the DM or graphics + // card settings is highly non-optimal. + desiredRot = DistRotateCCW90; + if (crtcInfo->rotation != RR_Rotate_0) + { + OVR::LogError("Please do not rotate your rift's screen."); + + if (crtcInfo->rotation == RR_Rotate_90) + { + // The user has manually rotated the screen. + // So apply no rotation on our end. + desiredRot = DistRotateNone; + } + } + } + else + { + if (crtcInfo->rotation != RR_Rotate_0) + { + OVR::LogError("Please do not rotate your rift's screen."); + } + } + + int width = modeInfo->width; + int height = modeInfo->height; + + // Swap width / height if display is rotated (shouldn't be on linux). + if ( crtcInfo->rotation == RR_Rotate_90 + || crtcInfo->rotation == RR_Rotate_270) + { + width = modeInfo->height; + height = modeInfo->width; + } + + // Push detected monitor. + screens[numDevices].set(i, screen->crtcs[ii], desiredRot, + mi->product_code, width, height, + crtcInfo->x, crtcInfo->y); + ++numDevices; + } + + delete mi; + + if (numDevices == maxNumDevices) + { + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); + XRRFreeScreenResources(screen); + OVR::LogError("[SDKWindow] Maxed out number of devices.."); + XCloseDisplay(disp); + return numDevices; + } + + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); + } + + XRRFreeScreenResources(screen); + } + XCloseDisplay(disp); + return numDevices; +} + + +LinuxDeviceScreen SDKWindow::findDevScreenForHMD(const ovrHmd& hmd) +{ + return findDevScreenForDevID(hmd->DisplayDeviceName); +} + +LinuxDeviceScreen SDKWindow::findDevScreenForDevID(const char* deviceIDIn) +{ + const int maxNumDevices = 5; + LinuxDeviceScreen screens[maxNumDevices]; + int numDevices = getDeviceScreens(screens, maxNumDevices); + + if (numDevices > 0) + { + // Identify target for SDK window via hmd info. + for (int i = 0; i < numDevices; ++i) + { + LinuxDeviceScreen& screen = screens[i]; + + char deviceID[32]; + OVR_sprintf(deviceID, 32, "OVR%04d-%d", + screen.productCode, screen.crtcid); + + if (strcmp(deviceIDIn, deviceID) == 0) + { + return screen; + } + } + } + + return LinuxDeviceScreen(); +} + +DistortionRotation SDKWindow::getRotation(const ovrHmd& hmd) +{ + LinuxDeviceScreen screen = findDevScreenForHMD(hmd); + if (screen.isValid()) + { + return screen.rotation; + } + else + { + return DistRotateNone; + } +} + + +bool SDKWindow::getVisualFromDrawable(GLXDrawable drawable, XVisualInfo* vinfoOut) +{ + struct _XDisplay* display = glXGetCurrentDisplay(); + + unsigned int value; + glXQueryDrawable(display, drawable, GLX_FBCONFIG_ID, &value); + const int attribs[] = {GLX_FBCONFIG_ID, (int)value, None}; + int screen; + glXQueryContext(display, glXGetCurrentContext(), GLX_SCREEN, &screen); + int numElems; + GLXFBConfig* config = glXChooseFBConfig(display, screen, attribs, &numElems); + if (numElems > 0) + { + XVisualInfo* chosen = glXGetVisualFromFBConfig(display, *config); + *vinfoOut = *chosen; + XFree(config); + return true; + } + return false; +} + +SDKWindow::SDKWindow(const ovrHmd& hmd) : + mXDisplay(NULL), + mXScreen(-1), + mXVisual(NULL), + mXUniqueContext(-1), + mXWindow(0), + mFBConfigID(0) +{ + OVR_UNUSED(hmd); +} + +SDKWindow::~SDKWindow() +{ + if (mXWindow) + { + XDeleteContext(mXDisplay, mXWindow, mXUniqueContext); + XUnmapWindow(mXDisplay, mXWindow); + XDestroyWindow(mXDisplay, mXWindow); + mXWindow = static_cast(0); + } + + if (mXVisual) + { + XFree(mXVisual); + mXVisual = NULL; + } + + if (mXDisplay) + { + XCloseDisplay(mXDisplay); + } +} + +void SDKWindow::buildVisualAndWindow(const LinuxDeviceScreen& devScreen) +{ + mXDisplay = XOpenDisplay(NULL); + mXUniqueContext = XUniqueContext(); + mXScreen = devScreen.screen; + mFBConfigID = chooseFBConfigID(mXDisplay, mXScreen); + + mXVisual = getVisual(mXDisplay, mFBConfigID, mXScreen); + if (mXVisual != NULL) + { + mXWindow = constructWindow(mXDisplay, mXScreen, mXVisual, devScreen); + mDeviceScreen = devScreen; + } +} + +// Used in chooseVisual. May need to expose this to the end use so they can +// choose an appropriate framebuffer configuration. +struct FBConfig +{ + FBConfig() : + redBits(8), + greenBits(8), + blueBits(8), + alphaBits(8), + depthBits(8), + stencilBits(-1), + doubleBuffer(true), + auxBuffers(-1) + {} + + int redBits; + int greenBits; + int blueBits; + int alphaBits; + int depthBits; + int stencilBits; + bool doubleBuffer; + int auxBuffers; + + int xcfg; +}; + +static int fbCalcContrib(int desired, int current) +{ + int diff = desired - current; + if (current != -1) { return diff * diff; } + else { return 0; } +} + +// Choose frame buffer configuration and return fbConfigID. +int SDKWindow::chooseFBConfigID(struct _XDisplay* display, int xscreen) +{ + int nativeCount = 0; + GLXFBConfig* nativeConfigs = + glXGetFBConfigs(display, xscreen, &nativeCount); + if (!nativeCount) + { + OVR::LogError("[SDKWindow] No valid frame buffer configurations found."); + return 0; + } + + FBConfig* usables = static_cast(calloc(nativeCount, sizeof(FBConfig))); + int numUsables = 0; + + for (int i = 0; i < nativeCount; ++i) + { + GLXFBConfig native = nativeConfigs[i]; + FBConfig* usable = &usables[numUsables]; + int v = 0; + + // Only frame buffer configcs with attached visuals. + glXGetFBConfigAttrib(display, native, GLX_VISUAL_ID, &v); + if (!v) { continue; } + + // Only RGBA frame buffers. + glXGetFBConfigAttrib(display, native, GLX_RENDER_TYPE, &v); + if (!(v & GLX_RGBA_BIT)) { continue; } + + glXGetFBConfigAttrib(display, native, GLX_DRAWABLE_TYPE, &v); + if (!(v & GLX_WINDOW_BIT)) { continue; } + + glXGetFBConfigAttrib(display, native, GLX_DEPTH_SIZE, &usable->depthBits); + glXGetFBConfigAttrib(display, native, GLX_STENCIL_SIZE, &usable->stencilBits); + + glXGetFBConfigAttrib(display, native, GLX_RED_SIZE, &usable->redBits); + glXGetFBConfigAttrib(display, native, GLX_GREEN_SIZE, &usable->greenBits); + glXGetFBConfigAttrib(display, native, GLX_BLUE_SIZE, &usable->blueBits); + glXGetFBConfigAttrib(display, native, GLX_ALPHA_SIZE, &usable->alphaBits); + + glXGetFBConfigAttrib(display, native, GLX_ALPHA_SIZE, &usable->auxBuffers); + + glXGetFBConfigAttrib(display, native, GLX_DOUBLEBUFFER, &v); + usable->doubleBuffer = v ? true : false; + + glXGetFBConfigAttrib(display, native, GLX_FBCONFIG_ID, &usable->xcfg); + + ++numUsables; + } + + // We really want std::numeric_limits::max() instead of hardcoded vals. + const int MostMissing = 100; + int leastMissing = MostMissing; + int leastBias = MostMissing; + + const FBConfig* closest = NULL; + + // Desired is currently the default config built by constructor. + FBConfig desired; + + for (int i = 0; i < numUsables; ++i) + { + const FBConfig* cur = &usables[i]; + + if (desired.doubleBuffer != cur->doubleBuffer) { continue; } + + int missing = 0; + if (desired.alphaBits > 0 && cur->alphaBits == 0) { ++missing; } + if (desired.depthBits > 0 && cur->depthBits == 0) { ++missing; } + if (desired.stencilBits > 0 && cur->stencilBits == 0) { ++missing; } + if (desired.redBits > 0 && desired.redBits != cur->redBits) { ++missing; } + if (desired.greenBits > 0 && desired.greenBits != cur->greenBits) { ++missing; } + if (desired.blueBits > 0 && desired.blueBits != cur->blueBits) { ++missing; } + + int bias = fbCalcContrib(desired.redBits, cur->redBits) + + fbCalcContrib(desired.greenBits, cur->greenBits) + + fbCalcContrib(desired.blueBits, cur->blueBits) + + fbCalcContrib(desired.alphaBits, cur->alphaBits) + + fbCalcContrib(desired.depthBits, cur->depthBits) + + fbCalcContrib(desired.stencilBits, cur->stencilBits); + + if (missing < leastMissing) + { + closest = cur; + } + else if (missing == leastMissing) + { + // Now select against squared differences. + if (bias < leastBias) + { + closest = cur; + } + } + + if (closest == cur) + { + leastMissing = missing; + leastBias = bias; + } + } + + if (closest == NULL) + { + OVR::LogError("[SDKWindow] Failed to select appropriate frame buffer."); + XFree(nativeConfigs); + free(usables); + return 0; + } + + int retVal = closest->xcfg; + + XFree(nativeConfigs); + free(usables); + + return retVal; +} + +// Obtain visual from frame buffer configuration ID. +XVisualInfo* SDKWindow::getVisual(struct _XDisplay* display, + int fbConfigID, int xscreen) +{ + GLXFBConfig* cfg = getGLXFBConfig(display, fbConfigID, xscreen); + XVisualInfo* viOut = NULL; + if (cfg != NULL) + { + viOut = glXGetVisualFromFBConfig(display, *cfg); + XFree(cfg); + cfg = NULL; + } + else + { + OVR::LogError("Unable to find fb config ID."); + } + return viOut; +} + +// GLXFBConfig pointer from frame buffer configuration ID. You must call +// XFree on the GLXFBConfig pointer. +GLXFBConfig* SDKWindow::getGLXFBConfig(struct _XDisplay* display, + int fbConfigID, int xscreen) +{ + const int attribs[] = {GLX_FBCONFIG_ID, (int)fbConfigID, None}; + int numElems; + + GLXFBConfig* config = glXChooseFBConfig(display, xscreen, attribs, &numElems); + if (numElems > 0) + { + return config; + } + else + { + return NULL; + } +} + + +static int gXLastError = -1; +static int handleXError(struct _XDisplay* display, XErrorEvent* event) +{ + OVR_UNUSED(display); + gXLastError = event->error_code; + return 0; +} + +static void obtainXErrorHandler() +{ + gXLastError = Success; + XSetErrorHandler(handleXError); +} + +static void releaseXErrorHandler(struct _XDisplay* display) +{ + XSync(display, False); + XSetErrorHandler(NULL); +} + +// Returns 0 on error, otherwise a valid X window is returned. +static Window constructWindow(struct _XDisplay* xDisp, int xScreen, + XVisualInfo* xVisual, + const LinuxDeviceScreen& devScreen) +{ + XSetWindowAttributes wa; + + Window root = XRootWindow(xDisp, xScreen); + Window xWindowOut = 0; + + // Create Window + { + Colormap xWinColorMapOut = XCreateColormap( + xDisp, root, xVisual->visual, AllocNone); + unsigned long wamask = CWBorderPixel | CWColormap | CWEventMask; + + wa.colormap = xWinColorMapOut; + wa.border_pixel = 0; + wa.event_mask = StructureNotifyMask | ExposureMask | FocusChangeMask + | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask + | PropertyChangeMask; + + obtainXErrorHandler(); + + xWindowOut = XCreateWindow(xDisp, root, + 0, 0, + devScreen.width, devScreen.height, + 0, + xVisual->depth, + InputOutput, + xVisual->visual, + wamask, + &wa); + + releaseXErrorHandler(xDisp); + + if (!xWindowOut) + { + OVR::LogError("[SDKWindow] Failed to create SDK window."); + return 0; + } + + XFreeColormap(xDisp, xWinColorMapOut); + } + + // OVERRIDE REDIRECT. + XSetWindowAttributes attributes; + attributes.override_redirect = True; + XChangeWindowAttributes(xDisp, xWindowOut, + CWOverrideRedirect, &attributes); + + // Show the window (do this in full screen or windowed). + XMapRaised(xDisp, xWindowOut); + XFlush(xDisp); + + // Position ourselves manually since there should be no WM managing us. + XRaiseWindow(xDisp, xWindowOut); + XMoveWindow(xDisp, xWindowOut, devScreen.offsetX, devScreen.offsetY); + XResizeWindow(xDisp, xWindowOut, devScreen.width, devScreen.height); + + XFlush(xDisp); + + // WM Backup in case there still exists a WM managing us... + Atom NET_WM_BYPASS_COMPOSITOR = + XInternAtom(xDisp, "_NET_WM_BYPASS_COMPOSITOR", False); + Atom NET_WM_STATE = + XInternAtom(xDisp, "_NET_WM_STATE", False); + Atom NET_WM_STATE_FULLSCREEN = + XInternAtom(xDisp, "_NET_WM_STATE_FULLSCREEN", False); + Atom NET_ACTIVE_WINDOW = + XInternAtom(xDisp, "_NET_ACTIVE_WINDOW", False); + + // Bypass compositor if we are under a compositing WM. + // Just in case a WM ignores our override_redirect. + if (NET_WM_BYPASS_COMPOSITOR) + { + const unsigned long bypass = 1; + XChangeProperty(xDisp, xWindowOut, + NET_WM_BYPASS_COMPOSITOR, + XA_CARDINAL, 32, PropModeReplace, + (unsigned char*)&bypass, 1); + } + + if (NET_WM_STATE && NET_WM_STATE_FULLSCREEN) + { + // BACKUP: If we are still managed by a WM we want fullscreen. + const int EWMH_STATE_ADD = 1; + + if (NET_ACTIVE_WINDOW) + { + XEvent event; + memset(&event, 0, sizeof(event)); + + event.type = ClientMessage; + event.xclient.window = xWindowOut; + event.xclient.format = 32; + event.xclient.message_type = NET_ACTIVE_WINDOW; + event.xclient.data.l[0] = 1; + event.xclient.data.l[1] = 0; + + XSendEvent(xDisp, root, False, + SubstructureNotifyMask | SubstructureRedirectMask, + &event); + } + + XEvent event; + memset(&event, 0, sizeof(event)); + + event.type = ClientMessage; + event.xclient.window = xWindowOut; + event.xclient.format = 32; + event.xclient.message_type = NET_WM_STATE; + event.xclient.data.l[0] = EWMH_STATE_ADD; + event.xclient.data.l[1] = NET_WM_STATE_FULLSCREEN; + event.xclient.data.l[2] = 0; + event.xclient.data.l[3] = 1; + + XSendEvent(xDisp, root, False, + SubstructureNotifyMask | SubstructureRedirectMask, + &event); + } + + return xWindowOut; +} + +} // namespace OVR + diff --git a/LibOVR/Src/Displays/OVR_Linux_SDKWindow.h b/LibOVR/Src/Displays/OVR_Linux_SDKWindow.h new file mode 100644 index 0000000..70b95dd --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Linux_SDKWindow.h @@ -0,0 +1,147 @@ +/******************************************************************************* + +Filename : OVR_Linux_SDKWindow.h +Content : SDK generated Linux window. +Created : October 1, 2014 +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 +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_SDKWindow_h +#define OVR_Linux_SDKWindow_h + +#include "../OVR_CAPI.h" +#include "../CAPI/GL/CAPI_GL_Util.h" + +#include +#include +#include +#include +#include + +namespace OVR { + +enum DistortionRotation +{ + DistRotateNone, + DistRotateCCW90 +}; + +struct LinuxDeviceScreen +{ + LinuxDeviceScreen() : + screen(-1), + crtcid(0), + rotation(DistRotateNone), + productCode(-1), + width(-1), + height(-1), + offsetX(-1), + offsetY(-1) + {} + + void set(int xScreen, XID xid, DistortionRotation rot, int prodCode, + int w, int h, int x, int y) + { + screen = xScreen; + crtcid = xid; + rotation = rot; + productCode = prodCode; + + width = w; + height = h; + offsetX = x; + offsetY = y; + } + + bool isValid() {return (screen != -1);} + + int screen; ///< X Screen this device occupies. + XID crtcid; ///< XID uniquely identifying this device on XDisplay. + DistortionRotation rotation; + int productCode; + + // Actual width and height of screen. + int width; + int height; + + // Offset if using twinview + int offsetX; + int offsetY; +}; + +class SDKWindow +{ +public: + + SDKWindow(const ovrHmd& hmd); + ~SDKWindow(); + + /// Rotation necessary to correctly orient this SDK window. + DistortionRotation GetDistortionRotation() {return mDeviceScreen.rotation;} + + struct _XDisplay* GetDisplay() {return mXDisplay;} + XVisualInfo* GetVisual() {return mXVisual;} + Window GetDrawable() {return mXWindow;} + bool HasValidWindow() {return (mXWindow != 0);} + + // Choose frame buffer configuration and return fbConfigID. Returns -1 if + // a failure occurs. + static int chooseFBConfigID(struct _XDisplay* display, int xscreen); + + // Obtain visual from frame buffer configuration ID. You must call XFree + // on the XVisualInfo* pointer. + static XVisualInfo* getVisual(struct _XDisplay* display, + int fbConfigID, int xscreen); + + // GLXFBConfig pointer from frame buffer configuration ID. You must call + // XFree on the GLXFBConfig pointer. + static GLXFBConfig* getGLXFBConfig(struct _XDisplay* display, + int fbConfigID, int xscreen); + + static LinuxDeviceScreen findDevScreenForHMD(const ovrHmd& hmd); + static LinuxDeviceScreen findDevScreenForDevID(const char* deviceID); + + static DistortionRotation getRotation(const ovrHmd& hmd); + + // Obtains XVisualInfo for currently bound context. Returns true if a + // visual was successfully obtained. False otherwise. + static bool getVisualFromDrawable(GLXDrawable drawable, XVisualInfo* vinfoOut); + +private: + + /// Constructs SDK window on the given device screen. + void buildVisualAndWindow(const LinuxDeviceScreen& devScreen); + + // Added m in front of variables so as to not conflict with X names. + struct _XDisplay* mXDisplay; + int mXScreen; + XVisualInfo* mXVisual; + XContext mXUniqueContext; + Window mXWindow; + int mFBConfigID; + + LinuxDeviceScreen mDeviceScreen; +}; + + +} // namespace OVR + +#endif // OVR_Linux_SDKWindow_h diff --git a/LibOVR/Src/Displays/OVR_OSX_Display.cpp b/LibOVR/Src/Displays/OVR_OSX_Display.cpp new file mode 100644 index 0000000..67df51d --- /dev/null +++ b/LibOVR/Src/Displays/OVR_OSX_Display.cpp @@ -0,0 +1,372 @@ +/************************************************************************************ + +Filename : OVR_OSX_Display.cpp +Content : OSX-specific Display declarations +Created : July 2, 2014 +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 +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_OSX_Display.h" +#include "../Kernel/OVR_Log.h" + +#include +#include +#include +#include + +//------------------------------------------------------------------------------------- +// ***** Display enumeration Helpers + +namespace OVR { + +// FIXME Code duplication with windows. +#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 UByte edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00 }; + +const UByte edid_v1_descriptor_flag[] = { 0x00, 0x00 }; + +// FIXME Code duplication with windows. Refactor. +static int blockType( UByte* 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( UByte const* block ) +{ + static char name[ 13 ]; + unsigned i; + UByte 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; +} + +// FIXME Code duplication with windows. Refactor. +static bool parseEdid( UByte* edid, OVR::OSX::DisplayEDID& edidResult ) +{ + unsigned i; + UByte* block; + const char* monitor_name = "Unknown"; + UByte 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; + } + + + // OVR_DEBUG_LOG_TEXT(( "\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; + } + } + + UByte 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); + + // printf( "\tIdentifier \"%s\"\n", monitor_name ); + // printf( "\tVendorName \"%s\"\n", vendorString ); + // printf( "\tModelName \"%s\"\n", monitor_name ); + // printf( "\tModelNumber %d\n", edidResult.ModelNumber ); + // printf( "\tSerialNumber \"%s\"\n", edidResult.SerialNumber.ToCStr() ); + + // FIXME: Get timings as well, though they aren't very useful here + // except for the vertical refresh rate, presumably + + return true; +} + +static int discoverExtendedRifts(OVR::OSX::DisplayDesc* descriptorArray, int inputArraySize, bool edidInfo) +{ + OVR_UNUSED(edidInfo); + int result = 0; + + static bool reportDiscovery = true; + OVR_UNUSED(reportDiscovery); + + CGDirectDisplayID Displays[32]; + uint32_t NDisplays = 0; + CGGetOnlineDisplayList(32, Displays, &NDisplays); + + for (unsigned int i = 0; i < NDisplays; i++) + { + io_service_t port = CGDisplayIOServicePort(Displays[i]); + CFDictionaryRef DispInfo = IODisplayCreateInfoDictionary(port, kNilOptions); + + // Display[i] + + uint32_t vendor = CGDisplayVendorNumber(Displays[i]); + uint32_t product = CGDisplayModelNumber(Displays[i]); + + CGRect desktop = CGDisplayBounds(Displays[i]); + Vector2i desktopOffset(desktop.origin.x, desktop.origin.y); + + if (vendor == 16082 && ( (product == 1)||(product == 2)||(product == 3) ) ) // 7" or HD + { + if( result >= inputArraySize ) + { + CFRelease(DispInfo); + return result; + } + + Sizei monitorResolution(1280, 800); + + // Obtain and parse EDID data. + CFDataRef data = + (CFDataRef)CFDictionaryGetValue(DispInfo, CFSTR(kIODisplayEDIDKey)); + if (!data) + { + CFRelease(DispInfo); + OVR::LogError("[OSX Display] Unable to obtain EDID for Oculus product %d", product); + continue; + } + UByte* edid = (UByte*)CFDataGetBytePtr(data); + OSX::DisplayEDID edidResult; + 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.LogicalResolutionInPixels = monitorResolution; + desc.DesktopDisplayOffset = desktopOffset; + + switch (product) + { + 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; + } + + // Hard-coded defaults in case the device doesn't have the data itself. + // DK2 prototypes (0003) or DK HD Prototypes (0002) + if (product == 3 || product == 2) + { + desc.LogicalResolutionInPixels = Sizei(1920, 1080); + desc.NativeResolutionInPixels = Sizei(1080, 1920); + } + else + { + desc.LogicalResolutionInPixels = monitorResolution; + desc.NativeResolutionInPixels = monitorResolution; + } + + //OVR_DEBUG_LOG_TEXT(("Display Found %x:%x\n", vendor, product)); + } + CFRelease(DispInfo); + } + + return result; +} + + +//------------------------------------------------------------------------------------- +// ***** Display + +bool Display::Initialize() +{ + // Nothing to initialize. OS X only supports compatibility mode. + return true; +} + + +bool Display::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) +{ + driverInstalled = false; + compatMode = true; + hideDK1Mode = false; + return true; +} + +bool Display::SetDriverMode(bool /*compatMode*/, bool /*hideDK1Mode*/) +{ + return false; +} + +DisplaySearchHandle* Display::GetDisplaySearchHandle() +{ + return new OSX::OSXDisplaySearchHandle(); +} + +bool Display::InCompatibilityMode( bool displaySearch ) +{ + OVR_UNUSED( displaySearch ); + return true; +} + +int Display::GetDisplayCount( DisplaySearchHandle* handle, bool extended, bool applicationOnly, bool edidInfo ) +{ + OVR_UNUSED(applicationOnly); + + static int extendedCount = -1; + + OSX::OSXDisplaySearchHandle* localHandle = (OSX::OSXDisplaySearchHandle*)handle; + if (localHandle == NULL) + { + OVR::LogError("[OSX Display] No search handle passed into GetDisplayCount. Return 0 rifts."); + return 0; + } + + if (extendedCount == -1 || extended) + { + extendedCount = discoverExtendedRifts(localHandle->cachedDescriptorArray, OSX::OSXDisplaySearchHandle::DescArraySize, edidInfo); + } + + localHandle->extended = true; + localHandle->extendedDisplayCount = extendedCount; + int totalCount = extendedCount; + + /// FIXME: Implement application mode for OS X. + localHandle->application = false; + localHandle->applicationDisplayCount = 0; + + localHandle->displayCount = totalCount; + + return totalCount; +} + +Ptr Display::GetDisplay( int index, DisplaySearchHandle* handle ) +{ + Ptr result = NULL; + + if (index < 0) + { + OVR::LogError("[OSX Display] Invalid index given to GetDisplay."); + return NULL; + } + + OSX::OSXDisplaySearchHandle* localHandle = (OSX::OSXDisplaySearchHandle*)handle; + if (localHandle == NULL) + { + OVR::LogError("[OSX Display] No search handle passed into GetDisplay. Return 0 rifts."); + return NULL; + } + + if (localHandle->extended) + { + if (index >= 0 && index < (int)localHandle->extendedDisplayCount) + { + return *new OSX::OSXDisplayGeneric(localHandle->cachedDescriptorArray[index]); + } + + // index -= localHandle->extendedDisplayCount; + } + + if (localHandle->application) + { + OVR::LogError("[OSX Display] Mac does not support application displays."); + } + + return result; +} +} // namespace OVR diff --git a/LibOVR/Src/Displays/OVR_OSX_Display.h b/LibOVR/Src/Displays/OVR_OSX_Display.h new file mode 100644 index 0000000..a69c955 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_OSX_Display.h @@ -0,0 +1,139 @@ +/************************************************************************************ + +Filename : OVR_OSX_Display.h +Content : OSX-specific Display declarations +Created : July 2, 2014 +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 +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_OSX_Display_h +#define OVR_OSX_Display_h + +#include "OVR_Display.h" + +namespace OVR { namespace OSX { + + +//------------------------------------------------------------------------------------- +// 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 +{ + DisplayDesc() : + DeviceTypeGuess(HmdType_None), + DisplayID(0), + LogicalResolutionInPixels(0), + NativeResolutionInPixels(0) + {} + + HmdTypeEnum DeviceTypeGuess; + uint32_t 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 +{ + DisplayEDID() : + ModelNumber(0) + {} + + String MonitorName; + UInt16 ModelNumber; + String VendorName; + String SerialNumber; +}; + +//------------------------------------------------------------------------------------- +// OSX Display Search Handle +class OSXDisplaySearchHandle : public DisplaySearchHandle +{ +public: + OSXDisplaySearchHandle() : + extended(false), + application(false), + extendedDisplayCount(0), + applicationDisplayCount(0), + displayCount(0) + {} + virtual ~OSXDisplaySearchHandle() {} + + static const int DescArraySize = 16; + + OSX::DisplayDesc cachedDescriptorArray[DescArraySize]; + bool extended; + bool application; + int extendedDisplayCount; + int applicationDisplayCount; + int displayCount; +}; + +//------------------------------------------------------------------------------------- +// OSXDisplayGeneric + +// Describes OSX display in Compatibility mode, containing basic data +class OSXDisplayGeneric : public Display +{ +public: + OSXDisplayGeneric( const DisplayDesc& dd ) : + Display(dd.DeviceTypeGuess, + dd.DisplayID, + dd.ModelName, + dd.EdidSerialNumber, + dd.LogicalResolutionInPixels, + dd.NativeResolutionInPixels, + dd.DesktopDisplayOffset, + 0, + 0, + false) + { + } + + virtual ~OSXDisplayGeneric() + { + } + + virtual bool InCompatibilityMode() const + { + return true; + } + + // Generic displays are not capable of mirroring + virtual MirrorMode SetMirrorMode( MirrorMode newMode ) + { + OVR_UNUSED( newMode ); + return MirrorDisabled; + } +}; + +}} // namespace OVR::OSX + +#endif // OVR_OSX_Display_h diff --git a/LibOVR/Src/Displays/OVR_OSX_FocusObserver.h b/LibOVR/Src/Displays/OVR_OSX_FocusObserver.h new file mode 100644 index 0000000..e2f28e3 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_OSX_FocusObserver.h @@ -0,0 +1,75 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..3dd77a8 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_OSX_FocusObserver.mm @@ -0,0 +1,245 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..dbfe9f6 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_OSX_FocusReader.h @@ -0,0 +1,45 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..bed95d6 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_OSX_FocusReader.mm @@ -0,0 +1,75 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..677c619 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_Display.cpp @@ -0,0 +1,1323 @@ +/************************************************************************************ + +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 diff --git a/LibOVR/Src/Displays/OVR_Win32_Display.h b/LibOVR/Src/Displays/OVR_Win32_Display.h new file mode 100644 index 0000000..4517d44 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_Display.h @@ -0,0 +1,182 @@ +/************************************************************************************ + +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 diff --git a/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h b/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h new file mode 100644 index 0000000..e801f4a --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h @@ -0,0 +1,429 @@ +/************************************************************************************ + +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 diff --git a/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp b/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp new file mode 100644 index 0000000..7c3c7a3 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp @@ -0,0 +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 diff --git a/LibOVR/Src/Displays/OVR_Win32_FocusReader.h b/LibOVR/Src/Displays/OVR_Win32_FocusReader.h new file mode 100644 index 0000000..358ab38 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_FocusReader.h @@ -0,0 +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 diff --git a/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp b/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp new file mode 100644 index 0000000..a74ab75 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp @@ -0,0 +1,974 @@ +/************************************************************************************ + +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; + } +} diff --git a/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp new file mode 100644 index 0000000..602df98 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp @@ -0,0 +1,234 @@ +/************************************************************************************ + +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 diff --git a/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h new file mode 100644 index 0000000..1339de4 --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h @@ -0,0 +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 diff --git a/LibOVR/Src/Displays/OVR_Win32_ShimVersion.h b/LibOVR/Src/Displays/OVR_Win32_ShimVersion.h new file mode 100644 index 0000000..f5eaa7c --- /dev/null +++ b/LibOVR/Src/Displays/OVR_Win32_ShimVersion.h @@ -0,0 +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)) diff --git a/LibOVR/Src/Kernel/OVR_Alg.cpp b/LibOVR/Src/Kernel/OVR_Alg.cpp index 2e52bc3..c087777 100644 --- a/LibOVR/Src/Kernel/OVR_Alg.cpp +++ b/LibOVR/Src/Kernel/OVR_Alg.cpp @@ -5,16 +5,16 @@ Content : Static lookup tables for Alg functions Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -29,7 +29,7 @@ limitations under the License. namespace OVR { namespace Alg { //------------------------------------------------------------------------ -extern const UByte UpperBitTable[256] = +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, @@ -41,7 +41,7 @@ extern const UByte UpperBitTable[256] = 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 UByte LowerBitTable[256] = +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, diff --git a/LibOVR/Src/Kernel/OVR_Alg.h b/LibOVR/Src/Kernel/OVR_Alg.h index e03cea0..f7f461f 100644 --- a/LibOVR/Src/Kernel/OVR_Alg.h +++ b/LibOVR/Src/Kernel/OVR_Alg.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -66,12 +66,12 @@ template OVR_FORCE_INLINE T Lerp(T a, T b, T f) // 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(UPInt)); + 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(UPInt)); + OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); return (b < a) ? a : b; } @@ -99,7 +99,7 @@ template struct OperatorLess // The range is specified with start, end, where "end" is exclusive! // The comparison predicate must be specified. template -void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less) +void QuickSortSliced(Array& arr, size_t start, size_t end, Less less) { enum { @@ -108,15 +108,15 @@ void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less) if(end - start < 2) return; - SPInt stack[80]; - SPInt* top = stack; - SPInt base = (SPInt)start; - SPInt limit = (SPInt)end; + intptr_t stack[80]; + intptr_t* top = stack; + intptr_t base = (intptr_t)start; + intptr_t limit = (intptr_t)end; for(;;) { - SPInt len = limit - base; - SPInt i, j, pivot; + intptr_t len = limit - base; + intptr_t i, j, pivot; if(len > Threshold) { @@ -201,7 +201,7 @@ void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less) // The range is specified with start, end, where "end" is exclusive! // The data type must have a defined "<" operator. template -void QuickSortSliced(Array& arr, UPInt start, UPInt end) +void QuickSortSliced(Array& arr, size_t start, size_t end) { typedef typename Array::ValueType ValueType; QuickSortSliced(arr, start, end, OperatorLess::Compare); @@ -210,7 +210,7 @@ void QuickSortSliced(Array& arr, UPInt start, UPInt end) // 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, UPInt start, UPInt end, Less less) +bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end, Less less) { enum { @@ -219,15 +219,15 @@ bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less) if(end - start < 2) return true; - SPInt stack[80]; - SPInt* top = stack; - SPInt base = (SPInt)start; - SPInt limit = (SPInt)end; + intptr_t stack[80]; + intptr_t* top = stack; + intptr_t base = (intptr_t)start; + intptr_t limit = (intptr_t)end; for(;;) { - SPInt len = limit - base; - SPInt i, j, pivot; + intptr_t len = limit - base; + intptr_t i, j, pivot; if(len > Threshold) { @@ -316,7 +316,7 @@ bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less) } template -bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end) +bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end) { typedef typename Array::ValueType ValueType; return QuickSortSlicedSafe(arr, start, end, OperatorLess::Compare); @@ -374,11 +374,11 @@ bool QuickSortSafe(Array& arr) // 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, UPInt start, UPInt end, Less less) +void InsertionSortSliced(Array& arr, size_t start, size_t end, Less less) { - UPInt j = start; - UPInt i = j + 1; - UPInt limit = end; + size_t j = start; + size_t i = j + 1; + size_t limit = end; for(; i < limit; j = i, i++) { @@ -401,7 +401,7 @@ void InsertionSortSliced(Array& arr, UPInt start, UPInt end, Less less) // The range is specified with start, end, where "end" is exclusive! // The data type must have a defined "<" operator. template -void InsertionSortSliced(Array& arr, UPInt start, UPInt end) +void InsertionSortSliced(Array& arr, size_t start, size_t end) { typedef typename Array::ValueType ValueType; InsertionSortSliced(arr, start, end, OperatorLess::Compare); @@ -442,14 +442,14 @@ void InsertionSort(Array& arr) template typename Array::ValueType& Median(Array& arr) { - UPInt count = arr.GetSize(); - UPInt mid = (count - 1) / 2; + size_t count = arr.GetSize(); + size_t mid = (count - 1) / 2; OVR_ASSERT(count > 0); - for (UPInt j = 0; j <= mid; j++) + for (size_t j = 0; j <= mid; j++) { - UPInt min = j; - for (UPInt k = j + 1; k < count; k++) + 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]); @@ -461,12 +461,12 @@ typename Array::ValueType& Median(Array& arr) // ***** LowerBoundSliced // template -UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less) +size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) { - SPInt first = (SPInt)start; - SPInt len = (SPInt)(end - start); - SPInt half; - SPInt middle; + intptr_t first = (intptr_t)start; + intptr_t len = (intptr_t)(end - start); + intptr_t half; + intptr_t middle; while(len > 0) { @@ -482,7 +482,7 @@ UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& va len = half; } } - return (UPInt)first; + return (size_t)first; } @@ -490,7 +490,7 @@ UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& va // ***** LowerBoundSliced // template -UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val) +size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) { return LowerBoundSliced(arr, start, end, val, OperatorLess::Compare); } @@ -499,7 +499,7 @@ UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& va // ***** LowerBoundSized // template -UPInt LowerBoundSized(const Array& arr, UPInt size, const Value& val) +size_t LowerBoundSized(const Array& arr, size_t size, const Value& val) { return LowerBoundSliced(arr, 0, size, val, OperatorLess::Compare); } @@ -508,7 +508,7 @@ UPInt LowerBoundSized(const Array& arr, UPInt size, const Value& val) // ***** LowerBound // template -UPInt LowerBound(const Array& arr, const Value& val, Less less) +size_t LowerBound(const Array& arr, const Value& val, Less less) { return LowerBoundSliced(arr, 0, arr.GetSize(), val, less); } @@ -518,7 +518,7 @@ UPInt LowerBound(const Array& arr, const Value& val, Less less) // ***** LowerBound // template -UPInt LowerBound(const Array& arr, const Value& val) +size_t LowerBound(const Array& arr, const Value& val) { return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess::Compare); } @@ -529,12 +529,12 @@ UPInt LowerBound(const Array& arr, const Value& val) // ***** UpperBoundSliced // template -UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less) +size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) { - SPInt first = (SPInt)start; - SPInt len = (SPInt)(end - start); - SPInt half; - SPInt middle; + intptr_t first = (intptr_t)start; + intptr_t len = (intptr_t)(end - start); + intptr_t half; + intptr_t middle; while(len > 0) { @@ -550,7 +550,7 @@ UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& va len = len - half - 1; } } - return (UPInt)first; + return (size_t)first; } @@ -558,7 +558,7 @@ UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& va // ***** UpperBoundSliced // template -UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val) +size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) { return UpperBoundSliced(arr, start, end, val, OperatorLess::Compare); } @@ -568,7 +568,7 @@ UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& va // ***** UpperBoundSized // template -UPInt UpperBoundSized(const Array& arr, UPInt size, const Value& val) +size_t UpperBoundSized(const Array& arr, size_t size, const Value& val) { return UpperBoundSliced(arr, 0, size, val, OperatorLess::Compare); } @@ -578,7 +578,7 @@ UPInt UpperBoundSized(const Array& arr, UPInt size, const Value& val) // ***** UpperBound // template -UPInt UpperBound(const Array& arr, const Value& val, Less less) +size_t UpperBound(const Array& arr, const Value& val, Less less) { return UpperBoundSliced(arr, 0, arr.GetSize(), val, less); } @@ -588,7 +588,7 @@ UPInt UpperBound(const Array& arr, const Value& val, Less less) // ***** UpperBound // template -UPInt UpperBound(const Array& arr, const Value& val) +size_t UpperBound(const Array& arr, const Value& val) { return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess::Compare); } @@ -599,8 +599,8 @@ UPInt UpperBound(const Array& arr, const Value& val) // template void ReverseArray(Array& arr) { - SPInt from = 0; - SPInt to = arr.GetSize() - 1; + intptr_t from = 0; + intptr_t to = arr.GetSize() - 1; while(from < to) { Swap(arr[from], arr[to]); @@ -615,7 +615,7 @@ template void ReverseArray(Array& arr) template void AppendArray(CDst& dst, const CSrc& src) { - UPInt i; + size_t i; for(i = 0; i < src.GetSize(); i++) dst.PushBack(src[i]); } @@ -630,13 +630,14 @@ template class ArrayAdaptor public: typedef T ValueType; ArrayAdaptor() : Data(0), Size(0) {} - ArrayAdaptor(T* ptr, UPInt size) : Data(ptr), Size(size) {} - UPInt GetSize() const { return Size; } - const T& operator [] (UPInt i) const { return Data[i]; } - T& operator [] (UPInt i) { return Data[i]; } + 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; - UPInt Size; + size_t Size; }; @@ -650,24 +651,25 @@ template class ConstArrayAdaptor public: typedef T ValueType; ConstArrayAdaptor() : Data(0), Size(0) {} - ConstArrayAdaptor(const T* ptr, UPInt size) : Data(ptr), Size(size) {} - UPInt GetSize() const { return Size; } - const T& operator [] (UPInt i) const { return Data[i]; } + 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; - UPInt Size; + size_t Size; }; //----------------------------------------------------------------------------------- -extern const UByte UpperBitTable[256]; -extern const UByte LowerBitTable[256]; +extern const uint8_t UpperBitTable[256]; +extern const uint8_t LowerBitTable[256]; //----------------------------------------------------------------------------------- -inline UByte UpperBit(UPInt val) +inline uint8_t UpperBit(size_t val) { #ifndef OVR_64BIT_POINTERS @@ -712,7 +714,7 @@ inline UByte UpperBit(UPInt val) } //----------------------------------------------------------------------------------- -inline UByte LowerBit(UPInt val) +inline uint8_t LowerBit(size_t val) { #ifndef OVR_64BIT_POINTERS @@ -765,18 +767,18 @@ class MemUtil public: // Memory compare - static int Cmp (const void* p1, const void* p2, UPInt byteCount) { return memcmp(p1, p2, byteCount); } - static int Cmp16(const void* p1, const void* p2, UPInt int16Count); - static int Cmp32(const void* p1, const void* p2, UPInt int32Count); - static int Cmp64(const void* p1, const void* p2, UPInt int64Count); + 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, UPInt int16Count) +inline int MemUtil::Cmp16(const void* p1, const void* p2, size_t int16Count) { - SInt16* pa = (SInt16*)p1; - SInt16* pb = (SInt16*)p2; + int16_t* pa = (int16_t*)p1; + int16_t* pb = (int16_t*)p2; unsigned ic = 0; if (int16Count == 0) return 0; @@ -785,10 +787,10 @@ inline int MemUtil::Cmp16(const void* p1, const void* p2, UPInt int16Count) return 0; return pa[ic] > pb[ic] ? 1 : -1; } -inline int MemUtil::Cmp32(const void* p1, const void* p2, UPInt int32Count) +inline int MemUtil::Cmp32(const void* p1, const void* p2, size_t int32Count) { - SInt32* pa = (SInt32*)p1; - SInt32* pb = (SInt32*)p2; + int32_t* pa = (int32_t*)p1; + int32_t* pb = (int32_t*)p2; unsigned ic = 0; if (int32Count == 0) return 0; @@ -797,10 +799,10 @@ inline int MemUtil::Cmp32(const void* p1, const void* p2, UPInt int32Count) return 0; return pa[ic] > pb[ic] ? 1 : -1; } -inline int MemUtil::Cmp64(const void* p1, const void* p2, UPInt int64Count) +inline int MemUtil::Cmp64(const void* p1, const void* p2, size_t int64Count) { - SInt64* pa = (SInt64*)p1; - SInt64* pb = (SInt64*)p2; + int64_t* pa = (int64_t*)p1; + int64_t* pb = (int64_t*)p2; unsigned ic = 0; if (int64Count == 0) return 0; @@ -822,8 +824,8 @@ namespace ByteUtil { // Swap the byte order of a byte array inline void SwapOrder(void* pv, int size) { - UByte* pb = (UByte*)pv; - UByte temp; + uint8_t* pb = (uint8_t*)pv; + uint8_t temp; for (int i = 0; i < size>>1; i++) { temp = pb[size-1-i]; @@ -833,29 +835,29 @@ namespace ByteUtil { } // Swap the byte order of primitive types - inline UByte SwapOrder(UByte v) { return v; } - inline SByte SwapOrder(SByte v) { return v; } - inline UInt16 SwapOrder(UInt16 v) { return UInt16(v>>8)|UInt16(v<<8); } - inline SInt16 SwapOrder(SInt16 v) { return SInt16((UInt16(v)>>8)|(v<<8)); } - inline UInt32 SwapOrder(UInt32 v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); } - inline SInt32 SwapOrder(SInt32 p) { return (SInt32)SwapOrder(UInt32(p)); } - inline UInt64 SwapOrder(UInt64 v) + 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(0x00FF000000000000ULL))>>40) | - ((v&UInt64(0x0000FF0000000000ULL))>>24) | - ((v&UInt64(0x000000FF00000000ULL))>>8) | - ((v&UInt64(0x00000000FF000000ULL))<<8) | - ((v&UInt64(0x0000000000FF0000ULL))<<24) | - ((v&UInt64(0x000000000000FF00ULL))<<40) | + ((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 SInt64 SwapOrder(SInt64 v) { return (SInt64)SwapOrder(UInt64(v)); } + inline int64_t SwapOrder(int64_t v) { return (int64_t)SwapOrder(uint64_t(v)); } inline float SwapOrder(float p) { union { float p; - UInt32 v; + uint32_t v; } u; u.p = p; u.v = SwapOrder(u.v); @@ -866,7 +868,7 @@ namespace ByteUtil { { union { double p; - UInt64 v; + uint64_t v; } u; u.p = p; u.v = SwapOrder(u.v); @@ -877,99 +879,99 @@ namespace ByteUtil { #if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN) // Little Endian to System (LE) - inline UByte LEToSystem(UByte v) { return v; } - inline SByte LEToSystem(SByte v) { return v; } - inline UInt16 LEToSystem(UInt16 v) { return v; } - inline SInt16 LEToSystem(SInt16 v) { return v; } - inline UInt32 LEToSystem(UInt32 v) { return v; } - inline SInt32 LEToSystem(SInt32 v) { return v; } - inline UInt64 LEToSystem(UInt64 v) { return v; } - inline SInt64 LEToSystem(SInt64 v) { return v; } + 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 UByte BEToSystem(UByte v) { return SwapOrder(v); } - inline SByte BEToSystem(SByte v) { return SwapOrder(v); } - inline UInt16 BEToSystem(UInt16 v) { return SwapOrder(v); } - inline SInt16 BEToSystem(SInt16 v) { return SwapOrder(v); } - inline UInt32 BEToSystem(UInt32 v) { return SwapOrder(v); } - inline SInt32 BEToSystem(SInt32 v) { return SwapOrder(v); } - inline UInt64 BEToSystem(UInt64 v) { return SwapOrder(v); } - inline SInt64 BEToSystem(SInt64 v) { return SwapOrder(v); } + 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 UByte SystemToLE(UByte v) { return v; } - inline SByte SystemToLE(SByte v) { return v; } - inline UInt16 SystemToLE(UInt16 v) { return v; } - inline SInt16 SystemToLE(SInt16 v) { return v; } - inline UInt32 SystemToLE(UInt32 v) { return v; } - inline SInt32 SystemToLE(SInt32 v) { return v; } - inline UInt64 SystemToLE(UInt64 v) { return v; } - inline SInt64 SystemToLE(SInt64 v) { return v; } + 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 UByte SystemToBE(UByte v) { return SwapOrder(v); } - inline SByte SystemToBE(SByte v) { return SwapOrder(v); } - inline UInt16 SystemToBE(UInt16 v) { return SwapOrder(v); } - inline SInt16 SystemToBE(SInt16 v) { return SwapOrder(v); } - inline UInt32 SystemToBE(UInt32 v) { return SwapOrder(v); } - inline SInt32 SystemToBE(SInt32 v) { return SwapOrder(v); } - inline UInt64 SystemToBE(UInt64 v) { return SwapOrder(v); } - inline SInt64 SystemToBE(SInt64 v) { return SwapOrder(v); } + 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 UByte LEToSystem(UByte v) { return SwapOrder(v); } - inline SByte LEToSystem(SByte v) { return SwapOrder(v); } - inline UInt16 LEToSystem(UInt16 v) { return SwapOrder(v); } - inline SInt16 LEToSystem(SInt16 v) { return SwapOrder(v); } - inline UInt32 LEToSystem(UInt32 v) { return SwapOrder(v); } - inline SInt32 LEToSystem(SInt32 v) { return SwapOrder(v); } - inline UInt64 LEToSystem(UInt64 v) { return SwapOrder(v); } - inline SInt64 LEToSystem(SInt64 v) { return SwapOrder(v); } + 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 UByte BEToSystem(UByte v) { return v; } - inline SByte BEToSystem(SByte v) { return v; } - inline UInt16 BEToSystem(UInt16 v) { return v; } - inline SInt16 BEToSystem(SInt16 v) { return v; } - inline UInt32 BEToSystem(UInt32 v) { return v; } - inline SInt32 BEToSystem(SInt32 v) { return v; } - inline UInt64 BEToSystem(UInt64 v) { return v; } - inline SInt64 BEToSystem(SInt64 v) { return v; } + 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 UByte SystemToLE(UByte v) { return SwapOrder(v); } - inline SByte SystemToLE(SByte v) { return SwapOrder(v); } - inline UInt16 SystemToLE(UInt16 v) { return SwapOrder(v); } - inline SInt16 SystemToLE(SInt16 v) { return SwapOrder(v); } - inline UInt32 SystemToLE(UInt32 v) { return SwapOrder(v); } - inline SInt32 SystemToLE(SInt32 v) { return SwapOrder(v); } - inline UInt64 SystemToLE(UInt64 v) { return SwapOrder(v); } - inline SInt64 SystemToLE(SInt64 v) { return SwapOrder(v); } + 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 UByte SystemToBE(UByte v) { return v; } - inline SByte SystemToBE(SByte v) { return v; } - inline UInt16 SystemToBE(UInt16 v) { return v; } - inline SInt16 SystemToBE(SInt16 v) { return v; } - inline UInt32 SystemToBE(UInt32 v) { return v; } - inline SInt32 SystemToBE(SInt32 v) { return v; } - inline UInt64 SystemToBE(UInt64 v) { return v; } - inline SInt64 SystemToBE(SInt64 v) { return v; } + 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; } @@ -983,30 +985,30 @@ namespace ByteUtil { // Used primarily for hardware interfacing such as sensor reports, firmware, etc. // Reported data is all little-endian. -inline UInt16 DecodeUInt16(const UByte* buffer) +inline uint16_t DecodeUInt16(const uint8_t* buffer) { - return ByteUtil::LEToSystem ( *(const UInt16*)buffer ); + return ByteUtil::LEToSystem ( *(const uint16_t*)buffer ); } -inline SInt16 DecodeSInt16(const UByte* buffer) +inline int16_t DecodeSInt16(const uint8_t* buffer) { - return ByteUtil::LEToSystem ( *(const SInt16*)buffer ); + return ByteUtil::LEToSystem ( *(const int16_t*)buffer ); } -inline UInt32 DecodeUInt32(const UByte* buffer) +inline uint32_t DecodeUInt32(const uint8_t* buffer) { - return ByteUtil::LEToSystem ( *(const UInt32*)buffer ); + return ByteUtil::LEToSystem ( *(const uint32_t*)buffer ); } -inline SInt32 DecodeSInt32(const UByte* buffer) +inline int32_t DecodeSInt32(const uint8_t* buffer) { - return ByteUtil::LEToSystem ( *(const SInt32*)buffer ); + return ByteUtil::LEToSystem ( *(const int32_t*)buffer ); } -inline float DecodeFloat(const UByte* buffer) +inline float DecodeFloat(const uint8_t* buffer) { union { - UInt32 U; + uint32_t U; float F; }; @@ -1014,30 +1016,30 @@ inline float DecodeFloat(const UByte* buffer) return F; } -inline void EncodeUInt16(UByte* buffer, UInt16 val) +inline void EncodeUInt16(uint8_t* buffer, uint16_t val) { - *(UInt16*)buffer = ByteUtil::SystemToLE ( val ); + *(uint16_t*)buffer = ByteUtil::SystemToLE ( val ); } -inline void EncodeSInt16(UByte* buffer, SInt16 val) +inline void EncodeSInt16(uint8_t* buffer, int16_t val) { - *(SInt16*)buffer = ByteUtil::SystemToLE ( val ); + *(int16_t*)buffer = ByteUtil::SystemToLE ( val ); } -inline void EncodeUInt32(UByte* buffer, UInt32 val) +inline void EncodeUInt32(uint8_t* buffer, uint32_t val) { - *(UInt32*)buffer = ByteUtil::SystemToLE ( val ); + *(uint32_t*)buffer = ByteUtil::SystemToLE ( val ); } -inline void EncodeSInt32(UByte* buffer, SInt32 val) +inline void EncodeSInt32(uint8_t* buffer, int32_t val) { - *(SInt32*)buffer = ByteUtil::SystemToLE ( val ); + *(int32_t*)buffer = ByteUtil::SystemToLE ( val ); } -inline void EncodeFloat(UByte* buffer, float val) +inline void EncodeFloat(uint8_t* buffer, float val) { union { - UInt32 U; + uint32_t U; float F; }; @@ -1046,12 +1048,12 @@ inline void EncodeFloat(UByte* buffer, float val) } // Converts an 8-bit binary-coded decimal -inline SByte DecodeBCD(UByte byte) +inline int8_t DecodeBCD(uint8_t byte) { - UByte digit1 = (byte >> 4) & 0x0f; - UByte digit2 = byte & 0x0f; + uint8_t digit1 = (byte >> 4) & 0x0f; + uint8_t digit2 = byte & 0x0f; int decimal = digit1 * 10 + digit2; // maximum value = 99 - return (SByte)decimal; + return (int8_t)decimal; } diff --git a/LibOVR/Src/Kernel/OVR_Allocator.cpp b/LibOVR/Src/Kernel/OVR_Allocator.cpp index 0f82561..f963d08 100644 --- a/LibOVR/Src/Kernel/OVR_Allocator.cpp +++ b/LibOVR/Src/Kernel/OVR_Allocator.cpp @@ -5,16 +5,16 @@ Content : Installable memory allocator implementation Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -31,6 +31,14 @@ limitations under the License. #include #endif +#if defined(OVR_OS_MS) + #include +#elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) + #include + #include +#endif + + namespace OVR { //----------------------------------------------------------------------------------- @@ -39,25 +47,25 @@ namespace OVR { Allocator* Allocator::pInstance = 0; // Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding. -void* Allocator::AllocAligned(UPInt size, UPInt align) +void* Allocator::AllocAligned(size_t size, size_t align) { OVR_ASSERT((align & (align-1)) == 0); - align = (align > sizeof(UPInt)) ? align : sizeof(UPInt); - UPInt p = (UPInt)Alloc(size+align); - UPInt aligned = 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 = (UPInt(p) + align-1) & ~(align-1); + aligned = (size_t(p) + align-1) & ~(align-1); if (aligned == p) aligned += align; - *(((UPInt*)aligned)-1) = aligned-p; + *(((size_t*)aligned)-1) = aligned-p; } return (void*)aligned; } void Allocator::FreeAligned(void* p) { - UPInt src = UPInt(p) - *(((UPInt*)p)-1); + size_t src = size_t(p) - *(((size_t*)p)-1); Free((void*)src); } @@ -68,21 +76,21 @@ void Allocator::FreeAligned(void* p) // This allocator is created and used if no other allocator is installed. // Default allocator delegates to system malloc. -void* DefaultAllocator::Alloc(UPInt size) +void* DefaultAllocator::Alloc(size_t size) { return malloc(size); } -void* DefaultAllocator::AllocDebug(UPInt size, const char* file, unsigned line) +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 - OVR_UNUSED2(file, line); return malloc(size); #endif } -void* DefaultAllocator::Realloc(void* p, UPInt newSize) +void* DefaultAllocator::Realloc(void* p, size_t newSize) { return realloc(p, newSize); } @@ -92,4 +100,42 @@ void DefaultAllocator::Free(void *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 index b862557..dcf097d 100644 --- a/LibOVR/Src/Kernel/OVR_Allocator.h +++ b/LibOVR/Src/Kernel/OVR_Allocator.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +PublicHeader: OVR_Kernel.h Filename : OVR_Allocator.h Content : Installable memory allocator Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -56,7 +56,7 @@ limitations under the License. # include # else // Useful on MSVC - OVR_FORCE_INLINE void* operator new (OVR::UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; } + 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 @@ -71,9 +71,9 @@ limitations under the License. // class member operator new. #define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \ - void* operator new(UPInt sz) \ + void* operator new(size_t sz) \ { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; } \ - void* operator new(UPInt sz, const char* file, int line) \ + 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); } \ @@ -81,7 +81,7 @@ limitations under the License. { check_delete(class_name, p); OVR_FREE(p); } #define OVR_MEMORY_DEFINE_PLACEMENT_NEW \ - void* operator new (UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; } \ + void* operator new (size_t n, void *ptr) { OVR_UNUSED(n); return ptr; } \ void operator delete (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); } @@ -127,20 +127,20 @@ OVR_FORCE_INLINE T* ConstructAlt(void *p, const S1& src1, const S2& src2) } template -OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count) +OVR_FORCE_INLINE void ConstructArray(void *p, size_t count) { - UByte *pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + 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, UPInt count, const T& source) +OVR_FORCE_INLINE void ConstructArray(void *p, size_t count, const T& source) { - UByte *pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + uint8_t *pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) { Construct(pdata, source); } @@ -154,9 +154,9 @@ OVR_FORCE_INLINE void Destruct(T *pobj) } template -OVR_FORCE_INLINE void DestructArray(T *pobj, UPInt count) +OVR_FORCE_INLINE void DestructArray(T *pobj, size_t count) { - for (UPInt i=0; i~T(); } @@ -178,15 +178,16 @@ 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(UPInt size) = 0; + virtual void* Alloc(size_t size) = 0; // Same as Alloc, but provides an option of passing debug data. - virtual void* AllocDebug(UPInt size, const char* file, unsigned line) + 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 @@ -195,7 +196,7 @@ public: // 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, UPInt newSize) = 0; + 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. @@ -207,7 +208,7 @@ public: // 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(UPInt size, UPInt align); + virtual void* AllocAligned(size_t size, size_t align); // Frees memory allocated with AllocAligned. virtual void FreeAligned(void* p); @@ -250,7 +251,7 @@ class Allocator_SingletonSupport : public Allocator { struct AllocContainer { - UPInt Data[(sizeof(D) + sizeof(UPInt)-1) / sizeof(UPInt)]; + size_t Data[(sizeof(D) + sizeof(size_t)-1) / sizeof(size_t)]; bool Initialized; AllocContainer() : Initialized(0) { } }; @@ -295,9 +296,9 @@ protected: class DefaultAllocator : public Allocator_SingletonSupport { public: - virtual void* Alloc(UPInt size); - virtual void* AllocDebug(UPInt size, const char* file, unsigned line); - virtual void* Realloc(void* p, UPInt newSize); + 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); }; @@ -335,6 +336,18 @@ public: }; +//------------------------------------------------------------------------ +// ***** 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 diff --git a/LibOVR/Src/Kernel/OVR_Array.h b/LibOVR/Src/Kernel/OVR_Array.h index 7a715ba..7855a5b 100644 --- a/LibOVR/Src/Kernel/OVR_Array.h +++ b/LibOVR/Src/Kernel/OVR_Array.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +PublicHeader: OVR_Kernel.h Filename : OVR_Array.h Content : Template implementation for Array Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -44,14 +44,14 @@ struct ArrayDefaultPolicy ArrayDefaultPolicy() : Capacity(0) {} ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {} - UPInt GetMinCapacity() const { return 0; } - UPInt GetGranularity() const { return 4; } + size_t GetMinCapacity() const { return 0; } + size_t GetGranularity() const { return 4; } bool NeverShrinking() const { return 0; } - UPInt GetCapacity() const { return Capacity; } - void SetCapacity(UPInt capacity) { Capacity = capacity; } + size_t GetCapacity() const { return Capacity; } + void SetCapacity(size_t capacity) { Capacity = capacity; } private: - UPInt Capacity; + size_t Capacity; }; @@ -68,14 +68,14 @@ struct ArrayConstPolicy ArrayConstPolicy() : Capacity(0) {} ArrayConstPolicy(const SelfType&) : Capacity(0) {} - UPInt GetMinCapacity() const { return MinCapacity; } - UPInt GetGranularity() const { return Granularity; } + size_t GetMinCapacity() const { return MinCapacity; } + size_t GetGranularity() const { return Granularity; } bool NeverShrinking() const { return NeverShrink; } - UPInt GetCapacity() const { return Capacity; } - void SetCapacity(UPInt capacity) { Capacity = capacity; } + size_t GetCapacity() const { return Capacity; } + void SetCapacity(size_t capacity) { Capacity = capacity; } private: - UPInt Capacity; + size_t Capacity; }; //----------------------------------------------------------------------------------- @@ -103,7 +103,7 @@ struct ArrayDataBase Allocator::Free(Data); } - UPInt GetCapacity() const + size_t GetCapacity() const { return Policy.GetCapacity(); } @@ -117,7 +117,7 @@ struct ArrayDataBase Policy.SetCapacity(0); } - void Reserve(UPInt newCapacity) + void Reserve(size_t newCapacity) { if (Policy.NeverShrinking() && newCapacity < GetCapacity()) return; @@ -137,7 +137,7 @@ struct ArrayDataBase } else { - UPInt gran = Policy.GetGranularity(); + size_t gran = Policy.GetGranularity(); newCapacity = (newCapacity + gran - 1) / gran * gran; if (Data) { @@ -148,7 +148,7 @@ struct ArrayDataBase else { T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity); - UPInt i, s; + size_t i, s; s = (Size < newCapacity) ? Size : newCapacity; for (i = 0; i < s; ++i) { @@ -176,9 +176,9 @@ struct ArrayDataBase // 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(UPInt newSize) + void ResizeNoConstruct(size_t newSize) { - UPInt oldSize = Size; + size_t oldSize = Size; if (newSize < oldSize) { @@ -199,7 +199,7 @@ struct ArrayDataBase } ValueType* Data; - UPInt Size; + size_t Size; SizePolicy Policy; }; @@ -222,16 +222,16 @@ struct ArrayData : ArrayDataBase ArrayData() : BaseType() { } - ArrayData(UPInt size) + ArrayData(size_t size) : BaseType() { Resize(size); } ArrayData(const SelfType& a) : BaseType(a.Policy) { Append(a.Data, a.Size); } - void Resize(UPInt newSize) + void Resize(size_t newSize) { - UPInt oldSize = this->Size; + size_t oldSize = this->Size; BaseType::ResizeNoConstruct(newSize); if(newSize > oldSize) Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize); @@ -240,6 +240,7 @@ struct ArrayData : ArrayDataBase void PushBack(const ValueType& val) { BaseType::ResizeNoConstruct(this->Size + 1); + OVR_ASSERT(this->Data != NULL); Allocator::Construct(this->Data + this->Size - 1, val); } @@ -251,11 +252,11 @@ struct ArrayData : ArrayDataBase } // Append the given data to the array. - void Append(const ValueType other[], UPInt count) + void Append(const ValueType other[], size_t count) { if (count) { - UPInt oldSize = this->Size; + size_t oldSize = this->Size; BaseType::ResizeNoConstruct(this->Size + count); Allocator::ConstructArray(this->Data + oldSize, count, other); } @@ -281,16 +282,16 @@ struct ArrayDataCC : ArrayDataBase ArrayDataCC(const ValueType& defval) : BaseType(), DefaultValue(defval) { } - ArrayDataCC(const ValueType& defval, UPInt size) + 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(UPInt newSize) + void Resize(size_t newSize) { - UPInt oldSize = this->Size; + size_t oldSize = this->Size; BaseType::ResizeNoConstruct(newSize); if(newSize > oldSize) Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue); @@ -310,11 +311,11 @@ struct ArrayDataCC : ArrayDataBase } // Append the given data to the array. - void Append(const ValueType other[], UPInt count) + void Append(const ValueType other[], size_t count) { if (count) { - UPInt oldSize = this->Size; + size_t oldSize = this->Size; BaseType::ResizeNoConstruct(this->Size + count); Allocator::ConstructArray(this->Data + oldSize, count, other); } @@ -359,64 +360,65 @@ public: ArrayBase() : Data() {} - ArrayBase(UPInt size) + ArrayBase(size_t size) : Data(size) {} ArrayBase(const SelfType& a) : Data(a.Data) {} ArrayBase(const ValueType& defval) : Data(defval) {} - ArrayBase(const ValueType& defval, UPInt size) + 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(); } - UPInt GetSize() const { return Data.Size; } - bool IsEmpty() const { return Data.Size == 0; } - UPInt GetCapacity() const { return Data.GetCapacity(); } - UPInt GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); } + 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(UPInt newSize) { Data.Resize(newSize); } + void Resize(size_t newSize) { Data.Resize(newSize); } // Reserve can only increase the capacity - void Reserve(UPInt newCapacity) + void Reserve(size_t newCapacity) { if (newCapacity > Data.GetCapacity()) Data.Reserve(newCapacity); } // Basic access. - ValueType& At(UPInt index) + ValueType& At(size_t index) { - OVR_ASSERT(index < Data.Size); - return Data.Data[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(UPInt index) const + const ValueType& At(size_t index) const { - OVR_ASSERT(index < Data.Size); - return Data.Data[index]; + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; } - ValueType ValueAt(UPInt index) const + ValueType ValueAt(size_t index) const { - OVR_ASSERT(index < Data.Size); - return Data.Data[index]; + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; } // Basic access. - ValueType& operator [] (UPInt index) + ValueType& operator [] (size_t index) { - OVR_ASSERT(index < Data.Size); + OVR_ASSERT((Data.Data) && (index < Data.Size)); return Data.Data[index]; } - const ValueType& operator [] (UPInt index) const + const ValueType& operator [] (size_t index) const { - OVR_ASSERT(index < Data.Size); - return Data.Data[index]; + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; } // Raw pointer to the data. Use with caution! @@ -440,7 +442,7 @@ public: } // Remove the last element. - void PopBack(UPInt count = 1) + void PopBack(size_t count = 1) { OVR_ASSERT(Data.Size >= count); Data.Resize(Data.Size - count); @@ -454,6 +456,7 @@ public: ValueType Pop() { + OVR_ASSERT((Data.Data) && (Data.Size > 0)); ValueType t = Back(); PopBack(); return t; @@ -472,14 +475,15 @@ public: const SelfType& operator = (const SelfType& a) { Resize(a.GetSize()); - for (UPInt i = 0; i < Data.Size; i++) { + 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(UPInt index, UPInt num) + void RemoveMultipleAt(size_t index, size_t num) { OVR_ASSERT(index + num <= Data.Size); if (Data.Size == num) @@ -502,9 +506,9 @@ public: // If order of elements in the array is not important then use // RemoveAtUnordered, that could be much faster than the regular // RemoveAt. - void RemoveAt(UPInt index) + void RemoveAt(size_t index) { - OVR_ASSERT(index < Data.Size); + OVR_ASSERT((Data.Data) && (index < Data.Size)); if (Data.Size == 1) { Clear(); @@ -523,9 +527,9 @@ public: // 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(UPInt index) + void RemoveAtUnordered(size_t index) { - OVR_ASSERT(index < Data.Size); + OVR_ASSERT((Data.Data) && (index < Data.Size)); if (Data.Size == 1) { Clear(); @@ -535,7 +539,7 @@ public: // copy the last element into the 'index' position // and decrement the size (instead of moving all elements // in [index + 1 .. size - 1] range). - const UPInt lastElemIndex = Data.Size - 1; + const size_t lastElemIndex = Data.Size - 1; if (index < lastElemIndex) { AllocatorType::Destruct(Data.Data + index); @@ -547,7 +551,7 @@ public: } // Insert the given object at the given index shifting all the elements up. - void InsertAt(UPInt index, const ValueType& val = ValueType()) + void InsertAt(size_t index, const ValueType& val = ValueType()) { OVR_ASSERT(index <= Data.Size); @@ -563,7 +567,7 @@ public: } // Insert the given object at the given index shifting all the elements up. - void InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType()) + void InsertMultipleAt(size_t index, size_t num, const ValueType& val = ValueType()) { OVR_ASSERT(index <= Data.Size); @@ -575,7 +579,7 @@ public: Data.Data + index, Data.Size - num - index); } - for (UPInt i = 0; i < num; ++i) + for (size_t i = 0; i < num; ++i) AllocatorType::Construct(Data.Data + index + i, val); } @@ -586,7 +590,7 @@ public: } // Append the given data to the array. - void Append(const ValueType other[], UPInt count) + void Append(const ValueType other[], size_t count) { Data.Append(other, count); } @@ -594,11 +598,11 @@ public: class Iterator { SelfType* pArray; - SPInt CurIndex; + intptr_t CurIndex; public: Iterator() : pArray(0), CurIndex(-1) {} - Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {} + 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; } @@ -607,7 +611,7 @@ public: { if (pArray) { - if (CurIndex < (SPInt)pArray->GetSize()) + if (CurIndex < (intptr_t)pArray->GetSize()) ++CurIndex; } return *this; @@ -641,7 +645,7 @@ public: { return Iterator(pArray, CurIndex - delta); } - SPInt operator-(const Iterator& right) const + intptr_t operator-(const Iterator& right) const { OVR_ASSERT(pArray == right.pArray); return CurIndex - right.CurIndex; @@ -658,21 +662,21 @@ public: pArray->RemoveAt(CurIndex); } - SPInt GetIndex() const { return CurIndex; } + intptr_t GetIndex() const { return CurIndex; } }; Iterator Begin() { return Iterator(this); } - Iterator End() { return Iterator(this, (SPInt)GetSize()); } - Iterator Last() { return Iterator(this, (SPInt)GetSize() - 1); } + Iterator End() { return Iterator(this, (intptr_t)GetSize()); } + Iterator Last() { return Iterator(this, (intptr_t)GetSize() - 1); } class ConstIterator { const SelfType* pArray; - SPInt CurIndex; + intptr_t CurIndex; public: ConstIterator() : pArray(0), CurIndex(-1) {} - ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {} + 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; } @@ -715,7 +719,7 @@ public: { return ConstIterator(pArray, CurIndex - delta); } - SPInt operator-(const ConstIterator& right) const + intptr_t operator-(const ConstIterator& right) const { OVR_ASSERT(pArray == right.pArray); return CurIndex - right.CurIndex; @@ -726,11 +730,11 @@ public: bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } - SPInt GetIndex() const { return CurIndex; } + intptr_t GetIndex() const { return CurIndex; } }; ConstIterator Begin() const { return ConstIterator(this); } - ConstIterator End() const { return ConstIterator(this, (SPInt)GetSize()); } - ConstIterator Last() const { return ConstIterator(this, (SPInt)GetSize() - 1); } + ConstIterator End() const { return ConstIterator(this, (intptr_t)GetSize()); } + ConstIterator Last() const { return ConstIterator(this, (intptr_t)GetSize() - 1); } protected: ArrayData Data; @@ -754,7 +758,7 @@ public: typedef ArrayBase, SizePolicy> > BaseType; Array() : BaseType() {} - Array(UPInt size) : BaseType(size) {} + 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; } @@ -776,7 +780,7 @@ public: typedef ArrayBase, SizePolicy> > BaseType; ArrayPOD() : BaseType() {} - ArrayPOD(UPInt size) : BaseType(size) {} + 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; } @@ -798,7 +802,7 @@ public: typedef ArrayBase, SizePolicy> > BaseType; ArrayCPP() : BaseType() {} - ArrayCPP(UPInt size) : BaseType(size) {} + 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; } @@ -822,7 +826,7 @@ public: typedef ArrayBase, SizePolicy> > BaseType; ArrayCC(const ValueType& defval) : BaseType(defval) {} - ArrayCC(const ValueType& defval, UPInt size) : BaseType(defval, size) {} + 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; } diff --git a/LibOVR/Src/Kernel/OVR_Atomic.cpp b/LibOVR/Src/Kernel/OVR_Atomic.cpp index 9ea6e76..f7cf9a6 100644 --- a/LibOVR/Src/Kernel/OVR_Atomic.cpp +++ b/LibOVR/Src/Kernel/OVR_Atomic.cpp @@ -7,16 +7,16 @@ Content : Contains atomic operations and inline fastest locking Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -32,7 +32,7 @@ limitations under the License. #ifdef OVR_ENABLE_THREADS // Include Windows 8-Metro compatible Synchronization API -#if defined(OVR_OS_WIN32) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) +#if defined(OVR_OS_MS) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) #include #endif @@ -41,43 +41,20 @@ namespace OVR { // ***** Windows Lock implementation -#if defined(OVR_OS_WIN32) +#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, spinCount, - OVR_DEBUG_SELECT(NULL, CRITICAL_SECTION_NO_DEBUG_INFO)); -#else - // Spin count init critical section function prototype for Window NT - typedef BOOL (WINAPI *Function_InitializeCriticalSectionAndSpinCount) - (LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount); - - - // Try to load function dynamically so that we don't require NT - // On Windows NT we will use InitializeCriticalSectionAndSpinCount - static bool initTried = 0; - static Function_InitializeCriticalSectionAndSpinCount pInitFn = 0; - - if (!initTried) - { - HMODULE hmodule = ::LoadLibrary(OVR_STR("kernel32.dll")); - pInitFn = (Function_InitializeCriticalSectionAndSpinCount) - ::GetProcAddress(hmodule, "InitializeCriticalSectionAndSpinCount"); - initTried = true; - } - - // Initialize the critical section - if (pInitFn) - pInitFn(&cs, spinCount); - else - ::InitializeCriticalSection(&cs); -#endif - + #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 } @@ -107,7 +84,7 @@ Lock* SharedLock::GetLockAddRef() do { oldUseCount = UseCount; - if (oldUseCount == LockInitMarker) + if (oldUseCount == (int)LockInitMarker) continue; if (oldUseCount == 0) @@ -137,7 +114,7 @@ void SharedLock::ReleaseLock(Lock* plock) do { oldUseCount = UseCount; - OVR_ASSERT(oldUseCount != LockInitMarker); + OVR_ASSERT(oldUseCount != (int)LockInitMarker); if (oldUseCount == 1) { diff --git a/LibOVR/Src/Kernel/OVR_Atomic.h b/LibOVR/Src/Kernel/OVR_Atomic.h index b826251..478077b 100644 --- a/LibOVR/Src/Kernel/OVR_Atomic.h +++ b/LibOVR/Src/Kernel/OVR_Atomic.h @@ -1,6 +1,6 @@ /************************************************************************************ -PublicHeader: OVR.h +PublicHeader: OVR_Kernel.h Filename : OVR_Atomic.h Content : Contains atomic operations and inline fastest locking functionality. Will contain #ifdefs for OS efficiency. @@ -8,16 +8,16 @@ Content : Contains atomic operations and inline fastest locking Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -26,18 +26,26 @@ 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_WIN32) -#include +#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 { @@ -50,7 +58,7 @@ template class AtomicOps; template class AtomicInt; template class AtomicPtr; -class Lock; +class Lock; //----------------------------------------------------------------------------------- @@ -93,7 +101,7 @@ class Lock; struct AtomicOpsRawBase { -#if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_OS_WIN32) || defined(OVR_OS_IPHONE) +#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() { } }; @@ -109,12 +117,11 @@ struct AtomicOpsRawBase struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } }; struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } }; -#elif defined(OVR_CPU_ARM) +#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() { } }; @@ -130,11 +137,11 @@ 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; + typedef uint32_t T; // *** Thread - Safe Atomic Versions. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_MS) // Use special defined for VC6, where volatile is not used and // InterlockedCompareExchange is declared incorrectly. @@ -153,10 +160,10 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase 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; - static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j) + typedef uint32_t T; + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) { - UInt32 ret; + uint32_t ret; asm volatile("1:\n\t" "lwarx %[r],0,%[i]\n\t" @@ -167,9 +174,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return ret; } - static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j) + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) { - UInt32 dummy, ret; + uint32_t dummy, ret; asm volatile("1:\n\t" "lwarx %[r],0,%[i]\n\t" @@ -181,9 +188,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return ret; } - static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value) + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) { - UInt32 ret; + uint32_t ret; asm volatile("1:\n\t" "lwarx %[r],0,%[i]\n\t" @@ -199,11 +206,11 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase } #elif defined(OVR_CPU_MIPS) - typedef UInt32 T; + typedef uint32_t T; - static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j) + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) { - UInt32 ret; + uint32_t ret; asm volatile("1:\n\t" "ll %[r],0(%[i])\n\t" @@ -215,9 +222,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return ret; } - static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j) + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) { - UInt32 ret; + uint32_t ret; asm volatile("1:\n\t" "ll %[r],0(%[i])\n\t" @@ -230,9 +237,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return ret; } - static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value) + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) { - UInt32 ret, dummy; + uint32_t ret, dummy; asm volatile("1:\n\t" "move %[r],$0\n\t" @@ -250,9 +257,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase } #elif defined(OVR_CPU_ARM) && defined(OVR_CC_ARM) - typedef UInt32 T; + typedef uint32_t T; - static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j) + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) { for(;;) { @@ -261,7 +268,7 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return r; } } - static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j) + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) { for(;;) { @@ -271,7 +278,7 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase } } - static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value) + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) { for(;;) { @@ -284,11 +291,11 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase } #elif defined(OVR_CPU_ARM) - typedef UInt32 T; + typedef uint32_t T; - static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j) + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) { - UInt32 ret, dummy; + uint32_t ret, dummy; asm volatile("1:\n\t" "ldrex %[r],[%[i]]\n\t" @@ -300,9 +307,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return ret; } - static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j) + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) { - UInt32 ret, dummy, test; + uint32_t ret, dummy, test; asm volatile("1:\n\t" "ldrex %[r],[%[i]]\n\t" @@ -315,9 +322,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return ret; } - static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value) + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) { - UInt32 ret = 1, dummy, test; + uint32_t ret = 1, dummy, test; asm volatile("1:\n\t" "ldrex %[o],[%[i]]\n\t" @@ -334,9 +341,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase } #elif defined(OVR_CPU_X86) - typedef UInt32 T; + typedef uint32_t T; - static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j) + 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"); @@ -344,7 +351,7 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return j; } - static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 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"); @@ -352,9 +359,9 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase return j; } - static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value) + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) { - UInt32 ret; + uint32_t ret; asm volatile("lock; cmpxchgl %[v],%[i]\n" : "+m" (*i), "=a" (ret) : [i] "m" (*i), "1" (c), [v] "q" (value) : "cc", "memory"); @@ -364,7 +371,7 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1) - typedef UInt32 T; + typedef uint32_t T; static inline T Exchange_NoSync(volatile T *i, T j) { @@ -396,10 +403,10 @@ 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; + typedef uint64_t T; // *** Thread - Safe OS specific versions. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_MS) // This is only for 64-bit systems. typedef LONG64 T; @@ -410,11 +417,11 @@ struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase #elif defined(OVR_CPU_PPC64) - typedef UInt64 T; + typedef uint64_t T; - static inline UInt64 Exchange_NoSync(volatile UInt64 *i, UInt64 j) + static inline uint64_t Exchange_NoSync(volatile uint64_t *i, uint64_t j) { - UInt64 dummy, ret; + uint64_t dummy, ret; asm volatile("1:\n\t" "ldarx %[r],0,%[i]\n\t" @@ -426,9 +433,9 @@ struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase return ret; } - static inline UInt64 ExchangeAdd_NoSync(volatile UInt64 *i, UInt64 j) + static inline uint64_t ExchangeAdd_NoSync(volatile uint64_t *i, uint64_t j) { - UInt64 dummy, ret; + uint64_t dummy, ret; asm volatile("1:\n\t" "ldarx %[r],0,%[i]\n\t" @@ -440,9 +447,9 @@ struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase return ret; } - static inline bool CompareAndSet_NoSync(volatile UInt64 *i, UInt64 c, UInt64 value) + static inline bool CompareAndSet_NoSync(volatile uint64_t *i, uint64_t c, uint64_t value) { - UInt64 ret, dummy; + uint64_t ret, dummy; asm volatile("1:\n\t" "ldarx %[r],0,%[i]\n\t" @@ -459,7 +466,7 @@ struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1) - typedef UInt64 T; + typedef uint64_t T; static inline T Exchange_NoSync(volatile T *i, T j) { @@ -533,7 +540,22 @@ struct AtomicOpsRaw_DefImpl : public O #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); return *p; } + 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; + } }; @@ -583,11 +605,15 @@ public: 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_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); } + 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); } }; @@ -616,7 +642,7 @@ public: 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_Relse(&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); } @@ -787,7 +813,6 @@ public: }; - //----------------------------------------------------------------------------------- // ***** Lock @@ -816,11 +841,11 @@ public: inline void Unlock() { } // Windows. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_MS) CRITICAL_SECTION cs; public: - Lock(unsigned spinCount = 0); + Lock(unsigned spinCount = 10000); // Mutexes with non-zero spin counts usually result in better performance. ~Lock(); // Locking functions. inline void DoLock() { ::EnterCriticalSection(&cs); } @@ -833,9 +858,9 @@ public: static pthread_mutexattr_t RecursiveAttr; static bool RecursiveAttrInit; - Lock (unsigned dummy = 0) + Lock (unsigned spinCount = 0) // To do: Support spin count, probably via a custom lock implementation. { - OVR_UNUSED(dummy); + OVR_UNUSED(spinCount); if (!RecursiveAttrInit) { pthread_mutexattr_init(&RecursiveAttr); @@ -881,7 +906,7 @@ private: // UseCount and max alignment. volatile int UseCount; - UInt64 Buffer[(sizeof(Lock)+sizeof(UInt64)-1)/sizeof(UInt64)]; + uint64_t Buffer[(sizeof(Lock)+sizeof(uint64_t)-1)/sizeof(uint64_t)]; }; diff --git a/LibOVR/Src/Kernel/OVR_CRC32.cpp b/LibOVR/Src/Kernel/OVR_CRC32.cpp new file mode 100644 index 0000000..82cbe7f --- /dev/null +++ b/LibOVR/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/LibOVR/Src/Kernel/OVR_CRC32.h b/LibOVR/Src/Kernel/OVR_CRC32.h new file mode 100644 index 0000000..e4edd65 --- /dev/null +++ b/LibOVR/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/LibOVR/Src/Kernel/OVR_Color.h b/LibOVR/Src/Kernel/OVR_Color.h index cf536da..7b5e966 100644 --- a/LibOVR/Src/Kernel/OVR_Color.h +++ b/LibOVR/Src/Kernel/OVR_Color.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +PublicHeader: OVR_Kernel.h Filename : OVR_Color.h Content : Contains color struct. Created : February 7, 2013 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -31,11 +31,17 @@ limitations under the License. namespace OVR { + struct Color { - UByte R,G,B,A; + uint8_t R,G,B,A; - Color() {} + 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. @@ -61,6 +67,7 @@ struct Color } }; -} + +} // namespace OVR #endif diff --git a/LibOVR/Src/Kernel/OVR_Compiler.h b/LibOVR/Src/Kernel/OVR_Compiler.h new file mode 100644 index 0000000..93a4181 --- /dev/null +++ b/LibOVR/Src/Kernel/OVR_Compiler.h @@ -0,0 +1,1524 @@ +/************************************************************************************ + +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 index afc0e6a..46bea2e 100644 --- a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h +++ b/LibOVR/Src/Kernel/OVR_ContainerAllocator.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -45,8 +45,8 @@ namespace OVR { class ContainerAllocatorBase { public: - static void* Alloc(UPInt size) { return OVR_ALLOC(size); } - static void* Realloc(void* p, UPInt newSize) { return OVR_REALLOC(p, newSize); } + 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); } }; @@ -73,29 +73,29 @@ public: *(T*)p = source; } - static void ConstructArray(void*, UPInt) {} + static void ConstructArray(void*, size_t) {} - static void ConstructArray(void* p, UPInt count, const T& source) + static void ConstructArray(void* p, size_t count, const T& source) { - UByte *pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + 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, UPInt count, const T* psource) + 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*, UPInt) {} + static void DestructArray(T*, size_t) {} - static void CopyArrayForward(T* dst, const T* src, UPInt count) + 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, UPInt count) + static void CopyArrayBackward(T* dst, const T* src, size_t count) { memmove(dst, src, count * sizeof(T)); } @@ -129,24 +129,24 @@ public: OVR::ConstructAlt(p, source); } - static void ConstructArray(void* p, UPInt count) + static void ConstructArray(void* p, size_t count) { - UByte* pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) Construct(pdata); } - static void ConstructArray(void* p, UPInt count, const T& source) + static void ConstructArray(void* p, size_t count, const T& source) { - UByte* pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + 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, UPInt count, const T* psource) + static void ConstructArray(void* p, size_t count, const T* psource) { - UByte* pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) Construct(pdata, *psource++); } @@ -156,19 +156,19 @@ public: OVR_UNUSED(p); // Suppress silly MSVC warning } - static void DestructArray(T* p, UPInt count) + static void DestructArray(T* p, size_t count) { p += count - 1; - for (UPInt i=0; i~T(); } - static void CopyArrayForward(T* dst, const T* src, UPInt count) + 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, UPInt count) + static void CopyArrayBackward(T* dst, const T* src, size_t count) { memmove(dst, src, count * sizeof(T)); } @@ -202,24 +202,24 @@ public: OVR::ConstructAlt(p, source); } - static void ConstructArray(void* p, UPInt count) + static void ConstructArray(void* p, size_t count) { - UByte* pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) Construct(pdata); } - static void ConstructArray(void* p, UPInt count, const T& source) + static void ConstructArray(void* p, size_t count, const T& source) { - UByte* pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + 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, UPInt count, const T* psource) + static void ConstructArray(void* p, size_t count, const T* psource) { - UByte* pdata = (UByte*)p; - for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) Construct(pdata, *psource++); } @@ -229,22 +229,22 @@ public: OVR_UNUSED(p); // Suppress silly MSVC warning } - static void DestructArray(T* p, UPInt count) + static void DestructArray(T* p, size_t count) { p += count - 1; - for (UPInt i=0; i~T(); } - static void CopyArrayForward(T* dst, const T* src, UPInt count) + static void CopyArrayForward(T* dst, const T* src, size_t count) { - for(UPInt i = 0; i < count; ++i) + for(size_t i = 0; i < count; ++i) dst[i] = src[i]; } - static void CopyArrayBackward(T* dst, const T* src, UPInt count) + static void CopyArrayBackward(T* dst, const T* src, size_t count) { - for(UPInt i = count; i; --i) + for(size_t i = count; i; --i) dst[i-1] = src[i-1]; } diff --git a/LibOVR/Src/Kernel/OVR_DebugHelp.cpp b/LibOVR/Src/Kernel/OVR_DebugHelp.cpp new file mode 100644 index 0000000..fe7b54f --- /dev/null +++ b/LibOVR/Src/Kernel/OVR_DebugHelp.cpp @@ -0,0 +1,3926 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..2430ae4 --- /dev/null +++ b/LibOVR/Src/Kernel/OVR_DebugHelp.h @@ -0,0 +1,461 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..88948b4 --- /dev/null +++ b/LibOVR/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/LibOVR/Src/Kernel/OVR_Deque.h b/LibOVR/Src/Kernel/OVR_Deque.h index ca242ad..951ed84 100644 --- a/LibOVR/Src/Kernel/OVR_Deque.h +++ b/LibOVR/Src/Kernel/OVR_Deque.h @@ -5,16 +5,16 @@ Content : Deque container Created : Nov. 15, 2013 Authors : Dov Katz -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -27,9 +27,11 @@ limitations under the License. #ifndef OVR_Deque_h #define OVR_Deque_h +#include "OVR_ContainerAllocator.h" + namespace OVR{ -template +template > class Deque { public: @@ -48,8 +50,12 @@ public: 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 UPInt GetSize (void) const; // Returns Number of Elements - virtual inline UPInt GetCapacity(void) const; // Returns the maximum possible number of elements + 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; @@ -65,30 +71,34 @@ protected: int ElemCount; private: - Deque& operator= (const Deque& q) { }; // forbidden - Deque(const Deque &OtherDeque) { }; + OVR_NON_COPYABLE(Deque); }; -template -class InPlaceMutableDeque : public Deque +template > +class InPlaceMutableDeque : public Deque { + typedef Deque BaseType; + public: - InPlaceMutableDeque( int capacity = Deque::DefaultCapacity ) : Deque( capacity ) {} + InPlaceMutableDeque( int capacity = BaseType::DefaultCapacity ) : BaseType( capacity ) {} virtual ~InPlaceMutableDeque() {}; - using Deque::PeekBack; - using Deque::PeekFront; + 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 +template > +class CircularBuffer : public InPlaceMutableDeque { + typedef InPlaceMutableDeque BaseType; + public: - CircularBuffer(int MaxSize = Deque::DefaultCapacity) : InPlaceMutableDeque(MaxSize) { }; + 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 @@ -99,42 +109,54 @@ public: //---------------------------------------------------------------------------------- // Deque Constructor function -template -Deque::Deque(int capacity) : +template +Deque::Deque(int capacity) : Capacity( capacity ), Beginning(0), End(0), ElemCount(0) { - Data = (Elem*) OVR_ALLOC(Capacity * sizeof(Elem)); - ConstructArray(Data, Capacity); + Data = (Elem*) Allocator::Alloc(Capacity * sizeof(Elem)); } // Deque Destructor function -template -Deque::~Deque(void) +template +Deque::~Deque(void) { - DestructArray(Data, Capacity); - OVR_FREE(Data); + Clear(); + Allocator::Free(Data); } -template -void Deque::Clear() +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; - - DestructArray(Data, Capacity); - ConstructArray(Data, Capacity); } // Push functions -template -void Deque::PushBack(const Elem &Item) +template +void Deque::PushBack(const Elem &Item) { // Error Check: Make sure we aren't // exceeding our maximum storage space OVR_ASSERT( ElemCount < Capacity ); - Data[ End++ ] = Item; + Allocator::Construct(Data + End, Item); + ++End; ++ElemCount; // Check for wrap-around @@ -142,32 +164,31 @@ void Deque::PushBack(const Elem &Item) End -= Capacity; } -template -void Deque::PushFront(const Elem &Item) +template +void Deque::PushFront(const Elem &Item) { // Error Check: Make sure we aren't // exceeding our maximum storage space OVR_ASSERT( ElemCount < Capacity ); - Beginning--; + --Beginning; // Check for wrap-around if (Beginning < 0) Beginning += Capacity; - Data[ Beginning ] = Item; + Allocator::Construct(Data + Beginning, Item); ++ElemCount; } // Pop functions -template -Elem Deque::PopFront(void) +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 ]; - Destruct(&Data[ Beginning ]); - Construct(&Data[ Beginning ]); + Allocator::Destruct(Data + Beginning); ++Beginning; --ElemCount; @@ -179,13 +200,13 @@ Elem Deque::PopFront(void) return ReturnValue; } -template -Elem Deque::PopBack(void) +template +Elem Deque::PopBack(void) { // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( ElemCount > 0 ); - End--; + --End; --ElemCount; // Check for wrap-around @@ -193,15 +214,14 @@ Elem Deque::PopBack(void) End += Capacity; Elem ReturnValue = Data[ End ]; - Destruct(&Data[ End ]); - Construct(&Data[ End ]); + Allocator::Destruct(Data + End); return ReturnValue; } // Peek functions -template -const Elem& Deque::PeekFront(int count) const +template +const Elem& Deque::PeekFront(int count) const { // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( ElemCount > count ); @@ -212,8 +232,8 @@ const Elem& Deque::PeekFront(int count) const return Data[ idx ]; } -template -const Elem& Deque::PeekBack(int count) const +template +const Elem& Deque::PeekBack(int count) const { // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( ElemCount > count ); @@ -225,70 +245,70 @@ const Elem& Deque::PeekBack(int count) const } // Mutable Peek functions -template -Elem& InPlaceMutableDeque::PeekFront(int count) +template +Elem& InPlaceMutableDeque::PeekFront(int count) { // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( Deque::ElemCount > count ); + OVR_ASSERT( BaseType::ElemCount > count ); - int idx = Deque::Beginning + count; - if (idx >= Deque::Capacity) - idx -= Deque::Capacity; - return Deque::Data[ idx ]; + int idx = BaseType::Beginning + count; + if (idx >= BaseType::Capacity) + idx -= BaseType::Capacity; + return BaseType::Data[ idx ]; } -template -Elem& InPlaceMutableDeque::PeekBack(int count) +template +Elem& InPlaceMutableDeque::PeekBack(int count) { // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( Deque::ElemCount > count ); + OVR_ASSERT( BaseType::ElemCount > count ); - int idx = Deque::End - count - 1; + int idx = BaseType::End - count - 1; if (idx < 0) - idx += Deque::Capacity; - return Deque::Data[ idx ]; + idx += BaseType::Capacity; + return BaseType::Data[ idx ]; } -template -inline UPInt Deque::GetCapacity(void) const +template +inline size_t Deque::GetCapacity(void) const { - return Deque::Capacity; + return Capacity; } -template -inline UPInt Deque::GetSize(void) const +template +inline size_t Deque::GetSize(void) const { - return Deque::ElemCount; + return ElemCount; } -template -inline bool Deque::IsEmpty(void) const +template +inline bool Deque::IsEmpty(void) const { - return Deque::ElemCount==0; + return ElemCount == 0; } -template -inline bool Deque::IsFull(void) const +template +inline bool Deque::IsFull(void) const { - return Deque::ElemCount==Deque::Capacity; + return ElemCount == Capacity; } // ******* CircularBuffer ******* // Push functions -template -void CircularBuffer::PushBack(const Elem &Item) +template +void CircularBuffer::PushBack(const Elem &Item) { if (this->IsFull()) this->PopFront(); - Deque::PushBack(Item); + BaseType::PushBack(Item); } -template -void CircularBuffer::PushFront(const Elem &Item) +template +void CircularBuffer::PushFront(const Elem &Item) { if (this->IsFull()) this->PopBack(); - Deque::PushFront(Item); + BaseType::PushFront(Item); } }; diff --git a/LibOVR/Src/Kernel/OVR_File.cpp b/LibOVR/Src/Kernel/OVR_File.cpp index 31ab516..c431928 100644 --- a/LibOVR/Src/Kernel/OVR_File.cpp +++ b/LibOVR/Src/Kernel/OVR_File.cpp @@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32) Created : April 5, 1999 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -46,7 +46,7 @@ namespace OVR { // Not supposed to be used BufferedFile::BufferedFile() : DelegatedFile(0) { - pBuffer = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE); + pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); BufferMode = NoBuffer; FilePos = 0; Pos = 0; @@ -56,7 +56,7 @@ BufferedFile::BufferedFile() : DelegatedFile(0) // Takes another file as source BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile) { - pBuffer = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE); + pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); BufferMode = NoBuffer; FilePos = pfile->LTell(); Pos = 0; @@ -177,12 +177,12 @@ int BufferedFile::Tell() return pos; } -SInt64 BufferedFile::LTell() +int64_t BufferedFile::LTell() { if (BufferMode == ReadBuffer) return FilePos - DataSize + Pos; - SInt64 pos = pFile->LTell(); + int64_t pos = pFile->LTell(); if (pos!=-1) { OVR_ASSERT(BufferMode != ReadBuffer); @@ -204,13 +204,13 @@ int BufferedFile::GetLength() } return len; } -SInt64 BufferedFile::LGetLength() +int64_t BufferedFile::LGetLength() { - SInt64 len = pFile->LGetLength(); + int64_t len = pFile->LGetLength(); // If writing through buffer, file length may actually be bigger if ((len!=-1) && (BufferMode==WriteBuffer)) { - SInt64 currPos = pFile->LTell() + Pos; + int64_t currPos = pFile->LTell() + Pos; if (currPos>len) len = currPos; } @@ -225,7 +225,7 @@ bool BufferedFile::Stat(FileStats *pfs) { if (BufferMode==WriteBuffer) { - SInt64 currPos = pFile->LTell() + Pos; + int64_t currPos = pFile->LTell() + Pos; if (currPos > pfs->Size) { pfs->Size = currPos; @@ -239,7 +239,7 @@ bool BufferedFile::Stat(FileStats *pfs) } */ -int BufferedFile::Write(const UByte *psourceBuffer, int numBytes) +int BufferedFile::Write(const uint8_t *psourceBuffer, int numBytes) { if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer)) { @@ -268,7 +268,7 @@ int BufferedFile::Write(const UByte *psourceBuffer, int numBytes) return sz; } -int BufferedFile::Read(UByte *pdestBuffer, int numBytes) +int BufferedFile::Read(uint8_t *pdestBuffer, int numBytes) { if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer)) { @@ -413,7 +413,7 @@ int BufferedFile::Seek(int offset, int origin) // 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)offset) < ~(UInt64)0); + OVR_ASSERT(((FilePos - DataSize + Pos) + (uint64_t)offset) < ~(uint64_t)0); offset = (int)(FilePos - DataSize + Pos) + offset; Pos = DataSize = 0; } @@ -421,7 +421,7 @@ int BufferedFile::Seek(int offset, int origin) { if (((unsigned)offset - (FilePos-DataSize)) <= DataSize) { - OVR_ASSERT((FilePos-DataSize) < ~(UInt64)0); + OVR_ASSERT((FilePos-DataSize) < ~(uint64_t)0); Pos = (unsigned)offset - (unsigned)(FilePos-DataSize); return offset; } @@ -461,7 +461,7 @@ int BufferedFile::Seek(int offset, int origin) return int (FilePos); } -SInt64 BufferedFile::LSeek(SInt64 offset, int origin) +int64_t BufferedFile::LSeek(int64_t offset, int origin) { if (BufferMode == ReadBuffer) { @@ -472,20 +472,20 @@ SInt64 BufferedFile::LSeek(SInt64 offset, int origin) if (((unsigned(offset) + Pos)) <= DataSize) { Pos += (unsigned)offset; - return SInt64(FilePos - DataSize + Pos); + 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 = (SInt64)(FilePos - DataSize + Pos) + offset; + offset = (int64_t)(FilePos - DataSize + Pos) + offset; Pos = DataSize = 0; } else if (origin == Seek_Set) { - if (((UInt64)offset - (FilePos-DataSize)) <= DataSize) + if (((uint64_t)offset - (FilePos-DataSize)) <= DataSize) { - Pos = (unsigned)((UInt64)offset - (FilePos-DataSize)); + Pos = (unsigned)((uint64_t)offset - (FilePos-DataSize)); return offset; } Pos = DataSize = 0; @@ -508,7 +508,7 @@ SInt64 BufferedFile::LSeek(SInt64 offset, int origin) Pos += int (offset); return FilePos - DataSize + Pos; } - else if (origin == Seek_Set && offset >= SInt64(FilePos - DataSize) && offset < SInt64(FilePos)) + else if (origin == Seek_Set && offset >= int64_t(FilePos - DataSize) && offset < int64_t(FilePos)) { Pos = unsigned(offset - FilePos + DataSize); return FilePos - DataSize + Pos; @@ -526,7 +526,7 @@ 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 - UByte buff[0x4000]; + uint8_t* buff = new uint8_t[0x4000]; int count = 0; int szRequest, szRead, szWritten; @@ -544,6 +544,9 @@ int BufferedFile::CopyFromStream(File *pstream, int byteSize) if (szWritten < szRequest) break; } + + delete[] buff; + return count; } @@ -571,8 +574,8 @@ bool BufferedFile::Close() // Find trailing short filename in a path. const char* OVR_CDECL GetShortFilename(const char* purl) { - UPInt len = OVR_strlen(purl); - for (UPInt i=len; i>0; i--) + 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; diff --git a/LibOVR/Src/Kernel/OVR_File.h b/LibOVR/Src/Kernel/OVR_File.h index a8dc615..d9d3b0f 100644 --- a/LibOVR/Src/Kernel/OVR_File.h +++ b/LibOVR/Src/Kernel/OVR_File.h @@ -11,16 +11,16 @@ Notes : errno may not be preserved across use of BaseFile member functio : Directories cannot be deleted while files opened from them are in use (For the GetFullName function) -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -136,11 +136,11 @@ public: // Return position virtual int Tell() = 0; - virtual SInt64 LTell() = 0; + virtual int64_t LTell() = 0; // File size virtual int GetLength() = 0; - virtual SInt64 LGetLength() = 0; + virtual int64_t LGetLength() = 0; // Returns file stats // 0 for failure @@ -156,12 +156,12 @@ public: // 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 UByte *pbufer, int numBytes) = 0; + 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(UByte *pbufer, int numBytes) = 0; + virtual int Read(uint8_t *pbufer, int numBytes) = 0; // Skips (ignores) a given # of bytes // Same return values as Read @@ -183,7 +183,7 @@ public: // Seeking // Returns new position, -1 for error virtual int Seek(int offset, int origin=Seek_Set) = 0; - virtual SInt64 LSeek(SInt64 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); } @@ -203,70 +203,70 @@ public: // Read/Write helpers private: - UInt64 PRead64() { UInt64 v = 0; Read((UByte*)&v, 8); return v; } - UInt32 PRead32() { UInt32 v = 0; Read((UByte*)&v, 4); return v; } - UInt16 PRead16() { UInt16 v = 0; Read((UByte*)&v, 2); return v; } - UByte PRead8() { UByte v = 0; Read((UByte*)&v, 1); return v; } - void PWrite64(UInt64 v) { Write((UByte*)&v, 8); } - void PWrite32(UInt32 v) { Write((UByte*)&v, 4); } - void PWrite16(UInt16 v) { Write((UByte*)&v, 2); } - void PWrite8(UByte v) { Write((UByte*)&v, 1); } + 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(UByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSByte(SByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt8(UByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt8(SByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt16(UInt16 v) { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt16(SInt16 v) { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt32(UInt32 v) { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt32(SInt32 v) { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt64(UInt64 v) { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt64(SInt64 v) { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteFloat(float v) { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 4); } - inline void WriteDouble(double v) { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 8); } + 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(UByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSByteBE(SByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt8BE(UInt16 v) { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt8BE(SInt16 v) { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt16BE(UInt16 v) { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt16BE(UInt16 v) { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt32BE(UInt32 v) { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt32BE(UInt32 v) { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt64BE(UInt64 v) { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt64BE(UInt64 v) { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteFloatBE(float v) { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 4); } - inline void WriteDoubleBE(double v) { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 8); } + 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 UByte ReadUByte() { return (UByte)Alg::ByteUtil::LEToSystem(PRead8()); } - inline SByte ReadSByte() { return (SByte)Alg::ByteUtil::LEToSystem(PRead8()); } - inline UByte ReadUInt8() { return (UByte)Alg::ByteUtil::LEToSystem(PRead8()); } - inline SByte ReadSInt8() { return (SByte)Alg::ByteUtil::LEToSystem(PRead8()); } - inline UInt16 ReadUInt16() { return (UInt16)Alg::ByteUtil::LEToSystem(PRead16()); } - inline SInt16 ReadSInt16() { return (SInt16)Alg::ByteUtil::LEToSystem(PRead16()); } - inline UInt32 ReadUInt32() { return (UInt32)Alg::ByteUtil::LEToSystem(PRead32()); } - inline SInt32 ReadSInt32() { return (SInt32)Alg::ByteUtil::LEToSystem(PRead32()); } - inline UInt64 ReadUInt64() { return (UInt64)Alg::ByteUtil::LEToSystem(PRead64()); } - inline SInt64 ReadSInt64() { return (SInt64)Alg::ByteUtil::LEToSystem(PRead64()); } - inline float ReadFloat() { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::LEToSystem(v); } - inline double ReadDouble() { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::LEToSystem(v); } + 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 UByte ReadUByteBE() { return (UByte)Alg::ByteUtil::BEToSystem(PRead8()); } - inline SByte ReadSByteBE() { return (SByte)Alg::ByteUtil::BEToSystem(PRead8()); } - inline UByte ReadUInt8BE() { return (UByte)Alg::ByteUtil::BEToSystem(PRead8()); } - inline SByte ReadSInt8BE() { return (SByte)Alg::ByteUtil::BEToSystem(PRead8()); } - inline UInt16 ReadUInt16BE() { return (UInt16)Alg::ByteUtil::BEToSystem(PRead16()); } - inline SInt16 ReadSInt16BE() { return (SInt16)Alg::ByteUtil::BEToSystem(PRead16()); } - inline UInt32 ReadUInt32BE() { return (UInt32)Alg::ByteUtil::BEToSystem(PRead32()); } - inline SInt32 ReadSInt32BE() { return (SInt32)Alg::ByteUtil::BEToSystem(PRead32()); } - inline UInt64 ReadUInt64BE() { return (UInt64)Alg::ByteUtil::BEToSystem(PRead64()); } - inline SInt64 ReadSInt64BE() { return (SInt64)Alg::ByteUtil::BEToSystem(PRead64()); } - inline float ReadFloatBE() { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::BEToSystem(v); } - inline double ReadDoubleBE() { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::BEToSystem(v); } + 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); } }; @@ -294,18 +294,18 @@ public: // virtual bool IsRecoverable() { return pFile->IsRecoverable(); } virtual int Tell() { return pFile->Tell(); } - virtual SInt64 LTell() { return pFile->LTell(); } + virtual int64_t LTell() { return pFile->LTell(); } virtual int GetLength() { return pFile->GetLength(); } - virtual SInt64 LGetLength() { return pFile->LGetLength(); } + 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 UByte *pbuffer, int numBytes) { return pFile->Write(pbuffer,numBytes); } - virtual int Read(UByte *pbuffer, int numBytes) { return pFile->Read(pbuffer,numBytes); } + 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); } @@ -315,7 +315,7 @@ public: // Seeking virtual int Seek(int offset, int origin=Seek_Set) { return pFile->Seek(offset,origin); } - virtual SInt64 LSeek(SInt64 offset, int origin=Seek_Set) { return pFile->LSeek(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); } @@ -342,14 +342,14 @@ protected: }; // Buffer & the mode it's in - UByte* pBuffer; + uint8_t* pBuffer; BufferModeType BufferMode; // Position in buffer unsigned Pos; // Data in buffer if reading unsigned DataSize; // Underlying file position - UInt64 FilePos; + uint64_t FilePos; // Initializes buffering to a certain mode bool SetBufferMode(BufferModeType mode); @@ -362,7 +362,8 @@ protected: // Hidden constructor BufferedFile(); - inline BufferedFile(const BufferedFile &source) : DelegatedFile() { OVR_UNUSED(source); } + BufferedFile(const BufferedFile &) : DelegatedFile(), pBuffer(NULL), BufferMode(NoBuffer), Pos(0), DataSize(0), FilePos(0) { } + public: // Constructor @@ -376,15 +377,15 @@ public: // We override all the functions that can possibly // require buffer mode switch, flush, or extra calculations virtual int Tell(); - virtual SInt64 LTell(); + virtual int64_t LTell(); virtual int GetLength(); - virtual SInt64 LGetLength(); + virtual int64_t LGetLength(); // virtual bool Stat(GFileStats *pfs); - virtual int Write(const UByte *pbufer, int numBytes); - virtual int Read(UByte *pbufer, int numBytes); + virtual int Write(const uint8_t *pbufer, int numBytes); + virtual int Read(uint8_t *pbufer, int numBytes); virtual int SkipBytes(int numBytes); @@ -393,7 +394,7 @@ public: virtual bool Flush(); virtual int Seek(int offset, int origin=Seek_Set); - virtual SInt64 LSeek(SInt64 offset, int origin=Seek_Set); + virtual int64_t LSeek(int64_t offset, int origin=Seek_Set); virtual int CopyFromStream(File *pstream, int byteSize); @@ -417,10 +418,10 @@ public: int GetErrorCode() { return 0; } int Tell() { return FileIndex; } - SInt64 LTell() { return (SInt64) FileIndex; } + int64_t LTell() { return (int64_t) FileIndex; } int GetLength() { return FileSize; } - SInt64 LGetLength() { return (SInt64) FileSize; } + int64_t LGetLength() { return (int64_t) FileSize; } bool Close() { @@ -433,12 +434,12 @@ public: return 0; } - int Write(const UByte *pbuffer, int numBytes) + int Write(const uint8_t *pbuffer, int numBytes) { OVR_UNUSED2(pbuffer, numBytes); return 0; } - int Read(UByte *pbufer, int numBytes) + int Read(uint8_t *pbufer, int numBytes) { if (FileIndex + numBytes > FileSize) { @@ -484,14 +485,14 @@ public: return FileIndex; } - SInt64 LSeek(SInt64 offset, int origin = Seek_Set) + int64_t LSeek(int64_t offset, int origin = Seek_Set) { - return (SInt64) Seek((int) offset, origin); + return (int64_t) Seek((int) offset, origin); } public: - MemoryFile (const String& fileName, const UByte *pBuffer, int buffSize) + MemoryFile (const String& fileName, const uint8_t *pBuffer, int buffSize) : FilePath(fileName) { FileData = pBuffer; @@ -501,7 +502,7 @@ public: } // pfileName should be encoded as UTF-8 to support international file names. - MemoryFile (const char* pfileName, const UByte *pBuffer, int buffSize) + MemoryFile (const char* pfileName, const uint8_t *pBuffer, int buffSize) : FilePath(pfileName) { FileData = pBuffer; @@ -512,7 +513,7 @@ public: private: String FilePath; - const UByte *FileData; + const uint8_t *FileData; int FileSize; int FileIndex; bool Valid; diff --git a/LibOVR/Src/Kernel/OVR_FileFILE.cpp b/LibOVR/Src/Kernel/OVR_FileFILE.cpp index 8478086..9b2123f 100644 --- a/LibOVR/Src/Kernel/OVR_FileFILE.cpp +++ b/LibOVR/Src/Kernel/OVR_FileFILE.cpp @@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32) Created : April 5, 1999 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -60,7 +60,8 @@ static int SFerror () return FileConstants::Error_IOError; }; -#ifdef OVR_OS_WIN32 +#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 @@ -73,16 +74,20 @@ public: { if (pfileName && (pfileName[0]!=0) && pfileName[1]==':') { - Disabled = 1; + Disabled = TRUE; OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); } else + { Disabled = 0; + OldMode = 0; + } } ~SysErrorModeDisabler() { - if (Disabled) ::SetErrorMode(OldMode); + if (Disabled) + ::SetErrorMode(OldMode); } }; #else @@ -121,25 +126,31 @@ protected: int LastOp; #ifdef OVR_FILE_VERIFY_SEEK_ERRORS - UByte* pFileTestBuffer; + uint8_t* pFileTestBuffer; unsigned FileTestLength; unsigned TestPos; // File pointer position during tests. #endif public: - FILEFile() + 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 { - Opened = 0; FileName = ""; - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - pFileTestBuffer =0; - 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); @@ -157,21 +168,21 @@ public: // Return position / file size virtual int Tell(); - virtual SInt64 LTell(); + virtual int64_t LTell(); virtual int GetLength(); - virtual SInt64 LGetLength(); + virtual int64_t LGetLength(); // virtual bool Stat(FileStats *pfs); virtual int GetErrorCode(); // ** Stream implementation & I/O - virtual int Write(const UByte *pbuffer, int numBytes); - virtual int Read(UByte *pbuffer, int numBytes); + 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 SInt64 LSeek(SInt64 offset, int origin); + virtual int64_t LSeek(int64_t offset, int origin); virtual int CopyFromStream(File *pStream, int byteSize); virtual bool Close(); @@ -218,7 +229,7 @@ void FILEFile::init() else if (OpenFlags & Open_Write) omode = "r+b"; -#ifdef OVR_OS_WIN32 +#if defined(OVR_OS_MS) SysErrorModeDisabler disabler(FileName.ToCStr()); #endif @@ -248,7 +259,7 @@ void FILEFile::init() fseek(fs, 0, SEEK_END); FileTestLength = ftell(fs); fseek(fs, 0, SEEK_SET); - pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength); + pFileTestBuffer = (uint8_t*)OVR_ALLOC(FileTestLength); if (pFileTestBuffer) { OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength)); @@ -293,9 +304,9 @@ int FILEFile::Tell() return pos; } -SInt64 FILEFile::LTell() +int64_t FILEFile::LTell() { - SInt64 pos = ftell(fs); + int64_t pos = ftell(fs); if (pos < 0) ErrorCode = SFerror(); return pos; @@ -313,13 +324,13 @@ int FILEFile::GetLength() } return -1; } -SInt64 FILEFile::LGetLength() +int64_t FILEFile::LGetLength() { - SInt64 pos = LTell(); + int64_t pos = LTell(); if (pos >= 0) { LSeek (0, Seek_End); - SInt64 size = LTell(); + int64_t size = LTell(); LSeek (pos, Seek_Set); return size; } @@ -332,7 +343,7 @@ int FILEFile::GetErrorCode() } // ** Stream implementation & I/O -int FILEFile::Write(const UByte *pbuffer, int numBytes) +int FILEFile::Write(const uint8_t *pbuffer, int numBytes) { if (LastOp && LastOp != Open_Write) fflush(fs); @@ -349,7 +360,7 @@ int FILEFile::Write(const UByte *pbuffer, int numBytes) return written; } -int FILEFile::Read(UByte *pbuffer, int numBytes) +int FILEFile::Read(uint8_t *pbuffer, int numBytes) { if (LastOp && LastOp != Open_Read) fflush(fs); @@ -362,7 +373,7 @@ int FILEFile::Read(UByte *pbuffer, int numBytes) if (read > 0) { // Read-in data must match our pre-loaded buffer data! - UByte* pcompareBuffer = pFileTestBuffer + TestPos; + uint8_t* pcompareBuffer = pFileTestBuffer + TestPos; for (int i=0; i< read; i++) { OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]); @@ -380,8 +391,8 @@ int FILEFile::Read(UByte *pbuffer, int numBytes) // Seeks ahead to skip bytes int FILEFile::SkipBytes(int numBytes) { - SInt64 pos = LTell(); - SInt64 newPos = LSeek(numBytes, Seek_Cur); + int64_t pos = LTell(); + int64_t newPos = LSeek(numBytes, Seek_Cur); // Return -1 for major error if ((pos==-1) || (newPos==-1)) @@ -396,8 +407,8 @@ int FILEFile::SkipBytes(int numBytes) // Return # of bytes till EOF int FILEFile::BytesAvailable() { - SInt64 pos = LTell(); - SInt64 endPos = LGetLength(); + int64_t pos = LTell(); + int64_t endPos = LGetLength(); // Return -1 for major error if ((pos==-1) || (endPos==-1)) @@ -452,14 +463,14 @@ int FILEFile::Seek(int offset, int origin) return (int)Tell(); } -SInt64 FILEFile::LSeek(SInt64 offset, int origin) +int64_t FILEFile::LSeek(int64_t offset, int origin) { return Seek((int)offset,origin); } int FILEFile::CopyFromStream(File *pstream, int byteSize) { - UByte buff[0x4000]; + uint8_t* buff = new uint8_t[0x4000]; int count = 0; int szRequest, szRead, szWritten; @@ -477,6 +488,9 @@ int FILEFile::CopyFromStream(File *pstream, int byteSize) if (szWritten < szRequest) break; } + + delete[] buff; + return count; } @@ -570,7 +584,7 @@ Ptr FileFILEOpen(const String& path, int flags, int mode) // Helper function: obtain file information time. bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) // 64-bit implementation on Windows. struct __stat64 fileStat; // Stat returns 0 for success. diff --git a/LibOVR/Src/Kernel/OVR_Hash.h b/LibOVR/Src/Kernel/OVR_Hash.h index 04c4db8..3316d1e 100644 --- a/LibOVR/Src/Kernel/OVR_Hash.h +++ b/LibOVR/Src/Kernel/OVR_Hash.h @@ -6,16 +6,16 @@ Content : Template hash-table/set implementation Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -71,8 +71,8 @@ template class IdentityHash { public: - UPInt operator()(const C& data) const - { return (UPInt) data; } + size_t operator()(const C& data) const + { return (size_t) data; } }; // Computes a hash of an object's representation. @@ -84,22 +84,23 @@ public: // 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 UPInt SDBM_Hash(const void* data_in, UPInt size, UPInt seed = 5381) + static OVR_FORCE_INLINE size_t SDBM_Hash(const void* data_in, size_t size, size_t seed = 5381) { - const UByte* data = (const UByte*) data_in; - UPInt h = seed; - while (size > 0) + const uint8_t* data = (const uint8_t*) data_in; + size_t h = seed; + while (size-- > 0) { - size--; - h = (h << 16) + (h << 6) - h + (UPInt)data[size]; + #ifndef __clang_analyzer__ // It mistakenly thinks data is garbage. + h = (h << 16) + (h << 6) - h + (size_t)data[size]; + #endif } return h; } - UPInt operator()(const C& data) const + size_t operator()(const C& data) const { - unsigned char* p = (unsigned char*) &data; - int size = sizeof(C); + const unsigned char* p = (const unsigned char*) &data; + const size_t size = sizeof(C); return SDBM_Hash(p, size); } @@ -116,14 +117,14 @@ class HashsetEntry { public: // Internal chaining for collisions. - SPInt NextInChain; + intptr_t NextInChain; C Value; HashsetEntry() : NextInChain(-2) { } HashsetEntry(const HashsetEntry& e) : NextInChain(e.NextInChain), Value(e.Value) { } - HashsetEntry(const C& key, SPInt next) + HashsetEntry(const C& key, intptr_t next) : NextInChain(next), Value(key) { } bool IsEmpty() const { return NextInChain == -2; } @@ -131,8 +132,8 @@ public: // Cached hash value access - can be optimized bu storing hash locally. // Mask value only needs to be used if SetCachedHash is not implemented. - UPInt GetCachedHash(UPInt maskValue) const { return HashF()(Value) & maskValue; } - void SetCachedHash(UPInt) {} + size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; } + void SetCachedHash(size_t) {} void Clear() { @@ -151,15 +152,15 @@ class HashsetCachedEntry { public: // Internal chaining for collisions. - SPInt NextInChain; - UPInt HashValue; + 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, SPInt next) + HashsetCachedEntry(const C& key, intptr_t next) : NextInChain(next), Value(key) { } bool IsEmpty() const { return NextInChain == -2; } @@ -167,8 +168,8 @@ public: // Cached hash value access - can be optimized bu storing hash locally. // Mask value only needs to be used if SetCachedHash is not implemented. - UPInt GetCachedHash(UPInt maskValue) const { OVR_UNUSED(maskValue); return HashValue; } - void SetCachedHash(UPInt hashValue) { HashValue = hashValue; } + size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; } + void SetCachedHash(size_t hashValue) { HashValue = hashValue; } void Clear() { @@ -210,7 +211,7 @@ public: if (pTable) { // Delete the entries. - for (UPInt i = 0, n = pTable->SizeMask; i <= n; i++) + for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) { Entry* e = &E(i); if (!e->IsEmpty()) @@ -244,7 +245,7 @@ public: if (pTable) { // Delete the entries. - for (UPInt i = 0, n = pTable->SizeMask; i <= n; i++) + for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) { Entry* e = &E(i); if (!e->IsEmpty()) @@ -269,8 +270,8 @@ public: template void Set(const CRef& key) { - UPInt hashValue = HashF()(key); - SPInt index = (SPInt)-1; + size_t hashValue = HashF()(key); + intptr_t index = (intptr_t)-1; if (pTable != NULL) index = findIndexCore(key, hashValue & pTable->SizeMask); @@ -289,7 +290,7 @@ public: template inline void Add(const CRef& key) { - UPInt hashValue = HashF()(key); + size_t hashValue = HashF()(key); add(key, hashValue); } @@ -300,20 +301,20 @@ public: if (pTable == NULL) return; - UPInt hashValue = AltHashF()(key); - SPInt index = hashValue & pTable->SizeMask; + 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) != (UPInt)index)) + if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (size_t)index)) return; // Save index - SPInt naturalIndex = index; - SPInt prevIndex = -1; + intptr_t naturalIndex = index; + intptr_t prevIndex = -1; - while ((e->GetCachedHash(pTable->SizeMask) != (UPInt)naturalIndex) || !(e->Value == key)) + while ((e->GetCachedHash(pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) { // Keep looking through the chain. prevIndex = index; @@ -361,7 +362,7 @@ public: template C* Get(const K& key) { - SPInt index = findIndex(key); + intptr_t index = findIndex(key); if (index >= 0) return &E(index).Value; return 0; @@ -370,7 +371,7 @@ public: template const C* Get(const K& key) const { - SPInt index = findIndex(key); + intptr_t index = findIndex(key); if (index >= 0) return &E(index).Value; return 0; @@ -380,7 +381,7 @@ public: template const C* GetAlt(const K& key) const { - SPInt index = findIndexAlt(key); + intptr_t index = findIndexAlt(key); if (index >= 0) return &E(index).Value; return 0; @@ -389,7 +390,7 @@ public: template C* GetAlt(const K& key) { - SPInt index = findIndexAlt(key); + intptr_t index = findIndexAlt(key); if (index >= 0) return &E(index).Value; return 0; @@ -398,7 +399,7 @@ public: template bool GetAlt(const K& key, C* pval) const { - SPInt index = findIndexAlt(key); + intptr_t index = findIndexAlt(key); if (index >= 0) { if (pval) @@ -409,10 +410,11 @@ public: } - UPInt GetSize() const + size_t GetSize() const { - return pTable == NULL ? 0 : (UPInt)pTable->EntryCount; + 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 @@ -432,7 +434,7 @@ public: } // Hint the bucket count to >= n. - void Resize(UPInt n) + void Resize(size_t n) { // Not really sure what this means in relation to // STLport's hash_map... they say they "increase the @@ -446,9 +448,9 @@ public: // 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(UPInt newSize) + void SetCapacity(size_t newSize) { - UPInt newRawSize = (newSize * 5) / 4; + size_t newRawSize = (newSize * 5) / 4; if (newRawSize <= GetSize()) return; setRawCapacity(newRawSize); @@ -466,23 +468,23 @@ public: { const C& operator * () const { - OVR_ASSERT(Index >= 0 && Index <= (SPInt)pHash->pTable->SizeMask); + OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); return pHash->E(Index).Value; } const C* operator -> () const { - OVR_ASSERT(Index >= 0 && Index <= (SPInt)pHash->pTable->SizeMask); + OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); return &pHash->E(Index).Value; } void operator ++ () { // Find next non-empty Entry. - if (Index <= (SPInt)pHash->pTable->SizeMask) + if (Index <= (intptr_t)pHash->pTable->SizeMask) { Index++; - while ((UPInt)Index <= pHash->pTable->SizeMask && + while ((size_t)Index <= pHash->pTable->SizeMask && pHash->E(Index).IsEmpty()) { Index++; @@ -512,7 +514,7 @@ public: { return (pHash == NULL) || (pHash->pTable == NULL) || - (Index > (SPInt)pHash->pTable->SizeMask); + (Index > (intptr_t)pHash->pTable->SizeMask); } ConstIterator() @@ -522,7 +524,7 @@ public: public: // Constructor was intentionally made public to allow create // iterator with arbitrary index. - ConstIterator(const SelfType* h, SPInt index) + ConstIterator(const SelfType* h, intptr_t index) : pHash(h), Index(index) { } @@ -530,7 +532,7 @@ public: { return pHash; } - SPInt GetIndex() const + intptr_t GetIndex() const { return Index; } @@ -539,7 +541,7 @@ public: friend class HashSetBase; const SelfType* pHash; - SPInt Index; + intptr_t Index; }; friend struct ConstIterator; @@ -551,7 +553,7 @@ public: // Allow non-const access to entries. C& operator*() const { - OVR_ASSERT(ConstIterator::Index >= 0 && ConstIterator::Index <= (SPInt)ConstIterator::pHash->pTable->SizeMask); + 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; } @@ -577,20 +579,20 @@ public: //Entry* ee = &phash->E(ConstIterator::Index); //const C& key = ee->Value; - UPInt hashValue = AltHashF()(key); - SPInt index = hashValue & phash->pTable->SizeMask; + 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) != (UPInt)index)) + if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (size_t)index)) return; // Save index - SPInt naturalIndex = index; - SPInt prevIndex = -1; + intptr_t naturalIndex = index; + intptr_t prevIndex = -1; - while ((e->GetCachedHash(phash->pTable->SizeMask) != (UPInt)naturalIndex) || !(e->Value == key)) + while ((e->GetCachedHash(phash->pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) { // Keep looking through the chain. prevIndex = index; @@ -600,7 +602,7 @@ public: e = &phash->E(index); } - if (index == (SPInt)ConstIterator::Index) + if (index == (intptr_t)ConstIterator::Index) { // Found it - our item is at index if (naturalIndex == index) @@ -633,7 +635,7 @@ public: private: friend class HashSetBase; - Iterator(SelfType* h, SPInt i0) + Iterator(SelfType* h, intptr_t i0) : ConstIterator(h, i0) { } }; @@ -646,7 +648,7 @@ public: return Iterator(NULL, 0); // Scan till we hit the First valid Entry. - UPInt i0 = 0; + size_t i0 = 0; while (i0 <= pTable->SizeMask && E(i0).IsEmpty()) { i0++; @@ -661,7 +663,7 @@ public: template Iterator Find(const K& key) { - SPInt index = findIndex(key); + intptr_t index = findIndex(key); if (index >= 0) return Iterator(this, index); return Iterator(NULL, 0); @@ -670,7 +672,7 @@ public: template Iterator FindAlt(const K& key) { - SPInt index = findIndexAlt(key); + intptr_t index = findIndexAlt(key); if (index >= 0) return Iterator(this, index); return Iterator(NULL, 0); @@ -685,33 +687,33 @@ public: private: // Find the index of the matching Entry. If no match, then return -1. template - SPInt findIndex(const K& key) const + intptr_t findIndex(const K& key) const { if (pTable == NULL) return -1; - UPInt hashValue = HashF()(key) & pTable->SizeMask; + size_t hashValue = HashF()(key) & pTable->SizeMask; return findIndexCore(key, hashValue); } template - SPInt findIndexAlt(const K& key) const + intptr_t findIndexAlt(const K& key) const { if (pTable == NULL) return -1; - UPInt hashValue = AltHashF()(key) & pTable->SizeMask; + 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 - SPInt findIndexCore(const K& key, UPInt hashValue) const + 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); - UPInt index = hashValue; + size_t index = hashValue; const Entry* e = &E(index); // If empty or occupied by a collider, not found. @@ -733,7 +735,7 @@ private: // Keep looking through the chain. index = e->NextInChain; - if (index == (UPInt)-1) + if (index == (size_t)-1) break; // end of chain e = &E(index); @@ -745,14 +747,14 @@ private: // Add a new value to the HashSet table, under the specified key. template - void add(const CRef& key, UPInt hashValue) + void add(const CRef& key, size_t hashValue) { CheckExpand(); hashValue &= pTable->SizeMask; pTable->EntryCount++; - SPInt index = hashValue; + intptr_t index = hashValue; Entry* naturalEntry = &(E(index)); if (naturalEntry->IsEmpty()) @@ -763,14 +765,14 @@ private: else { // Find a blank spot. - SPInt blankIndex = index; + intptr_t blankIndex = index; do { blankIndex = (blankIndex + 1) & pTable->SizeMask; } while(!E(blankIndex).IsEmpty()); Entry* blankEntry = &E(blankIndex); - if (naturalEntry->GetCachedHash(pTable->SizeMask) == (UPInt)index) + if (naturalEntry->GetCachedHash(pTable->SizeMask) == (size_t)index) { // Collision. Link into this chain. @@ -788,8 +790,8 @@ private: // Entry must be moved. // Find natural location of collided element (i.e. root of chain) - SPInt collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask); - OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (SPInt)pTable->SizeMask); + intptr_t collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask); + OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); for (;;) { Entry* e = &E(collidedIndex); @@ -801,7 +803,7 @@ private: break; } collidedIndex = e->NextInChain; - OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (SPInt)pTable->SizeMask); + OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); } // Put the new data in the natural Entry. @@ -815,13 +817,13 @@ private: } // Index access helpers. - Entry& E(UPInt index) + 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(UPInt index) const + const Entry& E(size_t index) const { OVR_ASSERT(index <= pTable->SizeMask); return *(((Entry*) (pTable + 1)) + index); @@ -832,7 +834,7 @@ private: // 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(UPInt newSize) + void setRawCapacity(size_t newSize) { if (newSize == 0) { @@ -850,8 +852,8 @@ private: { // Force newSize to be a power of two. int bits = Alg::UpperBit(newSize-1) + 1; // Chop( Log2f((float)(newSize-1)) + 1); - OVR_ASSERT((UPInt(1) << bits) >= newSize); - newSize = UPInt(1) << bits; + OVR_ASSERT((size_t(1) << bits) >= newSize); + newSize = size_t(1) << bits; } SelfType newHash; @@ -863,7 +865,7 @@ private: newHash.pTable->EntryCount = 0; newHash.pTable->SizeMask = newSize - 1; - UPInt i, n; + size_t i, n; // Mark all entries as empty. for (i = 0; i < newSize; i++) @@ -895,8 +897,8 @@ private: struct TableType { - UPInt EntryCount; - UPInt SizeMask; + size_t EntryCount; + size_t SizeMask; // Entry array follows this structure // in memory. }; @@ -939,7 +941,7 @@ public: } // Hint the bucket count to >= n. - void Resize(UPInt n) + void Resize(size_t n) { BaseType::SetCapacity(n); } @@ -947,7 +949,7 @@ public: // 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(UPInt newSize) + void SetCapacity(size_t newSize) { BaseType::SetCapacity(newSize); } @@ -1004,7 +1006,7 @@ struct HashNode NodeRef(const NodeRef& src) : pFirst(src.pFirst), pSecond(src.pSecond) { } // Enable computation of ghash_node_hashf. - inline UPInt GetHash() const { return HashF()(*pFirst); } + inline size_t GetHash() const { return HashF()(*pFirst); } // Necessary conversion to allow HashNode::operator == to work. operator const C& () const { return *pFirst; } }; @@ -1018,20 +1020,20 @@ struct HashNode bool operator == (const K& src) const { return (First == src); } template - static UPInt CalcHash(const K& data) { return HashF()(data); } - inline UPInt GetHash() const { return HashF()(First); } + 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 - UPInt operator()(const K& data) const { return data.GetHash(); } + size_t operator()(const K& data) const { return data.GetHash(); } }; struct NodeAltHashF { template - UPInt operator()(const K& data) const { return HashNode::CalcHash(data); } + size_t operator()(const K& data) const { return HashNode::CalcHash(data); } }; }; @@ -1050,22 +1052,22 @@ class HashsetNodeEntry { public: // Internal chaining for collisions. - SPInt NextInChain; + intptr_t NextInChain; C Value; HashsetNodeEntry() : NextInChain(-2) { } HashsetNodeEntry(const HashsetNodeEntry& e) : NextInChain(e.NextInChain), Value(e.Value) { } - HashsetNodeEntry(const C& key, SPInt next) + HashsetNodeEntry(const C& key, intptr_t next) : NextInChain(next), Value(key) { } - HashsetNodeEntry(const typename C::NodeRef& keyRef, SPInt next) + 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; } - UPInt GetCachedHash(UPInt maskValue) const { return HashF()(Value) & maskValue; } - void SetCachedHash(UPInt hashValue) { OVR_UNUSED(hashValue); } + size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; } + void SetCachedHash(size_t hashValue) { OVR_UNUSED(hashValue); } void Clear() { @@ -1084,23 +1086,23 @@ class HashsetCachedNodeEntry { public: // Internal chaining for collisions. - SPInt NextInChain; - UPInt HashValue; + 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, SPInt next) + HashsetCachedNodeEntry(const C& key, intptr_t next) : NextInChain(next), Value(key) { } - HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, SPInt next) + 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; } - UPInt GetCachedHash(UPInt maskValue) const { OVR_UNUSED(maskValue); return HashValue; } - void SetCachedHash(UPInt hashValue) { HashValue = hashValue; } + size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; } + void SetCachedHash(size_t hashValue) { HashValue = hashValue; } void Clear() { @@ -1227,9 +1229,10 @@ public: } // Sizing methods - delegate to Hash. - inline UPInt GetSize() const { return mHash.GetSize(); } - inline void Resize(UPInt n) { mHash.Resize(n); } - inline void SetCapacity(UPInt newSize) { mHash.SetCapacity(newSize); } + 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; diff --git a/LibOVR/Src/Kernel/OVR_KeyCodes.h b/LibOVR/Src/Kernel/OVR_KeyCodes.h index b5c5930..8ecdc8b 100644 --- a/LibOVR/Src/Kernel/OVR_KeyCodes.h +++ b/LibOVR/Src/Kernel/OVR_KeyCodes.h @@ -1,20 +1,20 @@ /************************************************************************************ -PublicHeader: OVR.h +PublicHeader: OVR_Kernel.h Filename : OVR_KeyCodes.h Content : Common keyboard constants Created : September 19, 2012 -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, diff --git a/LibOVR/Src/Kernel/OVR_List.h b/LibOVR/Src/Kernel/OVR_List.h index 6b49f37..7e90af3 100644 --- a/LibOVR/Src/Kernel/OVR_List.h +++ b/LibOVR/Src/Kernel/OVR_List.h @@ -6,16 +6,16 @@ Content : Template implementation for doubly-connected linked List Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -55,6 +55,12 @@ struct ListNode void* pVoidNext; }; + ListNode() + { + pPrev = NULL; + pNext = NULL; + } + void RemoveNode() { pPrev->pNext = pNext; diff --git a/LibOVR/Src/Kernel/OVR_Lockless.cpp b/LibOVR/Src/Kernel/OVR_Lockless.cpp index 0f25805..6a5ec6b 100644 --- a/LibOVR/Src/Kernel/OVR_Lockless.cpp +++ b/LibOVR/Src/Kernel/OVR_Lockless.cpp @@ -1,21 +1,20 @@ /************************************************************************************ -PublicHeader: OVR.h Filename : OVR_Lockless.cpp Content : Test logic for lock-less classes Created : December 27, 2013 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -33,13 +32,12 @@ limitations under the License. #include "OVR_Timer.h" #include "OVR_Log.h" - namespace OVR { namespace LocklessTest { const int TestIterations = 10000000; -// Use volatile dummys to force compiler to do spinning. +// Use volatile dummies to force compiler to do spinning. volatile int Dummy1; int Unused1[32]; volatile int Dummy2; @@ -91,7 +89,7 @@ struct TestData volatile bool FirstItemWritten = false; -LocklessUpdater TestDataUpdater; +LocklessUpdater TestDataUpdater; // Use this lock to verify that testing algorithm is otherwise correct... Lock TestLock; @@ -108,7 +106,6 @@ class Consumer : public Thread { LogText("LocklessTest::Consumer::Run started.\n"); - while (!FirstItemWritten) { // spin until producer wrote first value... @@ -216,13 +213,10 @@ void StartLocklessTest() producerThread->Start(); consumerThread->Start(); - /* while (!producerThread->IsFinished() && consumerThread->IsFinished()) { Thread::MSleep(500); - } */ - - // TBD: Cleanup + } } diff --git a/LibOVR/Src/Kernel/OVR_Lockless.h b/LibOVR/Src/Kernel/OVR_Lockless.h index a12f824..4d5b87e 100644 --- a/LibOVR/Src/Kernel/OVR_Lockless.h +++ b/LibOVR/Src/Kernel/OVR_Lockless.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -42,14 +42,24 @@ namespace OVR { // 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 +template class LocklessUpdater { public: - LocklessUpdater() : UpdateBegin( 0 ), UpdateEnd( 0 ) {} + LocklessUpdater() : UpdateBegin( 0 ), UpdateEnd( 0 ) + { + OVR_COMPILER_ASSERT(sizeof(T) <= sizeof(SlotType)); + } - T GetState() const + T GetState() const { // Copy the state out, then retry with the alternate slot // if we determine that our copy may have been partially @@ -61,9 +71,9 @@ public: { // 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.ExchangeAdd_Sync(0); + end = UpdateEnd.Load_Acquire(); state = Slots[ end & 1 ]; - begin = UpdateBegin.ExchangeAdd_Sync(0); + begin = UpdateBegin.Load_Acquire(); if ( begin == end ) { break; } @@ -71,7 +81,7 @@ public: // 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.ExchangeAdd_NoSync(0); + final = UpdateBegin.Load_Acquire(); if ( final == begin ) { break; } @@ -82,7 +92,7 @@ public: return state; } - void SetState( T 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. @@ -90,9 +100,9 @@ public: UpdateEnd.ExchangeAdd_Sync(1); } - mutable AtomicInt UpdateBegin; - mutable AtomicInt UpdateEnd; - T Slots[2]; + AtomicInt UpdateBegin; + AtomicInt UpdateEnd; + SlotType Slots[2]; }; diff --git a/LibOVR/Src/Kernel/OVR_Log.cpp b/LibOVR/Src/Kernel/OVR_Log.cpp index d5f8a68..2631879 100644 --- a/LibOVR/Src/Kernel/OVR_Log.cpp +++ b/LibOVR/Src/Kernel/OVR_Log.cpp @@ -5,16 +5,16 @@ Content : Logging support Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -28,23 +28,83 @@ limitations under the License. #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_WIN32) +#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; + // 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) { @@ -52,6 +112,49 @@ Log::~Log() 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) { @@ -62,9 +165,32 @@ void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list ar return; #endif - char buffer[MaxLogBufferMessageSize]; - FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); - DefaultLogOutput(buffer, IsDebugMessage(messageType)); + 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, ...) @@ -76,35 +202,60 @@ void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...) } -void Log::FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType, +// 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) -{ - bool addNewline = true; +{ + 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: "); break; - case Log_Debug: OVR_strcpy(buffer, bufferSize, "Debug: "); break; - case Log_Assert: OVR_strcpy(buffer, bufferSize, "Assert: "); break; - case Log_Text: buffer[0] = 0; addNewline = false; break; - case Log_DebugText: buffer[0] = 0; addNewline = false; break; - default: - buffer[0] = 0; - addNewline = false; - break; + 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; } - UPInt prefixLength = OVR_strlen(buffer); - char *buffer2 = buffer + prefixLength; - OVR_vsprintf(buffer2, bufferSize - prefixLength, fmt, argList); + char* buffer2 = buffer + prefixLength; + size_t size2 = bufferSize - (size_t)prefixLength; + int messageLength = OVR_vsnprintf(buffer2, size2, fmt, argList); if (addNewline) - OVR_strcat(buffer, bufferSize, "\n"); -} + { + 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, bool debug) +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. @@ -116,12 +267,15 @@ void Log::DefaultLogOutput(const char* formattedText, bool debug) { ::OutputDebugStringA(formattedText); } - else - { - fputs(formattedText, stdout); - } + + 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 @@ -129,6 +283,24 @@ void Log::DefaultLogOutput(const char* formattedText, bool debug) #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); } @@ -161,16 +333,37 @@ Log* Log::GetDefaultLog() //----------------------------------------------------------------------------------- // ***** 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 argList; va_start(argList, fmt); \ - OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList); \ - va_end(argList); \ + 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) @@ -181,4 +374,59 @@ 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 index 4d9acc1..5982395 100644 --- a/LibOVR/Src/Kernel/OVR_Log.h +++ b/LibOVR/Src/Kernel/OVR_Log.h @@ -6,16 +6,16 @@ Content : Logging support Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -29,6 +29,8 @@ limitations under the License. #define OVR_Log_h #include "OVR_Types.h" +#include "../Kernel/OVR_Delegates.h" +#include "../Kernel//OVR_Observer.h" #include namespace OVR { @@ -92,7 +94,6 @@ enum LogMessageType # define OVR_LOG_VAARG_ATTRIBUTE(a,b) #endif - //----------------------------------------------------------------------------------- // ***** Log @@ -102,21 +103,34 @@ enum LogMessageType class Log { - friend class System; + friend class System; + +#ifdef OVR_OS_WIN32 + void* hEventSource; +#endif + public: - Log(unsigned logMask = LogMask_Debug) : LoggingMask(logMask) { } + Log(unsigned logMask = LogMask_Debug); virtual ~Log(); - // Log formating buffer size used by default LogMessageVarg. Longer strings are truncated. + 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); @@ -124,14 +138,16 @@ public: // 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. - static void FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType, + // 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. - static void DefaultLogOutput(const char* textBuffer, bool debug); + 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) @@ -184,18 +200,25 @@ void LogError(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_LOG_DEBUG(("Value %d", 2)). + // 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) - #define OVR_ASSERT_LOG(c, args) do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } 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_ASSERT_LOG(c, args) ((void)0) + #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 diff --git a/LibOVR/Src/Kernel/OVR_Math.cpp b/LibOVR/Src/Kernel/OVR_Math.cpp index 396d3ff..52977ed 100644 --- a/LibOVR/Src/Kernel/OVR_Math.cpp +++ b/LibOVR/Src/Kernel/OVR_Math.cpp @@ -5,16 +5,16 @@ 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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -34,45 +34,13 @@ namespace OVR { //------------------------------------------------------------------------------------- -// ***** Math - - -// Single-precision Math constants class. -const float Math::Pi = 3.1415926f; -const float Math::TwoPi = 3.1415926f * 2; -const float Math::PiOver2 = 3.1415926f / 2.0f; -const float Math::PiOver4 = 3.1415926f / 4.0f; -const float Math::E = 2.7182818f; - -const float Math::MaxValue = FLT_MAX; -const float Math::MinPositiveValue = FLT_MIN; - -const float Math::RadToDegreeFactor = 360.0f / Math::TwoPi; -const float Math::DegreeToRadFactor = Math::TwoPi / 360.0f; - -const float Math::Tolerance = 0.00001f; -const float Math::SingularityRadius = 0.0000001f; // Use for Gimbal lock numerical problems - -// Double-precision Math constants class. -const double Math::Pi = 3.14159265358979; -const double Math::TwoPi = 3.14159265358979 * 2; -const double Math::PiOver2 = 3.14159265358979 / 2.0; -const double Math::PiOver4 = 3.14159265358979 / 4.0; -const double Math::E = 2.71828182845905; - -const double Math::MaxValue = DBL_MAX; -const double Math::MinPositiveValue = DBL_MIN; - -const double Math::RadToDegreeFactor = 360.0 / Math::TwoPi; -const double Math::DegreeToRadFactor = Math::TwoPi / 360.0; - -const double Math::Tolerance = 0.00001; -const double Math::SingularityRadius = 0.000000000001; // Use for Gimbal lock numerical problems - +// ***** Constants +template<> +const Vector3 Vector3::ZERO = Vector3(); -//------------------------------------------------------------------------------------- -// ***** Matrix4 +template<> +const Vector3 Vector3::ZERO = Vector3(); template<> const Matrix4 Matrix4::IdentityValue = Matrix4(1.0f, 0.0f, 0.0f, 0.0f, @@ -87,5 +55,4 @@ const Matrix4 Matrix4::IdentityValue = Matrix4(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 index 4aa42b0..c187cda 100644 --- a/LibOVR/Src/Kernel/OVR_Math.h +++ b/LibOVR/Src/Kernel/OVR_Math.h @@ -1,22 +1,22 @@ /************************************************************************************ -PublicHeader: OVR.h +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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -125,7 +125,7 @@ template class Vector2; template class Vector3; template class Matrix3; template class Matrix4; -template class Transform; +template class Pose; template class PoseState; // CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class. @@ -134,7 +134,7 @@ struct CompatibleTypes { // Declaration here seems necessary for MSVC; specializations are // used instead. - typedef float Type; + typedef struct {} Type; }; // Specializations providing CompatibleTypes::Type value. @@ -150,11 +150,8 @@ 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 ovrPoseStatef Type; }; - -template<> struct CompatibleTypes > { typedef ovrPosed Type; }; -template<> struct CompatibleTypes > { typedef ovrPoseStated Type; }; +template<> struct CompatibleTypes > { typedef ovrPosef Type; }; +template<> struct CompatibleTypes > { typedef ovrPosed Type; }; //------------------------------------------------------------------------------------// // ***** Math @@ -170,28 +167,40 @@ public: 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: - static const float Pi; - static const float TwoPi; - static const float PiOver2; - static const float PiOver4; - static const float E; - - static const float MaxValue; // Largest positive float Value - static const float MinPositiveValue; // Smallest possible positive value - - static const float RadToDegreeFactor; - static const float DegreeToRadFactor; - - static const float Tolerance; // 0.00001f; - static const float SingularityRadius; // 0.0000001f for Gimbal lock numerical problems - - // Used to support direct conversions in template classes. - typedef double OtherFloatType; + typedef double OtherFloatType; }; // Double-precision Math constants class. @@ -199,21 +208,6 @@ template<> class Math { public: - static const double Pi; - static const double TwoPi; - static const double PiOver2; - static const double PiOver4; - static const double E; - - static const double MaxValue; // Largest positive double Value - static const double MinPositiveValue; // Smallest possible positive value - - static const double RadToDegreeFactor; - static const double DegreeToRadFactor; - - static const double Tolerance; // 0.00001; - static const double SingularityRadius; // 0.000000000001 for Gimbal lock numerical problems - typedef float OtherFloatType; }; @@ -223,23 +217,23 @@ typedef Math Mathd; // Conversion functions between degrees and radians template -T RadToDegree(T rads) { return rads * Math::RadToDegreeFactor; } +T RadToDegree(T rads) { return rads * ((T)MATH_DOUBLE_RADTODEGREEFACTOR); } template -T DegreeToRad(T rads) { return rads * Math::DegreeToRadFactor; } +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 Math::Pi; + 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 Math::PiOver2; - else if (val < T(-1)) return Math::PiOver2 * T(3); + 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); }; @@ -277,7 +271,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Vector2) == sizeof(CompatibleType)); + static_assert(sizeof(Vector2) == sizeof(CompatibleType), "sizeof(Vector2) failure"); return reinterpret_cast(*this); } @@ -307,12 +301,24 @@ public: (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 = Mathf::Tolerance) + bool Compare(const Vector2&b, T tolerance = ((T)MATH_DOUBLE_TOLERANCE)) { return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance); } - // Entrywise product of two vectors + // 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);} @@ -341,13 +347,13 @@ public: T Length() const { return sqrt(LengthSq()); } // Returns squared distance between two points represented by vectors. - T DistanceSq(Vector2& b) const { return (*this - b).LengthSq(); } + T DistanceSq(const Vector2& b) const { return (*this - b).LengthSq(); } // Returns distance between two points represented by vectors. - T Distance(Vector2& b) const { return (*this - b).Length(); } + 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; } + bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } // Normalize, convention vector length to 1. void Normalize() @@ -383,6 +389,10 @@ 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} @@ -396,12 +406,16 @@ 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; @@ -410,7 +424,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Vector3) == sizeof(CompatibleType)); + static_assert(sizeof(Vector3) == sizeof(CompatibleType), "sizeof(Vector3) failure"); return reinterpret_cast(*this); } @@ -447,7 +461,7 @@ public: } // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool Compare(const Vector3&b, T tolerance = Mathf::Tolerance) + bool Compare(const Vector3&b, T tolerance = ((T)MATH_DOUBLE_TOLERANCE)) { return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance) && @@ -515,7 +529,7 @@ public: T Distance(Vector3 const& b) const { return (*this - b).Length(); } // Determine if this a unit vector. - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math::Tolerance; } + bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } // Normalize, convention vector length to 1. void Normalize() @@ -550,27 +564,208 @@ public: Vector3 ProjectToPlane(const Vector3& normal) const { return *this - this->ProjectTo(normal); } }; - typedef Vector3 Vector3f; typedef Vector3 Vector3d; -typedef Vector3 Vector3i; +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; -// JDC: this was defined in Render_Device.h, I moved it here, but it -// needs to be fleshed out like the other Vector types. +//------------------------------------------------------------------------------------- +// ***** Vector4<> - 4D vector of {x, y, z, w} + // -// A vector with a dummy w component for alignment in uniform buffers (and for float colors). -// The w component is not used in any calculations. +// 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; + -struct Vector4f : public Vector3f +//------------------------------------------------------------------------------------- +// ***** Bounds3 + +// Bounds class used to describe a 3D axis aligned bounding box. + +template +class Bounds3 { - float w; +public: + Vector3 b[2]; + + Bounds3() + { + } + + Bounds3( const Vector3 & mins, const Vector3 & maxs ) +{ + b[0] = mins; + b[1] = maxs; + } - Vector4f() : w(1) {} - Vector4f(const Vector3f& v) : Vector3f(v), w(1) {} - Vector4f(float r, float g, float b, float a) : Vector3f(r,g,b), w(a) {} + 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; //------------------------------------------------------------------------------------- @@ -598,7 +793,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Size) == sizeof(CompatibleType)); + static_assert(sizeof(Size) == sizeof(CompatibleType), "sizeof(Size) failure"); return reinterpret_cast(*this); } @@ -626,7 +821,6 @@ public: 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); } @@ -663,7 +857,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Rect) == sizeof(CompatibleType)); + static_assert(sizeof(Rect) == sizeof(CompatibleType), "sizeof(Rect) failure"); return reinterpret_cast(*this); } @@ -702,12 +896,14 @@ public: 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 typename CompatibleTypes >::Type& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } + Quat(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } - operator typename CompatibleTypes >::Type () const + operator CompatibleType () const { - typename CompatibleTypes >::Type result; + CompatibleType result; result.x = x; result.y = y; result.z = z; @@ -753,12 +949,12 @@ public: // Compute axis and angle from quaternion void GetAxisAngle(Vector3* axis, T* angle) const { - if ( x*x + y*y + z*z > Math::Tolerance * Math::Tolerance ) { + 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 > Math::Pi) // Reduce the magnitude of the angle, if necessary + if (*angle > ((T)MATH_DOUBLE_PI)) // Reduce the magnitude of the angle, if necessary { - *angle = Math::TwoPi - *angle; + *angle = ((T)MATH_DOUBLE_TWOPI) - *angle; *axis = *axis * (-1); } } @@ -903,7 +1099,7 @@ public: } // Normalize - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math::Tolerance; } + bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } void Normalize() { @@ -973,10 +1169,10 @@ public: // 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 + template + void GetEulerAngles(T *a, T *b, T *c) const { - OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3)); + 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 @@ -992,17 +1188,17 @@ public: T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]); - if (s2 < T(-1) + Math::SingularityRadius) + if (s2 < T(-1) + ((T)MATH_DOUBLE_SINGULARITYRADIUS)) { // South pole singularity *a = T(0); - *b = -S*D*Math::PiOver2; + *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) - Math::SingularityRadius) + else if (s2 > T(1) - ((T)MATH_DOUBLE_SINGULARITYRADIUS)) { // North pole singularity *a = T(0); - *b = S*D*Math::PiOver2; + *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); } @@ -1025,7 +1221,6 @@ public: 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. @@ -1037,7 +1232,7 @@ public: template void GetEulerAnglesABA(T *a, T *b, T *c) const { - OVR_COMPILER_ASSERT(A1 != A2); + static_assert(A1 != A2, "A1 != A2"); T Q[3] = {x, y, z}; // Quaternion components @@ -1059,7 +1254,7 @@ public: if (c2 < T(-1) + Math::SingularityRadius) { // South pole singularity *a = T(0); - *b = S*D*Math::Pi; + *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); } @@ -1085,31 +1280,33 @@ public: 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 Transform +class Pose { public: + typedef typename CompatibleTypes >::Type CompatibleType; - typedef typename CompatibleTypes >::Type CompatibleType; - - Transform() { } - Transform(const Quat& orientation, const Vector3& pos) + Pose() { } + Pose(const Quat& orientation, const Vector3& pos) : Rotation(orientation), Translation(pos) { } - Transform(const Transform& s) + Pose(const Pose& s) : Rotation(s.Rotation), Translation(s.Translation) { } - Transform(const CompatibleType& s) + Pose(const CompatibleType& s) : Rotation(s.Orientation), Translation(s.Position) { } - explicit Transform(const Transform::OtherFloatType> &s) + explicit Pose(const Pose::OtherFloatType> &s) : Rotation(s.Rotation), Translation(s.Translation) { } - operator typename CompatibleTypes >::Type () const + operator typename CompatibleTypes >::Type () const { - typename CompatibleTypes >::Type result; + typename CompatibleTypes >::Type result; result.Orientation = Rotation; result.Position = Translation; return result; @@ -1117,6 +1314,21 @@ public: 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 { @@ -1133,32 +1345,24 @@ public: return Translate(Rotate(v)); } - Transform operator*(const Transform& other) const - { - return Transform(Rotation * other.Rotation, Apply(other.Translation)); - } - - PoseState operator*(const PoseState& poseState) const + Pose operator*(const Pose& other) const { - PoseState result; - result.Pose = (*this) * poseState.Pose; - result.LinearVelocity = this->Rotate(poseState.LinearVelocity); - result.LinearAcceleration = this->Rotate(poseState.LinearAcceleration); - result.AngularVelocity = this->Rotate(poseState.AngularVelocity); - result.AngularAcceleration = this->Rotate(poseState.AngularAcceleration); - return result; + return Pose(Rotation * other.Rotation, Apply(other.Translation)); } - Transform Inverted() const + Pose Inverted() const { Quat inv = Rotation.Inverted(); - return Transform(inv, inv.Rotate(-Translation)); + return Pose(inv, inv.Rotate(-Translation)); } }; -typedef Transform Transformf; -typedef Transform Transformd; +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 @@ -1241,7 +1445,7 @@ public: M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; } - explicit Matrix4(const Transform& p) + explicit Matrix4(const Pose& p) { Matrix4 result(p.Rotation); result.SetTranslation(p.Translation); @@ -1259,21 +1463,21 @@ public: // C-interop support. Matrix4(const typename CompatibleTypes >::Type& s) { - OVR_COMPILER_ASSERT(sizeof(s) == sizeof(Matrix4)); + 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_COMPILER_ASSERT(sizeof(result) == sizeof(Matrix4)); + static_assert(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)"); memcpy(result.M, M, sizeof(M)); return result; } - void ToString(char* dest, UPInt destsize) const + void ToString(char* dest, size_t destsize) const { - UPInt pos = 0; + 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]); @@ -1282,15 +1486,24 @@ public: 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; } @@ -1304,6 +1517,39 @@ public: 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; @@ -1404,9 +1650,18 @@ public: Vector3 Transform(const Vector3& v) const { - return Vector3(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3], - M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3], - M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]); + 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 @@ -1423,16 +1678,16 @@ public: } - T SubDet (const UPInt* rows, const UPInt* cols) const + 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(UPInt I, UPInt J) const + T Cofactor(size_t I, size_t J) const { - const UPInt indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}}; + 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]); } @@ -1488,9 +1743,9 @@ public: // 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) + void ToEulerAngles(T *a, T *b, T *c) const { - OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3)); + 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 @@ -1500,13 +1755,13 @@ public: if (pm < -1.0f + Math::SingularityRadius) { // South pole singularity *a = 0; - *b = -S*D*Math::PiOver2; + *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*Math::PiOver2; + *b = S*D*((T)MATH_DOUBLE_PIOVER2); *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] ); } else @@ -1526,9 +1781,9 @@ public: // 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) + void ToEulerAnglesABA(T *a, T *b, T *c) const { - OVR_COMPILER_ASSERT(A1 != A2); + static_assert(A1 != A2, "A1 != A2"); // Determine the axis that was not supplied int m = 3 - A1 - A2; @@ -1541,7 +1796,7 @@ public: if (c2 < -1 + Math::SingularityRadius) { // South pole singularity *a = 0; - *b = S*D*Math::Pi; + *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) @@ -1781,19 +2036,20 @@ public: 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 / (zfar - znear); - m.M[3][2] = 1; + 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; + 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; } - // PerspectiveRH creates a left-handed perspective projection matrix that can be + // 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. @@ -1805,17 +2061,17 @@ public: Matrix4 m; T tanHalfFov = tan(yfov * 0.5f); - m.M[0][0] = 1.0 / (aspect * tanHalfFov); - m.M[1][1] = 1.0 / tanHalfFov; - m.M[2][2] = zfar / (znear - zfar); - // m.M[2][2] = zfar / (zfar - znear); - m.M[3][2] = -1.0; + 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.0; + 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 cooridnate input. + // This is the case even for RHS coordinate input. return m; } @@ -1916,7 +2172,7 @@ public: M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = 0; } - explicit Matrix3(const Transform& p) + explicit Matrix3(const Pose& p) { Matrix3 result(p.Rotation); result.SetTranslation(p.Translation); @@ -1934,21 +2190,21 @@ public: // C-interop support. Matrix3(const typename CompatibleTypes >::Type& s) { - OVR_COMPILER_ASSERT(sizeof(s) == sizeof(Matrix3)); + static_assert(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)"); memcpy(M, s.M, sizeof(M)); } - operator typename CompatibleTypes >::Type () const + operator const typename CompatibleTypes >::Type () const { typename CompatibleTypes >::Type result; - OVR_COMPILER_ASSERT(sizeof(result) == sizeof(Matrix3)); + static_assert(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)"); memcpy(result.M, M, sizeof(M)); return result; } - void ToString(char* dest, UPInt destsize) const + void ToString(char* dest, size_t destsize) const { - UPInt pos = 0; + 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]); @@ -2108,6 +2364,13 @@ public: 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, @@ -2128,7 +2391,7 @@ public: } - T SubDet (const UPInt* rows, const UPInt* cols) const + 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]]) @@ -2415,10 +2678,10 @@ public: Angle() : a(0) {} // Fix the range to be between -Pi and Pi - Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*Math::DegreeToRadFactor) { FixRange(); } + 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*Math::RadToDegreeFactor; } - void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*Math::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; } @@ -2440,7 +2703,7 @@ public: 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 <= Math::Pi) ? c : Math::TwoPi - c; } + T Distance(const Angle& b) { T c = fabs(a - b.a); return (c <= ((T)MATH_DOUBLE_PI)) ? c : ((T)MATH_DOUBLE_TWOPI) - c; } private: @@ -2450,23 +2713,23 @@ private: // Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side inline void FastFixRange() { - if (a < -Math::Pi) - a += Math::TwoPi; - else if (a > Math::Pi) - a -= Math::TwoPi; + 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 >= -Math::Pi && a <= Math::Pi) + if (a >= -((T)MATH_DOUBLE_PI) && a <= ((T)MATH_DOUBLE_PI)) return; - a = fmod(a,Math::TwoPi); - if (a < -Math::Pi) - a += Math::TwoPi; - else if (a > Math::Pi) - a -= Math::TwoPi; + 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); } }; @@ -2481,7 +2744,7 @@ typedef Angle Angled; // Consists of a normal vector and distance from the origin where the plane is located. template -class Plane : public RefCountBase > +class Plane { public: Vector3 N; @@ -2520,6 +2783,8 @@ public: }; typedef Plane Planef; +typedef Plane Planed; + } // Namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_Nullptr.h b/LibOVR/Src/Kernel/OVR_Nullptr.h new file mode 100644 index 0000000..a09f446 --- /dev/null +++ b/LibOVR/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/LibOVR/Src/Kernel/OVR_Observer.h b/LibOVR/Src/Kernel/OVR_Observer.h new file mode 100644 index 0000000..76b4be6 --- /dev/null +++ b/LibOVR/Src/Kernel/OVR_Observer.h @@ -0,0 +1,457 @@ +/************************************************************************************ + +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 index c6301ed..f761811 100644 --- a/LibOVR/Src/Kernel/OVR_RefCount.cpp +++ b/LibOVR/Src/Kernel/OVR_RefCount.cpp @@ -5,16 +5,16 @@ Content : Reference counting implementation Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, diff --git a/LibOVR/Src/Kernel/OVR_RefCount.h b/LibOVR/Src/Kernel/OVR_RefCount.h index 775e24c..33c6f37 100644 --- a/LibOVR/Src/Kernel/OVR_RefCount.h +++ b/LibOVR/Src/Kernel/OVR_RefCount.h @@ -6,16 +6,16 @@ Content : Reference counting implementation headers Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -413,6 +413,7 @@ public: 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; diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp b/LibOVR/Src/Kernel/OVR_SharedMemory.cpp new file mode 100644 index 0000000..1a6ccd9 --- /dev/null +++ b/LibOVR/Src/Kernel/OVR_SharedMemory.cpp @@ -0,0 +1,691 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..2cc8b04 --- /dev/null +++ b/LibOVR/Src/Kernel/OVR_SharedMemory.h @@ -0,0 +1,240 @@ +/************************************************************************************ + +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 index 6b5be18..fc5ad04 100644 --- a/LibOVR/Src/Kernel/OVR_Std.cpp +++ b/LibOVR/Src/Kernel/OVR_Std.cpp @@ -5,16 +5,16 @@ Content : Standard C function implementation Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -34,10 +34,58 @@ 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_WIN32) +#if defined(OVR_OS_MS) #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) return ::_stricmp(a, b); #else @@ -49,50 +97,50 @@ int OVR_CDECL OVR_stricmp(const char* a, const char* b) #endif } -int OVR_CDECL OVR_strnicmp(const char* a, const char* b, UPInt count) +int OVR_CDECL OVR_strnicmp(const char* a, const char* b, size_t count) { -#if defined(OVR_OS_WIN32) -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_strnicmp(a, b, count); -#else - return ::strnicmp(a, b, count); -#endif +#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, UPInt destsize, const wchar_t* src) +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_WIN32) +#elif defined(OVR_OS_MS) OVR_UNUSED(destsize); wcscpy(dest, src); return dest; #else - UPInt l = OVR_wcslen(src) + 1; // incl term null + 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, UPInt destsize, const wchar_t* src, UPInt count) +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 - UPInt srclen = OVR_wcslen(src); - UPInt l = Alg::Min(srclen, count); + 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) { - UPInt remLen = Alg::Min(destsize - l, (count - srclen)); + size_t remLen = Alg::Min(destsize - l, (count - srclen)); memset(&dest[l], 0, sizeof(wchar_t)*remLen); } else if (l < destsize) @@ -102,30 +150,30 @@ wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src } -wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src) +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_WIN32) +#elif defined(OVR_OS_MS) OVR_UNUSED(destsize); wcscat(dest, src); return dest; #else - UPInt dstlen = OVR_wcslen(dest); // do not incl term null - UPInt srclen = OVR_wcslen(src) + 1; // incl term null - UPInt copylen = (dstlen + srclen < destsize) ? srclen : destsize - dstlen; + 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 } -UPInt OVR_CDECL OVR_wcslen(const wchar_t* str) +size_t OVR_CDECL OVR_wcslen(const wchar_t* str) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) return wcslen(str); #else - UPInt i = 0; + size_t i = 0; while(str[i] != '\0') ++i; return i; @@ -134,7 +182,7 @@ UPInt OVR_CDECL OVR_wcslen(const wchar_t* str) int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) +#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) return wcscmp(a, b); #else // not supported, use custom implementation @@ -161,12 +209,12 @@ 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) { -#if defined(OVR_OS_WIN32) -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_wcsicmp(a, b); -#else - return ::wcsicmp(a, b); -#endif +#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; @@ -193,16 +241,19 @@ int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b) } // This function is not inline because of dependency on -double OVR_CDECL OVR_strtod(const char* string, char** tailptr) +double OVR_CDECL OVR_strtod(const char* str, char** tailptr) { -#if !defined(OVR_OS_ANDROID) +#if !defined(OVR_OS_ANDROID) // The Android C library doesn't have localeconv. const char s = *localeconv()->decimal_point; - if (s != '.') + 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), string); + OVR_strcpy(buffer, sizeof(buffer), str); + + // Ensure null-termination of string + buffer[sizeof(buffer)-1] = '\0'; for (char* c = buffer; *c != '\0'; ++c) { @@ -213,11 +264,21 @@ double OVR_CDECL OVR_strtod(const char* string, char** tailptr) } } - return strtod(buffer, tailptr); + 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(string, tailptr); + return strtod(str, tailptr); } @@ -254,7 +315,7 @@ double OVR_CDECL OVR_strtod(const char* string, char** tailptr) // if (isNull(i)) Offsets[i] = 0; // else // if (isFull(i)) Offsets[i] = 1; -// else Offsets[i] = UInt16(offsetCount++ * 16 + 256); +// else Offsets[i] = uint16_t(offsetCount++ * 16 + 256); // } // for(i = 0; i < 16; ++i) // { @@ -280,7 +341,7 @@ double OVR_CDECL OVR_strtod(const char* string, char** tailptr) //private: // bool isNull(unsigned n) const // { -// const UInt16* p = Bits[n]; +// const uint16_t* p = Bits[n]; // for(unsigned i = 0; i < 16; ++i) // if (p[i] != 0) return false; // return true; @@ -288,18 +349,18 @@ double OVR_CDECL OVR_strtod(const char* string, char** tailptr) // // bool isFull(unsigned n) const // { -// const UInt16* p = Bits[n]; +// const uint16_t* p = Bits[n]; // for(unsigned i = 0; i < 16; ++i) // if (p[i] != 0xFFFF) return false; // return true; // } // -// UInt16 Offsets[256]; -// UInt16 Bits[256][16]; +// uint16_t Offsets[256]; +// uint16_t Bits[256][16]; //}; -const UInt16 UnicodeAlnumBits[] = { +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, @@ -354,7 +415,7 @@ const UInt16 UnicodeAlnumBits[] = { 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 UnicodeAlphaBits[] = { +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, @@ -409,7 +470,7 @@ const UInt16 UnicodeAlphaBits[] = { 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 UnicodeDigitBits[] = { +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, @@ -441,7 +502,7 @@ const UInt16 UnicodeDigitBits[] = { 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 UnicodeSpaceBits[] = { +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, @@ -463,7 +524,7 @@ const UInt16 UnicodeSpaceBits[] = { 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 UnicodeXDigitBits[] = { +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, @@ -484,7 +545,7 @@ const UInt16 UnicodeXDigitBits[] = { 0, 1023, 126, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Uncomment if necessary -//const UInt16 UnicodeCntrlBits[] = { +//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, @@ -508,7 +569,7 @@ const UInt16 UnicodeXDigitBits[] = { // 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 UnicodeGraphBits[] = { +//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, @@ -564,7 +625,7 @@ const UInt16 UnicodeXDigitBits[] = { // 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 UnicodePrintBits[] = { +//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, @@ -620,7 +681,7 @@ const UInt16 UnicodeXDigitBits[] = { // 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 UnicodePunctBits[] = { +//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, @@ -658,7 +719,7 @@ const UInt16 UnicodeXDigitBits[] = { // 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 UnicodeLowerBits[] = { +//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, @@ -688,7 +749,7 @@ const UInt16 UnicodeXDigitBits[] = { // 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 UnicodeUpperBits[] = { +//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, @@ -734,7 +795,7 @@ const UInt16 UnicodeXDigitBits[] = { // they match AS3. -static const UInt16 UnicodeToUpperBits[] = { +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, @@ -763,7 +824,7 @@ static const UInt16 UnicodeToUpperBits[] = { 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 UnicodeToLowerBits[] = { +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, @@ -795,10 +856,10 @@ static const UInt16 UnicodeToLowerBits[] = { struct GUnicodePairType { - UInt16 Key, Value; + uint16_t Key, Value; }; -static inline bool CmpUnicodeKey(const GUnicodePairType& a, UInt16 key) +static inline bool CmpUnicodeKey(const GUnicodePairType& a, uint16_t key) { return a.Key < key; } @@ -1002,11 +1063,11 @@ int OVR_CDECL OVR_towupper(wchar_t charCode) { // To protect from memory overrun in case the character is not found // we use one extra fake element in the table {65536, 0}. - UPInt idx = Alg::LowerBoundSliced( + size_t idx = Alg::LowerBoundSliced( UnicodeToUpperTable, 0, sizeof(UnicodeToUpperTable) / sizeof(UnicodeToUpperTable[0]) - 1, - (UInt16)charCode, + (uint16_t)charCode, CmpUnicodeKey); return UnicodeToUpperTable[idx].Value; } @@ -1020,11 +1081,11 @@ int OVR_CDECL OVR_towlower(wchar_t charCode) { // To protect from memory overrun in case the character is not found // we use one extra fake element in the table {65536, 0}. - UPInt idx = Alg::LowerBoundSliced( + size_t idx = Alg::LowerBoundSliced( UnicodeToLowerTable, 0, sizeof(UnicodeToLowerTable) / sizeof(UnicodeToLowerTable[0]) - 1, - (UInt16)charCode, + (uint16_t)charCode, CmpUnicodeKey); return UnicodeToLowerTable[idx].Value; } diff --git a/LibOVR/Src/Kernel/OVR_Std.h b/LibOVR/Src/Kernel/OVR_Std.h index c11f853..6a14231 100644 --- a/LibOVR/Src/Kernel/OVR_Std.h +++ b/LibOVR/Src/Kernel/OVR_Std.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +PublicHeader: OVR_Kernel.h Filename : OVR_Std.h Content : Standard C function interface Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -35,7 +35,7 @@ limitations under the License. #include #include -#if !defined(OVR_OS_WINCE) && defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) #define OVR_MSVC_SAFESTRING #include #endif @@ -46,8 +46,10 @@ limitations under the License. namespace OVR { -#if defined(OVR_OS_WIN32) -inline char* OVR_CDECL OVR_itoa(int val, char *dest, UPInt destsize, int radix) +// 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); @@ -57,8 +59,8 @@ inline char* OVR_CDECL OVR_itoa(int val, char *dest, UPInt destsize, int radix) return itoa(val, dest, radix); #endif } -#else // OVR_OS_WIN32 -inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix) +#else // OVR_OS_MS +inline char* OVR_itoa(int val, char* dest, size_t len, int radix) { if (val == 0) { @@ -67,12 +69,15 @@ inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix) 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; - unsigned int i = 0; - unsigned int sign = 0; + size_t i = 0; + size_t sign = 0; if (val < 0) { @@ -124,7 +129,7 @@ inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix) dest[i++] = '-'; } - for (unsigned int j = 0; j < i / 2; ++j) + for (size_t j = 0; j < i / 2; ++j) { char tmp = dest[j]; dest[j] = dest[i - 1 - j]; @@ -140,39 +145,78 @@ inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix) // String functions -inline UPInt OVR_CDECL OVR_strlen(const char* str) +inline size_t OVR_CDECL OVR_strlen(const char* str) { return strlen(str); } -inline char* OVR_CDECL OVR_strcpy(char* dest, UPInt destsize, const char* src) +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 } -inline char* OVR_CDECL OVR_strncpy(char* dest, UPInt destsize, const char* src, UPInt count) + +// 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, UPInt destsize, const char* src) +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 @@ -195,16 +239,16 @@ inline char* OVR_CDECL OVR_strchr(char* str, char c) inline const char* OVR_strrchr(const char* str, char c) { - UPInt len = OVR_strlen(str); - for (UPInt i=len; i>0; i--) + 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 UByte* OVR_CDECL OVR_memrchr(const UByte* str, UPInt size, UByte c) +inline const uint8_t* OVR_CDECL OVR_memrchr(const uint8_t* str, size_t size, uint8_t c) { - for (SPInt i = (SPInt)size - 1; i >= 0; i--) + for (intptr_t i = (intptr_t)size - 1; i >= 0; i--) { if (str[i] == c) return str + i; @@ -214,8 +258,8 @@ inline const UByte* OVR_CDECL OVR_memrchr(const UByte* str, UPInt size, UByte c) inline char* OVR_CDECL OVR_strrchr(char* str, char c) { - UPInt len = OVR_strlen(str); - for (UPInt i=len; i>0; i--) + size_t len = OVR_strlen(str); + for (size_t i=len; i>0; i--) if (str[i]==c) return str+i; return 0; @@ -234,23 +278,23 @@ 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, UPInt size) +inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, size_t size) { return strncmp(ws1, ws2, size); } -inline UInt64 OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base) +inline uint64_t OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base) { -#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) +#if defined(OVR_CC_MSVC) return _strtoui64(nptr, endptr, base); #else return strtoull(nptr, endptr, base); #endif } -inline SInt64 OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) +inline int64_t OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) { -#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) +#if defined(OVR_CC_MSVC) return _strtoi64(nptr, endptr, base); #else return strtoll(nptr, endptr, base); @@ -258,30 +302,34 @@ inline SInt64 OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) } -inline SInt64 OVR_CDECL OVR_atoq(const char* string) +inline int64_t OVR_CDECL OVR_atoq(const char* string) { -#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) +#if defined(OVR_CC_MSVC) return _atoi64(string); #else return atoll(string); #endif } -inline UInt64 OVR_CDECL OVR_atouq(const char* string) +inline uint64_t OVR_CDECL OVR_atouq(const char* string) { return OVR_strtouq(string, NULL, 10); } -// Implemented in GStd.cpp in platform-specific manner. +// 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, UPInt count); +int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, size_t count); + -inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* format, ...) +// 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); - UPInt ret; + size_t ret; #if defined(OVR_CC_MSVC) #if defined(OVR_MSVC_SAFESTRING) ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); @@ -301,9 +349,16 @@ inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* forma return ret; } -inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * format, va_list argList) + +// 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) { - UPInt ret; + size_t ret; #if defined(OVR_CC_MSVC) #if defined(OVR_MSVC_SAFESTRING) dest[0] = '\0'; @@ -314,50 +369,119 @@ inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * for ret = destsize - 1; } else - ret = (UPInt)rv; + ret = (size_t)rv; #else OVR_UNUSED(destsize); int rv = _vsnprintf(dest, destsize - 1, format, argList); OVR_ASSERT(rv != -1); - ret = (UPInt)rv; + ret = (size_t)rv; dest[destsize-1] = 0; #endif #else + // FIXME: This should be a safer implementation OVR_UNUSED(destsize); - ret = (UPInt)vsprintf(dest, format, argList); + ret = (size_t)vsprintf(dest, format, argList); OVR_ASSERT(ret < destsize); #endif return ret; } -// Returns the number of characters in the formatted string. -inline UPInt OVR_CDECL OVR_vscprintf(const char * format, va_list argList) +// 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) { - UPInt ret; + int ret; #if defined(OVR_CC_MSVC) - ret = (UPInt) _vscprintf(format, argList); + ret = _vscprintf(format, argList); #else - ret = (UPInt) vsnprintf(NULL, 0, format, argList); + ret = vsnprintf(NULL, 0, format, argList); #endif return ret; } -wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src); -wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count); -wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src); -UPInt OVR_CDECL OVR_wcslen(const wchar_t* str); +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_WIN32) -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_wcsicoll(a, b); -#else - return ::wcsicoll(a, b); -#endif +#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); @@ -366,7 +490,7 @@ inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) +#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) return wcscoll(a, b); #else // not supported, use regular wcscmp @@ -376,7 +500,7 @@ inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) #ifndef OVR_NO_WCTYPE -inline int OVR_CDECL UnicodeCharIs(const UInt16* table, wchar_t charCode) +inline int OVR_CDECL UnicodeCharIs(const uint16_t* table, wchar_t charCode) { unsigned offset = table[charCode >> 8]; if (offset == 0) return 0; @@ -384,19 +508,19 @@ inline int OVR_CDECL UnicodeCharIs(const UInt16* table, wchar_t charCode) return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0; } -extern const UInt16 UnicodeAlnumBits[]; -extern const UInt16 UnicodeAlphaBits[]; -extern const UInt16 UnicodeDigitBits[]; -extern const UInt16 UnicodeSpaceBits[]; -extern const UInt16 UnicodeXDigitBits[]; +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 UnicodeCntrlBits[]; -//extern const UInt16 UnicodeGraphBits[]; -//extern const UInt16 UnicodeLowerBits[]; -//extern const UInt16 UnicodePrintBits[]; -//extern const UInt16 UnicodePunctBits[]; -//extern const UInt16 UnicodeUpperBits[]; +//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); } @@ -473,10 +597,10 @@ inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr) OVR_UNUSED(tailptr); char buffer[64]; char* tp = NULL; - UPInt max = OVR_wcslen(string); + size_t max = OVR_wcslen(string); if (max > 63) max = 63; unsigned char c = 0; - for (UPInt i=0; i < max; i++) + for (size_t i=0; i < max; i++) { c = (unsigned char)string[i]; buffer[i] = ((c) < 128 ? (char)c : '!'); @@ -494,10 +618,10 @@ inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int r OVR_UNUSED(tailptr); char buffer[64]; char* tp = NULL; - UPInt max = OVR_wcslen(string); + size_t max = OVR_wcslen(string); if (max > 63) max = 63; unsigned char c = 0; - for (UPInt i=0; i < max; i++) + for (size_t i=0; i < max; i++) { c = (unsigned char)string[i]; buffer[i] = ((c) < 128 ? (char)c : '!'); diff --git a/LibOVR/Src/Kernel/OVR_String.cpp b/LibOVR/Src/Kernel/OVR_String.cpp index 75b7c0e..a539992 100644 --- a/LibOVR/Src/Kernel/OVR_String.cpp +++ b/LibOVR/Src/Kernel/OVR_String.cpp @@ -6,16 +6,16 @@ Content : String UTF8 string implementation with copy-on-write semantics Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -36,7 +36,7 @@ limitations under the License. namespace OVR { -#define String_LengthIsSize (UPInt(1) << String::Flag_LengthIsSizeShift) +#define String_LengthIsSize (size_t(1) << String::Flag_LengthIsSizeShift) String::DataDesc String::NullData = {String_LengthIsSize, 1, {0} }; @@ -50,16 +50,16 @@ String::String() String::String(const char* pdata) { // Obtain length in bytes; it doesn't matter if _data is UTF8. - UPInt size = pdata ? OVR_strlen(pdata) : 0; + 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. - UPInt size1 = pdata1 ? OVR_strlen(pdata1) : 0; - UPInt size2 = pdata2 ? OVR_strlen(pdata2) : 0; - UPInt size3 = pdata3 ? OVR_strlen(pdata3) : 0; + 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); @@ -67,14 +67,14 @@ String::String(const char* pdata1, const char* pdata2, const char* pdata3) pData = pdataDesc; } -String::String(const char* pdata, UPInt size) +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, UPInt size) +String::String(const InitStruct& src, size_t size) { pData = AllocData(size, 0); src.InitString(GetData()->Data, size); @@ -101,7 +101,7 @@ String::String(const wchar_t* data) } -String::DataDesc* String::AllocData(UPInt size, UPInt lengthIsSize) +String::DataDesc* String::AllocData(size_t size, size_t lengthIsSize) { String::DataDesc* pdesc; @@ -120,17 +120,17 @@ String::DataDesc* String::AllocData(UPInt size, UPInt lengthIsSize) } -String::DataDesc* String::AllocDataCopy1(UPInt size, UPInt lengthIsSize, - const char* pdata, UPInt copySize) +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(UPInt size, UPInt lengthIsSize, - const char* pdata1, UPInt copySize1, - const char* pdata2, UPInt copySize2) +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); @@ -139,16 +139,16 @@ String::DataDesc* String::AllocDataCopy2(UPInt size, UPInt lengthIsSize, } -UPInt String::GetLength() const +size_t String::GetLength() const { // Optimize length accesses for non-UTF8 character strings. DataDesc* pdata = GetData(); - UPInt length, size = pdata->GetSize(); + size_t length, size = pdata->GetSize(); if (pdata->LengthIsSize()) return size; - length = (UPInt)UTF8Util::GetLength(pdata->Data, (UPInt)size); + length = (size_t)UTF8Util::GetLength(pdata->Data, (size_t)size); if (length == size) pdata->Size |= String_LengthIsSize; @@ -157,15 +157,15 @@ UPInt String::GetLength() const } -//static UInt32 String_CharSearch(const char* buf, ) +//static uint32_t String_CharSearch(const char* buf, ) -UInt32 String::GetCharAt(UPInt index) const +uint32_t String::GetCharAt(size_t index) const { - SPInt i = (SPInt) index; + intptr_t i = (intptr_t) index; DataDesc* pdata = GetData(); const char* buf = pdata->Data; - UInt32 c; + uint32_t c; if (pdata->LengthIsSize()) { @@ -178,13 +178,13 @@ UInt32 String::GetCharAt(UPInt index) const return c; } -UInt32 String::GetFirstCharAt(UPInt index, const char** offset) const +uint32_t String::GetFirstCharAt(size_t index, const char** offset) const { DataDesc* pdata = GetData(); - SPInt i = (SPInt) index; + intptr_t i = (intptr_t) index; const char* buf = pdata->Data; const char* end = buf + pdata->GetSize(); - UInt32 c; + uint32_t c; do { @@ -204,40 +204,40 @@ UInt32 String::GetFirstCharAt(UPInt index, const char** offset) const return c; } -UInt32 String::GetNextChar(const char** offset) const +uint32_t String::GetNextChar(const char** offset) const { return UTF8Util::DecodeNextChar(offset); } -void String::AppendChar(UInt32 ch) +void String::AppendChar(uint32_t ch) { DataDesc* pdata = GetData(); - UPInt size = pdata->GetSize(); + size_t size = pdata->GetSize(); char buff[8]; - SPInt encodeSize = 0; + 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 + (UPInt)encodeSize, 0, - pdata->Data, size, buff, (UPInt)encodeSize)); + SetData(AllocDataCopy2(size + (size_t)encodeSize, 0, + pdata->Data, size, buff, (size_t)encodeSize)); pdata->Release(); } -void String::AppendString(const wchar_t* pstr, SPInt len) +void String::AppendString(const wchar_t* pstr, intptr_t len) { if (!pstr) return; DataDesc* pdata = GetData(); - UPInt oldSize = pdata->GetSize(); - UPInt encodeSize = (UPInt)UTF8Util::GetEncodeStringSize(pstr, len); + size_t oldSize = pdata->GetSize(); + size_t encodeSize = (size_t)UTF8Util::GetEncodeStringSize(pstr, len); - DataDesc* pnewData = AllocDataCopy1(oldSize + (UPInt)encodeSize, 0, + DataDesc* pnewData = AllocDataCopy1(oldSize + (size_t)encodeSize, 0, pdata->Data, oldSize); UTF8Util::EncodeString(pnewData->Data + oldSize, pstr, len); @@ -246,22 +246,22 @@ void String::AppendString(const wchar_t* pstr, SPInt len) } -void String::AppendString(const char* putf8str, SPInt utf8StrSz) +void String::AppendString(const char* putf8str, intptr_t utf8StrSz) { if (!putf8str || !utf8StrSz) return; if (utf8StrSz == -1) - utf8StrSz = (SPInt)OVR_strlen(putf8str); + utf8StrSz = (intptr_t)OVR_strlen(putf8str); DataDesc* pdata = GetData(); - UPInt oldSize = pdata->GetSize(); + size_t oldSize = pdata->GetSize(); - SetData(AllocDataCopy2(oldSize + (UPInt)utf8StrSz, 0, - pdata->Data, oldSize, putf8str, (UPInt)utf8StrSz)); + SetData(AllocDataCopy2(oldSize + (size_t)utf8StrSz, 0, + pdata->Data, oldSize, putf8str, (size_t)utf8StrSz)); pdata->Release(); } -void String::AssignString(const InitStruct& src, UPInt size) +void String::AssignString(const InitStruct& src, size_t size) { DataDesc* poldData = GetData(); DataDesc* pnewData = AllocData(size, 0); @@ -270,7 +270,7 @@ void String::AssignString(const InitStruct& src, UPInt size) poldData->Release(); } -void String::AssignString(const char* putf8str, UPInt size) +void String::AssignString(const char* putf8str, size_t size) { DataDesc* poldData = GetData(); SetData(AllocDataCopy1(size, 0, putf8str, size)); @@ -284,8 +284,10 @@ void String::operator = (const char* pstr) void String::operator = (const wchar_t* pwstr) { + pwstr = pwstr ? pwstr : L""; + DataDesc* poldData = GetData(); - UPInt size = pwstr ? (UPInt)UTF8Util::GetEncodeStringSize(pwstr) : 0; + size_t size = (size_t)UTF8Util::GetEncodeStringSize(pwstr); DataDesc* pnewData = AllocData(size, 0); UTF8Util::EncodeString(pnewData->Data, pwstr); @@ -316,9 +318,9 @@ void String::operator += (const String& src) { DataDesc *pourData = GetData(), *psrcData = src.GetData(); - UPInt ourSize = pourData->GetSize(), + size_t ourSize = pourData->GetSize(), srcSize = psrcData->GetSize(); - UPInt lflag = pourData->GetLengthFlag() & psrcData->GetLengthFlag(); + size_t lflag = pourData->GetLengthFlag() & psrcData->GetLengthFlag(); SetData(AllocDataCopy2(ourSize + srcSize, lflag, pourData->Data, ourSize, psrcData->Data, srcSize)); @@ -340,12 +342,12 @@ String String::operator + (const String& src) const return tmp1; } -void String::Remove(UPInt posAt, SPInt removeLength) +void String::Remove(size_t posAt, intptr_t removeLength) { DataDesc* pdata = GetData(); - UPInt oldSize = pdata->GetSize(); + size_t oldSize = pdata->GetSize(); // Length indicates the number of characters to remove. - UPInt length = GetLength(); + size_t length = GetLength(); // If index is past the string, nothing to remove. if (posAt >= length) @@ -355,8 +357,8 @@ void String::Remove(UPInt posAt, SPInt removeLength) removeLength = length - posAt; // Get the byte position of the UTF8 char at position posAt. - SPInt bytePos = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize); - SPInt removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos); + 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, @@ -365,9 +367,9 @@ void String::Remove(UPInt posAt, SPInt removeLength) } -String String::Substring(UPInt start, UPInt end) const +String String::Substring(size_t start, size_t end) const { - UPInt length = GetLength(); + size_t length = GetLength(); if ((start >= length) || (start >= end)) return String(); @@ -378,9 +380,9 @@ String String::Substring(UPInt start, UPInt end) const return String(pdata->Data + start, end - start); // Get position of starting character. - SPInt byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize()); - SPInt byteSize = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart); - return String(pdata->Data + byteStart, (UPInt)byteSize); + 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() @@ -393,11 +395,11 @@ void String::Clear() String String::ToUpper() const { - UInt32 c; + uint32_t c; const char* psource = GetData()->Data; const char* pend = psource + GetData()->GetSize(); String str; - SPInt bufferOffset = 0; + intptr_t bufferOffset = 0; char buffer[512]; while(psource < pend) @@ -405,7 +407,7 @@ String String::ToUpper() const do { c = UTF8Util::DecodeNextChar_Advance0(&psource); UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c))); - } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8))); + } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8))); // Append string a piece at a time. str.AppendString(buffer, bufferOffset); @@ -417,11 +419,11 @@ String String::ToUpper() const String String::ToLower() const { - UInt32 c; + uint32_t c; const char* psource = GetData()->Data; const char* pend = psource + GetData()->GetSize(); String str; - SPInt bufferOffset = 0; + intptr_t bufferOffset = 0; char buffer[512]; while(psource < pend) @@ -429,7 +431,7 @@ String String::ToLower() const do { c = UTF8Util::DecodeNextChar_Advance0(&psource); UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c))); - } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8))); + } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8))); // Append string a piece at a time. str.AppendString(buffer, bufferOffset); @@ -441,13 +443,13 @@ String String::ToLower() const -String& String::Insert(const char* substr, UPInt posAt, SPInt strSize) +String& String::Insert(const char* substr, size_t posAt, intptr_t strSize) { DataDesc* poldData = GetData(); - UPInt oldSize = poldData->GetSize(); - UPInt insertSize = (strSize < 0) ? OVR_strlen(substr) : (UPInt)strSize; - UPInt byteIndex = (poldData->LengthIsSize()) ? - posAt : (UPInt)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize); + 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); @@ -461,27 +463,27 @@ String& String::Insert(const char* substr, UPInt posAt, SPInt strSize) } /* -String& String::Insert(const UInt32* substr, UPInt posAt, SPInt len) +String& String::Insert(const uint32_t* substr, size_t posAt, intptr_t len) { - for (SPInt i = 0; i < len; ++i) + for (intptr_t i = 0; i < len; ++i) { - UPInt charw = InsertCharAt(substr[i], posAt); + size_t charw = InsertCharAt(substr[i], posAt); posAt += charw; } return *this; } */ -UPInt String::InsertCharAt(UInt32 c, UPInt posAt) +size_t String::InsertCharAt(uint32_t c, size_t posAt) { - char buf[8]; - SPInt index = 0; + char buf[8]; + intptr_t index = 0; UTF8Util::EncodeChar(buf, &index, c); OVR_ASSERT(index >= 0); - buf[(UPInt)index] = 0; + buf[(size_t)index] = 0; Insert(buf, posAt, index); - return (UPInt)index; + return (size_t)index; } @@ -490,22 +492,22 @@ int String::CompareNoCase(const char* a, const char* b) return OVR_stricmp(a, b); } -int String::CompareNoCase(const char* a, const char* b, SPInt len) +int String::CompareNoCase(const char* a, const char* b, intptr_t len) { if (len) { - SPInt f,l; - SPInt slen = len; + intptr_t f,l; + intptr_t slen = len; const char *s = b; do { - f = (SPInt)OVR_tolower((int)(*(a++))); - l = (SPInt)OVR_tolower((int)(*(b++))); + 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 = (SPInt)slen; - l = (SPInt)OVR_strlen(s); + f = (intptr_t)slen; + l = (intptr_t)OVR_strlen(s); return int(f - l); } @@ -518,10 +520,10 @@ int String::CompareNoCase(const char* a, const char* b, SPInt len) // ***** Implement hash static functions // Hash function -UPInt String::BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed) +size_t String::BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed) { - const UByte* pdata = (const UByte*) pdataIn; - UPInt h = seed; + const uint8_t* pdata = (const uint8_t*) pdataIn; + size_t h = seed; while (size > 0) { size--; @@ -532,10 +534,10 @@ UPInt String::BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed) } // Hash function, case-insensitive -UPInt String::BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed) +size_t String::BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed) { - const UByte* pdata = (const UByte*) pdataIn; - UPInt h = seed; + const uint8_t* pdata = (const uint8_t*) pdataIn; + size_t h = seed; while (size > 0) { size--; @@ -560,7 +562,7 @@ StringBuffer::StringBuffer() { } -StringBuffer::StringBuffer(UPInt growSize) +StringBuffer::StringBuffer(size_t growSize) : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) { SetGrowSize(growSize); @@ -572,7 +574,7 @@ StringBuffer::StringBuffer(const char* data) AppendString(data); } -StringBuffer::StringBuffer(const char* data, UPInt dataSize) +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); @@ -601,32 +603,32 @@ StringBuffer::~StringBuffer() if (pData) OVR_FREE(pData); } -void StringBuffer::SetGrowSize(UPInt growSize) +void StringBuffer::SetGrowSize(size_t growSize) { if (growSize <= 16) GrowSize = 16; else { - UByte bits = Alg::UpperBit(UInt32(growSize-1)); - UPInt size = 1<= BufferSize) // >= because of trailing zero! (!AB) { @@ -637,7 +639,7 @@ void StringBuffer::Reserve(UPInt _size) pData = (char*)OVR_REALLOC(pData, BufferSize); } } -void StringBuffer::Resize(UPInt _size) +void StringBuffer::Resize(size_t _size) { Reserve(_size); LengthIsSize = false; @@ -660,71 +662,79 @@ void StringBuffer::Clear() */ } // Appends a character -void StringBuffer::AppendChar(UInt32 ch) +void StringBuffer::AppendChar(uint32_t ch) { char buff[8]; - UPInt origSize = GetSize(); + 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. - SPInt srcSize = 0; + intptr_t srcSize = 0; UTF8Util::EncodeChar(buff, &srcSize, ch); OVR_ASSERT(srcSize >= 0); - UPInt size = origSize + srcSize; + 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, SPInt len) +void StringBuffer::AppendString(const wchar_t* pstr, intptr_t len) { - if (!pstr) + if (!pstr || !len) return; - SPInt srcSize = UTF8Util::GetEncodeStringSize(pstr, len); - UPInt origSize = GetSize(); - UPInt size = srcSize + origSize; + 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, SPInt utf8StrSz) +void StringBuffer::AppendString(const char* putf8str, intptr_t utf8StrSz) { if (!putf8str || !utf8StrSz) return; if (utf8StrSz == -1) - utf8StrSz = (SPInt)OVR_strlen(putf8str); + utf8StrSz = (intptr_t)OVR_strlen(putf8str); - UPInt origSize = GetSize(); - UPInt size = utf8StrSz + origSize; + 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 : ""; - UPInt size = OVR_strlen(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""; - UPInt size = (UPInt)UTF8Util::GetEncodeStringSize(pstr); + 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) { - Resize(src.GetSize()); - memcpy(pData, src.ToCStr(), src.GetSize()); + 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) @@ -735,16 +745,17 @@ void StringBuffer::operator = (const StringBuffer& src) // Inserts substr at posAt -void StringBuffer::Insert(const char* substr, UPInt posAt, SPInt len) +void StringBuffer::Insert(const char* substr, size_t posAt, intptr_t len) { - UPInt oldSize = Size; - UPInt insertSize = (len < 0) ? OVR_strlen(substr) : (UPInt)len; - UPInt byteIndex = LengthIsSize ? posAt : - (UPInt)UTF8Util::GetByteIndex(posAt, pData, (SPInt)Size); + 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; @@ -753,16 +764,16 @@ void StringBuffer::Insert(const char* substr, UPInt posAt, SPInt len) } // Inserts character at posAt -UPInt StringBuffer::InsertCharAt(UInt32 c, UPInt posAt) +size_t StringBuffer::InsertCharAt(uint32_t c, size_t posAt) { char buf[8]; - SPInt len = 0; + intptr_t len = 0; UTF8Util::EncodeChar(buf, &len, c); OVR_ASSERT(len >= 0); - buf[(UPInt)len] = 0; + buf[(size_t)len] = 0; Insert(buf, posAt, len); - return (UPInt)len; + return (size_t)len; } } // OVR diff --git a/LibOVR/Src/Kernel/OVR_String.h b/LibOVR/Src/Kernel/OVR_String.h index 0866968..ecef940 100644 --- a/LibOVR/Src/Kernel/OVR_String.h +++ b/LibOVR/Src/Kernel/OVR_String.h @@ -1,22 +1,22 @@ /************************************************************************************ -PublicHeader: OVR.h +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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -59,7 +59,7 @@ protected: //Flag_GetLength = 0x7FFFFFFF, // This flag is set if GetLength() == GetSize() for a string. // Avoid extra scanning is Substring and indexing logic. - Flag_LengthIsSizeShift = (sizeof(UPInt)*8 - 1) + Flag_LengthIsSizeShift = (sizeof(size_t)*8 - 1) }; @@ -68,13 +68,13 @@ protected: { // 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. - UPInt Size; - volatile SInt32 RefCount; + size_t Size; + volatile int32_t RefCount; char Data[1]; void AddRef() { - AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); + 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. @@ -88,13 +88,13 @@ protected: // checking against 0 needs to made an atomic operation. void Release() { - if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) + if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) OVR_FREE(this); } - static UPInt GetLengthFlagBit() { return UPInt(1) << Flag_LengthIsSizeShift; } - UPInt GetSize() const { return Size & ~GetLengthFlagBit() ; } - UPInt GetLengthFlag() const { return Size & GetLengthFlagBit(); } + 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; } }; @@ -109,11 +109,11 @@ protected: union { DataDesc* pData; - UPInt HeapTypeBits; + size_t HeapTypeBits; }; typedef union { DataDesc* pData; - UPInt HeapTypeBits; + size_t HeapTypeBits; } DataDescUnion; inline HeapType GetHeapType() const { return (HeapType) (HeapTypeBits & HT_Mask); } @@ -122,7 +122,7 @@ protected: { DataDescUnion u; u.pData = pData; - u.HeapTypeBits = (u.HeapTypeBits & ~(UPInt)HT_Mask); + u.HeapTypeBits = (u.HeapTypeBits & ~(size_t)HT_Mask); return u.pData; } @@ -135,12 +135,12 @@ protected: } - DataDesc* AllocData(UPInt size, UPInt lengthIsSize); - DataDesc* AllocDataCopy1(UPInt size, UPInt lengthIsSize, - const char* pdata, UPInt copySize); - DataDesc* AllocDataCopy2(UPInt size, UPInt lengthIsSize, - const char* pdata1, UPInt copySize1, - const char* pdata2, UPInt copySize2); + 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 { }; @@ -152,7 +152,7 @@ public: struct InitStruct { virtual ~InitStruct() { } - virtual void InitString(char* pbuffer, UPInt size) const = 0; + virtual void InitString(char* pbuffer, size_t size) const = 0; }; @@ -160,10 +160,10 @@ public: String(); String(const char* data); String(const char* data1, const char* pdata2, const char* pdata3 = 0); - String(const char* data, UPInt buflen); + String(const char* data, size_t buflen); String(const String& src); String(const StringBuffer& src); - String(const InitStruct& src, UPInt size); + String(const InitStruct& src, size_t size); explicit String(const wchar_t* data); // Destructor (Captain Obvious guarantees!) @@ -186,68 +186,69 @@ public: const char* ToCStr() const { return GetData()->Data; } // Returns number of bytes - UPInt GetSize() const { return GetData()->GetSize() ; } + 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 - UPInt GetLength() const; + size_t GetLength() const; + int GetLengthI() const { return (int)GetLength(); } // Returns character at the specified index - UInt32 GetCharAt(UPInt index) const; - UInt32 GetFirstCharAt(UPInt index, const char** offset) const; - UInt32 GetNextChar(const char** offset) const; + 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 ch); + void AppendChar(uint32_t ch); // Append a string - void AppendString(const wchar_t* pstr, SPInt len = -1); - void AppendString(const char* putf8str, SPInt utf8StrSz = -1); + 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, UPInt size); + void AssignString(const InitStruct& src, size_t size); // Assigns string with known size. - void AssignString(const char* putf8str, UPInt size); + void AssignString(const char* putf8str, size_t size); // Resize the string to the new size -// void Resize(UPInt _size); +// void Resize(size_t _size); // Removes the character at posAt - void Remove(UPInt posAt, SPInt len = 1); + 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(UPInt start, UPInt end) const; + 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, UPInt posAt, SPInt len = -1); + String& Insert (const char* substr, size_t posAt, intptr_t len = -1); // Inserts character at posAt - UPInt InsertCharAt(UInt32 c, UPInt 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* substr, UPInt posAt, SPInt size = -1); +// String& Insert(const uint32_t* substr, size_t posAt, intptr_t size = -1); // Get Byte index of the character at position = index - UPInt GetByteIndex(UPInt index) const { return (UPInt)UTF8Util::GetByteIndex(index, GetData()->Data); } + 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, SPInt len); + static int OVR_STDCALL CompareNoCase(const char* a, const char* b, intptr_t len); // Hash function, case-insensitive - static UPInt OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed = 5381); + static size_t OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed = 5381); // Hash function, case-sensitive - static UPInt OVR_STDCALL BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed = 5381); + static size_t OVR_STDCALL BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed = 5381); // ***** File path parsing helper functions. @@ -343,10 +344,10 @@ public: // Accesses raw bytes const char& operator [] (int index) const { - OVR_ASSERT(index >= 0 && (UPInt)index < GetSize()); + OVR_ASSERT(index >= 0 && (size_t)index < GetSize()); return GetData()->Data[index]; } - const char& operator [] (UPInt index) const + const char& operator [] (size_t index) const { OVR_ASSERT(index < GetSize()); return GetData()->Data[index]; @@ -373,9 +374,9 @@ public: // Hash functor used for strings. struct HashFunctor { - UPInt operator()(const String& data) const + size_t operator()(const String& data) const { - UPInt size = data.GetSize(); + size_t size = data.GetSize(); return String::BernsteinHashFunction((const char*)data, size); } }; @@ -383,14 +384,14 @@ public: // lookup based on NoCaseKey. struct NoCaseHashFunctor { - UPInt operator()(const String& data) const + size_t operator()(const String& data) const { - UPInt size = data.GetSize(); + size_t size = data.GetSize(); return String::BernsteinHashFunctionCIS((const char*)data, size); } - UPInt operator()(const NoCaseKey& data) const + size_t operator()(const NoCaseKey& data) const { - UPInt size = data.pStr->GetSize(); + size_t size = data.pStr->GetSize(); return String::BernsteinHashFunctionCIS((const char*)data.pStr->ToCStr(), size); } }; @@ -404,18 +405,18 @@ public: class StringBuffer { char* pData; - UPInt Size; - UPInt BufferSize; - UPInt GrowSize; + size_t Size; + size_t BufferSize; + size_t GrowSize; mutable bool LengthIsSize; public: // Constructors / Destructor. StringBuffer(); - explicit StringBuffer(UPInt growSize); + explicit StringBuffer(size_t growSize); StringBuffer(const char* data); - StringBuffer(const char* data, UPInt buflen); + StringBuffer(const char* data, size_t buflen); StringBuffer(const String& src); StringBuffer(const StringBuffer& src); explicit StringBuffer(const wchar_t* data); @@ -423,8 +424,8 @@ public: // Modify grow size used for growing/shrinking the buffer. - UPInt GetGrowSize() const { return GrowSize; } - void SetGrowSize(UPInt growSize); + size_t GetGrowSize() const { return GrowSize; } + void SetGrowSize(size_t growSize); // *** General Functions @@ -437,38 +438,38 @@ public: const char* ToCStr() const { return (pData) ? pData : ""; } // Returns number of bytes. - UPInt GetSize() const { return Size ; } + size_t GetSize() const { return Size ; } // Tells whether or not the string is empty. bool IsEmpty() const { return GetSize() == 0; } // Returns number of characters - UPInt GetLength() const; + size_t GetLength() const; // Returns character at the specified index - UInt32 GetCharAt(UPInt index) const; - UInt32 GetFirstCharAt(UPInt index, const char** offset) const; - UInt32 GetNextChar(const char** offset) const; + 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(UPInt _size); - void Reserve(UPInt _size); + void Resize(size_t _size); + void Reserve(size_t _size); // Appends a character - void AppendChar(UInt32 ch); + void AppendChar(uint32_t ch); // Append a string - void AppendString(const wchar_t* pstr, SPInt len = -1); - void AppendString(const char* putf8str, SPInt utf8StrSz = -1); + 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, UPInt size); + //void AssignString(const InitStruct& src, size_t size); // Inserts substr at posAt - void Insert (const char* substr, UPInt posAt, SPInt len = -1); + void Insert (const char* substr, size_t posAt, intptr_t len = -1); // Inserts character at posAt - UPInt InsertCharAt(UInt32 c, UPInt posAt); + size_t InsertCharAt(uint32_t c, size_t posAt); // Assignment void operator = (const char* str); @@ -487,10 +488,10 @@ public: // Accesses raw bytes char& operator [] (int index) { - OVR_ASSERT(((UPInt)index) < GetSize()); + OVR_ASSERT(((size_t)index) < GetSize()); return pData[index]; } - char& operator [] (UPInt index) + char& operator [] (size_t index) { OVR_ASSERT(index < GetSize()); return pData[index]; @@ -498,10 +499,10 @@ public: const char& operator [] (int index) const { - OVR_ASSERT(((UPInt)index) < GetSize()); + OVR_ASSERT(((size_t)index) < GetSize()); return pData[index]; } - const char& operator [] (UPInt index) const + const char& operator [] (size_t index) const { OVR_ASSERT(index < GetSize()); return pData[index]; @@ -520,7 +521,7 @@ public: StringDataPtr() : pStr(NULL), Size(0) {} StringDataPtr(const StringDataPtr& p) : pStr(p.pStr), Size(p.Size) {} - StringDataPtr(const char* pstr, UPInt sz) + StringDataPtr(const char* pstr, size_t sz) : pStr(pstr), Size(sz) {} StringDataPtr(const char* pstr) : pStr(pstr), Size((pstr != NULL) ? OVR_strlen(pstr) : 0) {} @@ -532,7 +533,7 @@ public: public: const char* ToCStr() const { return pStr; } - UPInt GetSize() const { return Size; } + size_t GetSize() const { return Size; } bool IsEmpty() const { return GetSize() == 0; } // value is a prefix of this string @@ -550,33 +551,33 @@ public: // Find first character. // init_ind - initial index. - SPInt FindChar(char c, UPInt init_ind = 0) const + intptr_t FindChar(char c, size_t init_ind = 0) const { - for (UPInt i = init_ind; i < GetSize(); ++i) + for (size_t i = init_ind; i < GetSize(); ++i) if (pStr[i] == c) - return static_cast(i); + return static_cast(i); return -1; } // Find last character. // init_ind - initial index. - SPInt FindLastChar(char c, UPInt init_ind = ~0) const + intptr_t FindLastChar(char c, size_t init_ind = ~0) const { - if (init_ind == (UPInt)~0 || init_ind > GetSize()) + if (init_ind == (size_t)~0 || init_ind > GetSize()) init_ind = GetSize(); else ++init_ind; - for (UPInt i = init_ind; i > 0; --i) + for (size_t i = init_ind; i > 0; --i) if (pStr[i - 1] == c) - return static_cast(i - 1); + return static_cast(i - 1); return -1; } // Create new object and trim size bytes from the left. - StringDataPtr GetTrimLeft(UPInt size) const + StringDataPtr GetTrimLeft(size_t size) const { // Limit trim size to the size of the string. size = Alg::PMin(GetSize(), size); @@ -584,7 +585,7 @@ public: return StringDataPtr(ToCStr() + size, GetSize() - size); } // Create new object and trim size bytes from the right. - StringDataPtr GetTrimRight(UPInt size) const + StringDataPtr GetTrimRight(size_t size) const { // Limit trim to the size of the string. size = Alg::PMin(GetSize(), size); @@ -596,7 +597,7 @@ public: // Useful for parsing. StringDataPtr GetNextToken(char separator = ':') const { - UPInt cur_pos = 0; + size_t cur_pos = 0; const char* cur_str = ToCStr(); for (; cur_pos < GetSize() && cur_str[cur_pos]; ++cur_pos) @@ -611,7 +612,7 @@ public: } // Trim size bytes from the left. - StringDataPtr& TrimLeft(UPInt size) + StringDataPtr& TrimLeft(size_t size) { // Limit trim size to the size of the string. size = Alg::PMin(GetSize(), size); @@ -621,7 +622,7 @@ public: return *this; } // Trim size bytes from the right. - StringDataPtr& TrimRight(UPInt size) + StringDataPtr& TrimRight(size_t size) { // Limit trim to the size of the string. size = Alg::PMin(GetSize(), size); @@ -636,7 +637,7 @@ public: // Hash functor used string data pointers struct HashFunctor { - UPInt operator()(const StringDataPtr& data) const + size_t operator()(const StringDataPtr& data) const { return String::BernsteinHashFunction(data.ToCStr(), data.GetSize()); } @@ -649,7 +650,7 @@ public: protected: const char* pStr; - UPInt Size; + size_t Size; }; } // OVR diff --git a/LibOVR/Src/Kernel/OVR_StringHash.h b/LibOVR/Src/Kernel/OVR_StringHash.h index baa80a7..410a578 100644 --- a/LibOVR/Src/Kernel/OVR_StringHash.h +++ b/LibOVR/Src/Kernel/OVR_StringHash.h @@ -7,16 +7,16 @@ Content : String hash table used when optional case-insensitive Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, diff --git a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp b/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp index e196dd7..d52b6bb 100644 --- a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp +++ b/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp @@ -5,16 +5,16 @@ Content : String format functions. Created : February 27, 2013 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -32,22 +32,45 @@ namespace OVR { void StringBuffer::AppendFormat(const char* format, ...) { va_list argList; + char buffer[512]; + char* bufferUsed = buffer; + char* bufferAllocated = NULL; va_start(argList, format); - UPInt size = OVR_vscprintf(format, argList); - va_end(argList); - char* buffer = (char*) OVR_ALLOC(sizeof(char) * (size+1)); + #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_start(argList, format); - UPInt result = OVR_vsprintf(buffer, size+1, format, argList); - OVR_UNUSED1(result); va_end(argList); - OVR_ASSERT_LOG(result == size, ("Error in OVR_vsprintf")); - AppendString(buffer); + if(bufferUsed) + AppendString(bufferUsed); - OVR_FREE(buffer); + if(bufferAllocated) + OVR_FREE(bufferAllocated); } } // OVR diff --git a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp b/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp index 02abe15..95f3de9 100644 --- a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp +++ b/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp @@ -5,16 +5,16 @@ Content : String filename/url helper function Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -39,7 +39,7 @@ void ScanFilePath(const char* url, const char** pfilename, const char** pext) const char *filename = 0; const char *lastDot = 0; - UInt32 charVal = UTF8Util::DecodeNextChar(&url); + uint32_t charVal = UTF8Util::DecodeNextChar(&url); while (charVal != 0) { @@ -76,8 +76,8 @@ void ScanFilePath(const char* url, const char** pfilename, const char** pext) // - protocol: 'file://', 'http://' const char* ScanPathProtocol(const char* url) { - UInt32 charVal = UTF8Util::DecodeNextChar(&url); - UInt32 charVal2; + uint32_t charVal = UTF8Util::DecodeNextChar(&url); + uint32_t charVal2; while (charVal != 0) { @@ -118,7 +118,7 @@ bool String::HasAbsolutePath(const char* url) if (!url || !*url) return true; // Treat empty strings as absolute. - UInt32 charVal = UTF8Util::DecodeNextChar(&url); + uint32_t charVal = UTF8Util::DecodeNextChar(&url); // Fist character of '/' or '\\' means absolute url. if ((charVal == '/') || (charVal == '\\')) diff --git a/LibOVR/Src/Kernel/OVR_SysFile.cpp b/LibOVR/Src/Kernel/OVR_SysFile.cpp index 604527a..6ef27c7 100644 --- a/LibOVR/Src/Kernel/OVR_SysFile.cpp +++ b/LibOVR/Src/Kernel/OVR_SysFile.cpp @@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32) Created : April 5, 1999 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -51,24 +51,24 @@ public: // Return position / file size virtual int Tell() { return 0; } - virtual SInt64 LTell() { return 0; } + virtual int64_t LTell() { return 0; } virtual int GetLength() { return 0; } - virtual SInt64 LGetLength() { 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 UByte *pbuffer, int numBytes) { return -1; OVR_UNUSED2(pbuffer, numBytes); } - virtual int Read(UByte *pbuffer, int numBytes) { return -1; OVR_UNUSED2(pbuffer, numBytes); } - virtual int SkipBytes(int numBytes) { return 0; OVR_UNUSED(numBytes); } - virtual int BytesAvailable() { return 0; } - virtual bool Flush() { return 0; } - virtual int Seek(int offset, int origin) { return -1; OVR_UNUSED2(offset, origin); } - virtual SInt64 LSeek(SInt64 offset, int origin) { return -1; OVR_UNUSED2(offset, origin); } + 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; OVR_UNUSED2(pstream, byteSize); } - virtual bool Close() { return 0; } + virtual int CopyFromStream(File * /*pstream*/, int /*byteSize*/) { return -1; } + virtual bool Close() { return 0; } }; diff --git a/LibOVR/Src/Kernel/OVR_SysFile.h b/LibOVR/Src/Kernel/OVR_SysFile.h index 61ad6e8..925c51d 100644 --- a/LibOVR/Src/Kernel/OVR_SysFile.h +++ b/LibOVR/Src/Kernel/OVR_SysFile.h @@ -11,16 +11,16 @@ Notes : errno may not be preserved across use of GBaseFile member functi : Directories cannot be deleted while files opened from them are in use (For the GetFullName function) -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -48,9 +48,9 @@ class SysFile; struct FileStat { // No change or create time because they are not available on most systems - SInt64 ModifyTime; - SInt64 AccessTime; - SInt64 FileSize; + int64_t ModifyTime; + int64_t AccessTime; + int64_t FileSize; bool operator== (const FileStat& stat) const { diff --git a/LibOVR/Src/Kernel/OVR_System.cpp b/LibOVR/Src/Kernel/OVR_System.cpp index 3144ade..66c764a 100644 --- a/LibOVR/Src/Kernel/OVR_System.cpp +++ b/LibOVR/Src/Kernel/OVR_System.cpp @@ -6,16 +6,16 @@ Content : General kernel initialization/cleanup, including that Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -28,10 +28,56 @@ 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 { -// ***** OVR::System Implementation +#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) @@ -41,6 +87,8 @@ void System::Init(Log* log, Allocator *palloc) Log::SetGlobalLog(log); Timer::initializeTimerSystem(); Allocator::setInstance(palloc); + Display::Initialize(); + DirectDisplayInitialize(); } else { @@ -52,13 +100,33 @@ void System::Destroy() { if (Allocator::GetInstance()) { - // Wait for all threads to finish; this must be done so that memory - // allocator and all destructors finalize correctly. +#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 - Thread::FinishAllThreads(); + // Wait for all threads to finish; this must be done so that memory + // allocator and all destructors finalize correctly. + Thread::FinishAllThreads(); #endif - // Shutdown heap and destroy SysAlloc singleton, if any. + // 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); @@ -77,5 +145,5 @@ bool System::IsInitialized() return Allocator::GetInstance() != 0; } -} // OVR +} // namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_System.h b/LibOVR/Src/Kernel/OVR_System.h index 253fe19..9d09911 100644 --- a/LibOVR/Src/Kernel/OVR_System.h +++ b/LibOVR/Src/Kernel/OVR_System.h @@ -7,16 +7,16 @@ Content : General kernel initialization/cleanup, including that Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -31,9 +31,103 @@ limitations under the License. #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; @@ -47,19 +141,20 @@ namespace OVR { 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(); @@ -68,11 +163,12 @@ public: 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 + // De-initializes System more, finalizing the threading system and destroying // the global memory allocator. - static void OVR_CDECL Destroy(); + static void OVR_CDECL Destroy(); }; -} // OVR + +} // namespace OVR #endif diff --git a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp new file mode 100644 index 0000000..90ba3cc --- /dev/null +++ b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp @@ -0,0 +1,401 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..9c2a7d3 --- /dev/null +++ b/LibOVR/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 "../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 index 307f107..e159157 100644 --- a/LibOVR/Src/Kernel/OVR_Threads.h +++ b/LibOVR/Src/Kernel/OVR_Threads.h @@ -6,16 +6,16 @@ Content : Contains thread-related (safe) functionality Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -175,8 +175,13 @@ public: //----------------------------------------------------------------------------------- // ***** Thread class -// ThreadId uniquely identifies a thread; returned by GetCurrentThreadId() and -// Thread::GetThreadId. +// 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; @@ -196,9 +201,7 @@ typedef void* ThreadId; 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. @@ -234,30 +237,31 @@ public: // Thread constructor parameters struct CreateParams { - CreateParams(ThreadFn func = 0, void* hand = 0, UPInt ssize = 128 * 1024, + 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 - UPInt stackSize; // Thread stack size + 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(UPInt stackSize = 128 * 1024, int processor = -1); + 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, UPInt stackSize = 128 * 1024, + 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); @@ -314,6 +318,11 @@ public: // 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(); @@ -321,19 +330,35 @@ public: // 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_WIN32) +#if defined(OVR_OS_MS) void* GetOSHandle() const { return ThreadHandle; } #else pthread_t GetOSHandle() const { return ThreadHandle; } #endif -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) ThreadId GetThreadId() const { return IdValue; } #else ThreadId GetThreadId() const { return (ThreadId)GetOSHandle(); } #endif - static int GetOSPriority(ThreadPriority); + // 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 @@ -343,16 +368,18 @@ public: // *** Debugging functionality -#if defined(OVR_OS_WIN32) - virtual void SetThreadName( const char* name ); -#else - virtual void SetThreadName( const char* name ) { OVR_UNUSED(name); } -#endif + 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 *pthread); - + 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); @@ -362,15 +389,15 @@ private: protected: // Thread state flags - AtomicInt ThreadFlags; - AtomicInt SuspendCount; - UPInt StackSize; + AtomicInt ThreadFlags; + AtomicInt SuspendCount; + size_t StackSize; // Hardware processor which this thread is running on. int Processor; ThreadPriority Priority; -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) void* ThreadHandle; volatile ThreadId IdValue; diff --git a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp b/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp index da483d5..760e489 100644 --- a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp +++ b/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp @@ -5,16 +5,16 @@ Content : Created : Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -33,11 +33,21 @@ limitations under the License. #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 { @@ -127,9 +137,9 @@ void MutexImpl::Unlock(Mutex* pmutex) OVR_UNUSED(pmutex); OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0); - unsigned lockCount; + //unsigned lockCount; LockCount--; - lockCount = LockCount; + //lockCount = LockCount; pthread_mutex_unlock(&SMutex); } @@ -619,6 +629,48 @@ Thread::ThreadState Thread::GetThreadState() const 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) { @@ -662,12 +714,88 @@ pthread_attr_t Thread::Attr; /* static */ int Thread::GetOSPriority(ThreadPriority p) -//static inline int MapToSystemPrority(Thread::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) @@ -779,9 +907,78 @@ bool Thread::MSleep(unsigned msecs) /* static */ int Thread::GetCPUCount() { - return 1; + #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 index 91a5e31..4786435 100644 --- a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp +++ b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp @@ -6,16 +6,16 @@ Content : Windows specific thread-related (safe) functionality Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -28,6 +28,7 @@ limitations under the License. #include "OVR_Threads.h" #include "OVR_Hash.h" #include "OVR_Log.h" +#include "OVR_Timer.h" #ifdef OVR_ENABLE_THREADS @@ -67,7 +68,12 @@ 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() { @@ -541,7 +547,7 @@ __declspec(thread) Thread* pCurrentThread = 0; // *** Thread constructors. -Thread::Thread(UPInt stackSize, int processor) +Thread::Thread(size_t stackSize, int processor) { CreateParams params; params.stackSize = stackSize; @@ -549,7 +555,7 @@ Thread::Thread(UPInt stackSize, int processor) Init(params); } -Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, UPInt stackSize, +Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, size_t stackSize, int processor, Thread::ThreadState initialState) { CreateParams params(threadFunction, userHandle, stackSize, processor, initialState); @@ -597,9 +603,14 @@ Thread::~Thread() // Default Run implementation int Thread::Run() { - // Call pointer to function, if available. - return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0; + if (!ThreadFunction) + return 0; + + int ret = ThreadFunction(this, UserHandle); + + return ret; } + void Thread::OnExit() { } @@ -608,7 +619,7 @@ void Thread::OnExit() void Thread::FinishAndRelease() { // Note: thread must be US. - ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED); + ThreadFlags &= (uint32_t)~(OVR_THREAD_STARTED); ThreadFlags |= OVR_THREAD_FINISHED; // Release our reference; this is equivalent to 'delete this' @@ -624,9 +635,9 @@ class ThreadList : public NewOverrideBase //------------------------------------------------------------------------ struct ThreadHashOp { - UPInt operator()(const Thread* ptr) + size_t operator()(const Thread* ptr) { - return (((UPInt)ptr) >> 6) ^ (UPInt)ptr; + return (((size_t)ptr) >> 6) ^ (size_t)ptr; } }; @@ -722,11 +733,12 @@ int Thread::PRun() if (ThreadFlags & OVR_THREAD_START_SUSPENDED) { Suspend(); - ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED; + ThreadFlags &= (uint32_t)~OVR_THREAD_START_SUSPENDED; } // Call the virtual run function ExitCode = Run(); + return ExitCode; } @@ -761,7 +773,7 @@ void Thread::SetExitFlag(bool exitFlag) if (exitFlag) ThreadFlags |= OVR_THREAD_EXIT; else - ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT; + ThreadFlags &= (uint32_t) ~OVR_THREAD_EXIT; } @@ -779,12 +791,39 @@ bool Thread::IsSuspended() const Thread::ThreadState Thread::GetThreadState() const { if (IsSuspended()) - return Suspended; + return Suspended; if (ThreadFlags & OVR_THREAD_STARTED) - return Running; + 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 @@ -793,19 +832,79 @@ int Thread::GetOSPriority(ThreadPriority p) { switch(p) { - case Thread::CriticalPriority: return THREAD_PRIORITY_TIME_CRITICAL; - case Thread::HighestPriority: return THREAD_PRIORITY_HIGHEST; - case Thread::AboveNormalPriority: return THREAD_PRIORITY_ABOVE_NORMAL; - case Thread::NormalPriority: return THREAD_PRIORITY_NORMAL; - case Thread::BelowNormalPriority: return THREAD_PRIORITY_BELOW_NORMAL; - case Thread::LowestPriority: return THREAD_PRIORITY_LOWEST; - case Thread::IdlePriority: return THREAD_PRIORITY_IDLE; + // 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) @@ -852,8 +951,15 @@ bool Thread::Start(ThreadState initialState) 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) @@ -890,13 +996,15 @@ bool Thread::Resume() return 0; // Decrement count, and resume thread if it is 0 - SInt32 oldCount = SuspendCount.ExchangeAdd_Acquire(-1); + int32_t oldCount = SuspendCount.ExchangeAdd_Acquire(-1); if (oldCount >= 1) { if (oldCount == 1) { - if (::ResumeThread(ThreadHandle) != 0xFFFFFFFF) - return 1; + if (::ResumeThread(ThreadHandle) != 0xFFFFFFFF) + { + return 1; + } } else { @@ -922,8 +1030,12 @@ void Thread::Exit(int exitCode) FinishAndRelease(); ThreadList::RemoveRunningThread(this); - // Call the exit function. + // 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 } @@ -951,43 +1063,74 @@ bool Thread::MSleep(unsigned msecs) return 1; } + + void Thread::SetThreadName( const char* name ) { -#if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING) - // Looks ugly, but it is the recommended way to name a thread. - typedef struct tagTHREADNAME_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 - } THREADNAME_INFO; + 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. +} - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = name; - info.dwThreadID = reinterpret_cast(GetThreadId()); - info.dwFlags = 0; +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 +} - __try - { -#ifdef _WIN64 - RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR *)&info ); -#else - RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD *)&info ); -#endif - } - __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER ) - { - } -#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; - GetSystemInfo(&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; } @@ -1001,5 +1144,3 @@ ThreadId GetCurrentThreadId() } // OVR #endif - - diff --git a/LibOVR/Src/Kernel/OVR_Timer.cpp b/LibOVR/Src/Kernel/OVR_Timer.cpp index a8de47d..3a75ec2 100644 --- a/LibOVR/Src/Kernel/OVR_Timer.cpp +++ b/LibOVR/Src/Kernel/OVR_Timer.cpp @@ -5,16 +5,16 @@ Content : Provides static functions for precise timing Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -27,22 +27,61 @@ limitations under the License. #include "OVR_Timer.h" #include "OVR_Log.h" -#if defined (OVR_OS_WIN32) +#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; +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 @@ -53,51 +92,65 @@ double Timer::GetSeconds() if(useFakeSeconds) return FakeSeconds; - return double(Timer::GetTicksNanos()) * 0.000000001; -} - - -#ifndef OVR_OS_WIN32 - -// Unused on OSs other then Win32. -void Timer::initializeTimerSystem() -{ -} -void Timer::shutdownTimerSystem() -{ -} + // 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; +} -//------------------------------------------------------------------------ -// *** Android Specific Timer - -#if defined(OVR_OS_ANDROID) -UInt64 Timer::GetTicksNanos() +uint64_t Timer::GetTicksNanos() { if (useFakeSeconds) - return (UInt64) (FakeSeconds * NanosPerSecond); + 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 )); } - const UInt64 result = (UInt64)tp.tv_sec * (UInt64)(1000 * 1000 * 1000) + UInt64(tp.tv_nsec); +#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_WIN32) +#elif defined (OVR_OS_MS) // This helper class implements high-resolution wrapper that combines timeGetTime() output @@ -106,8 +159,15 @@ UInt64 Timer::GetTicksNanos() struct PerformanceTimer { PerformanceTimer() - : OldMMTimeMs(0), MMTimeWrapCounter(0), PrefFrequency(0), - LastResultNanos(0), PerfMinusTicksDeltaNanos(0) + : UsingVistaOrLater(false), + TimeCS(), + OldMMTimeMs(0), + MMTimeWrapCounter(0), + PerfFrequency(0), + PerfFrequencyInverse(0), + PerfFrequencyInverseNanos(0), + PerfMinusTicksDeltaNanos(0), + LastResultNanos(0) { } enum { @@ -117,168 +177,372 @@ struct PerformanceTimer void Initialize(); void Shutdown(); - UInt64 GetTimeNanos(); - + uint64_t GetTimeSeconds(); + double GetTimeSecondsDouble(); + uint64_t GetTimeNanos(); UINT64 getFrequency() { - if (PrefFrequency == 0) + if (PerfFrequency == 0) { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); - PrefFrequency = freq.QuadPart; + PerfFrequency = freq.QuadPart; + PerfFrequencyInverse = 1.0 / (double)PerfFrequency; + PerfFrequencyInverseNanos = 1000000000.0 / (double)PerfFrequency; } - return PrefFrequency; + 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 OldMMTimeMs; - UInt32 MMTimeWrapCounter; + uint32_t OldMMTimeMs; + uint32_t MMTimeWrapCounter; // Cached performance frequency result. - UInt64 PrefFrequency; + 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 PerfMinusTicksDeltaNanos; + uint64_t PerfMinusTicksDeltaNanos; // Last returned value in nanoseconds, to ensure we don't back-step in time. - UInt64 LastResultNanos; + uint64_t LastResultNanos; }; -PerformanceTimer Win32_PerfTimer; +static PerformanceTimer Win32_PerfTimer; void PerformanceTimer::Initialize() { - timeBeginPeriod(1); + #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); - timeEndPeriod(1); + + #if defined(OVR_OS_WIN32) // Desktop Windows only + MMRESULT mmr = timeEndPeriod(1); + OVR_ASSERT(TIMERR_NOERROR == mmr); + OVR_UNUSED(mmr); + #endif } -UInt64 PerformanceTimer::GetTimeNanos() -{ - UInt64 resultNanos; - LARGE_INTEGER li; - DWORD mmTimeMs; - - // 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". - mmTimeMs = timeGetTime(); - QueryPerformanceCounter(&li); - - if (OldMMTimeMs > mmTimeMs) - MMTimeWrapCounter++; - OldMMTimeMs = mmTimeMs; - - // Normalize to nanoseconds. - UInt64 mmCounterNanos = ((UInt64(MMTimeWrapCounter) << 32) | mmTimeMs) * 1000000; - UInt64 frequency = getFrequency(); - UInt64 perfCounterSeconds = UInt64(li.QuadPart) / frequency; - UInt64 perfRemainderNanos = ( (UInt64(li.QuadPart) - perfCounterSeconds * frequency) * - Timer::NanosPerSecond ) / frequency; - UInt64 perfCounterNanos = perfCounterSeconds * Timer::NanosPerSecond + perfRemainderNanos; - - 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; +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); } - else if (resultNanos < (mmCounterNanos - MMTimerResolutionNanos)) - { - resultNanos = mmCounterNanos - MMTimerResolutionNanos; - if (resultNanos < LastResultNanos) - resultNanos = LastResultNanos; - PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; + + return (uint64_t)(GetTimeNanos() * .0000000001); +} + + +double PerformanceTimer::GetTimeSecondsDouble() +{ + if (UsingVistaOrLater) + { + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + OVR_ASSERT(PerfFrequencyInverse != 0); + return (li.QuadPart * PerfFrequencyInverse); } - LastResultNanos = resultNanos; - ::LeaveCriticalSection(&TimeCS); + return (GetTimeNanos() * .0000000001); +} - //Tom's addition, to keep precision - static UInt64 initial_time = 0; - if (!initial_time) initial_time = resultNanos; - resultNanos -= initial_time; +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 Timer::GetTicksNanos() +uint64_t Timer::GetTicksNanos() { if (useFakeSeconds) - return (UInt64) (FakeSeconds * NanosPerSecond); + return (uint64_t) (FakeSeconds * NanosPerSecond); return Win32_PerfTimer.GetTimeNanos(); } void Timer::initializeTimerSystem() { Win32_PerfTimer.Initialize(); - } void Timer::shutdownTimerSystem() { Win32_PerfTimer.Shutdown(); } -#else // !OVR_OS_WIN32 && !OVR_OS_ANDROID + + +#elif defined(OVR_OS_MAC) + + +double Timer::TimeConvertFactorNanos = 0.0; +double Timer::TimeConvertFactorSeconds = 0.0; //------------------------------------------------------------------------ // *** Standard OS Timer -UInt64 Timer::GetTicksNanos() +// 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) (FakeSeconds * NanosPerSecond); + 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 - // TODO: prefer rdtsc when available? - UInt64 result; + + // We cannot use rdtsc because its frequency changes at runtime. + uint64_t result; // Return microseconds. struct timeval tv; gettimeofday(&tv, 0); - result = (UInt64)tv.tv_sec * 1000000; + 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 diff --git a/LibOVR/Src/Kernel/OVR_Timer.h b/LibOVR/Src/Kernel/OVR_Timer.h index 12cba3b..6c8dbb7 100644 --- a/LibOVR/Src/Kernel/OVR_Timer.h +++ b/LibOVR/Src/Kernel/OVR_Timer.h @@ -6,16 +6,16 @@ Content : Provides static functions for precise timing Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -42,9 +42,9 @@ class Timer { public: enum { - MsPerSecond = 1000, // Milliseconds in one second. - NanosPerSecond = MsPerSecond * 1000 * 1000, - MksPerSecond = MsPerSecond * 1000 + 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 @@ -56,19 +56,19 @@ public: static double OVR_STDCALL GetSeconds(); // Returns time in Nanoseconds, using highest possible system resolution. - static UInt64 OVR_STDCALL GetTicksNanos(); + 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 OVR_STDCALL GetTicksMs() - { return UInt32(GetTicksNanos() / 1000000); } + static uint32_t OVR_STDCALL GetTicksMs() + { return uint32_t(GetTicksNanos() / 1000000); } // for recorded data playback - static void SetFakeSeconds(double fakeSeconds) + static void SetFakeSeconds(double fakeSeconds, bool enable = true) { FakeSeconds = fakeSeconds; - useFakeSeconds = true; + useFakeSeconds = enable; } private: @@ -79,7 +79,18 @@ private: // for recorded data playback static double FakeSeconds; - static bool useFakeSeconds; + 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 }; diff --git a/LibOVR/Src/Kernel/OVR_Types.h b/LibOVR/Src/Kernel/OVR_Types.h index 8f2b3f3..d42d131 100644 --- a/LibOVR/Src/Kernel/OVR_Types.h +++ b/LibOVR/Src/Kernel/OVR_Types.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -28,16 +28,42 @@ 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 +// ****** 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 (Windows 95/98/ME and Windows NT/2000/XP) -// DARWIN - Darwin OS (Mac OS X) -// LINUX - Linux -// ANDROID - Android -// IPHONE - iPhone +// 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__) @@ -46,22 +72,57 @@ limitations under the License. # else # define OVR_OS_DARWIN # define OVR_OS_MAC +# define OVR_OS_BSD # endif #elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) -# define OVR_OS_WIN32 +# 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(ANDROID) -# define OVR_OS_ANDROID +#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 // @@ -75,7 +136,7 @@ limitations under the License. // OTHER - CPU for which no special support is present or needed -#if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) +#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) @@ -101,7 +162,7 @@ limitations under the License. // Altivec - Available on all modern ppc processors. // Neon - Available on some armv7+ processors. -#if defined(__SSE__) || defined(OVR_OS_WIN32) +#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__ @@ -114,47 +175,6 @@ limitations under the License. #endif // __ARM_NEON__ -//----------------------------------------------------------------------------------- -// ***** 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 - -#elif defined(__GNUC__) -# define OVR_CC_GNU - -#elif defined(__CC_ARM) -# define OVR_CC_ARM - -#else -# error "Oculus does not support this Compiler" -#endif - - //----------------------------------------------------------------------------------- // ***** Compiler Warnings @@ -194,16 +214,23 @@ limitations under the License. # define _CRTDBG_MAP_ALLOC # include # include - -#if 0 -// Uncomment this to help debug memory leaks under Visual Studio in OVR apps only. -// This shouldn't be defined in customer releases. -# ifndef OVR_DEFINE_NEW -# define OVR_DEFINE_NEW new(__FILE__, __LINE__) -# define new OVR_DEFINE_NEW -# endif #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 @@ -219,7 +246,7 @@ typedef size_t UPInt; typedef ptrdiff_t SPInt; -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) typedef char SByte; // 8 bit Integer (Byte) typedef unsigned char UByte; @@ -255,33 +282,60 @@ 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]; +}; -// ***** BaseTypes Namespace -// BaseTypes namespace is explicitly declared to allow base types to be used -// by customers directly without other contents of OVR namespace. -// -// Its is expected that OVR samples will declare 'using namespace OVR::BaseTypes' -// to allow using these directly without polluting the target scope with other -// OVR declarations, such as Ptr<>, String or Mutex. -namespace BaseTypes -{ - using OVR::UPInt; - using OVR::SPInt; - using OVR::UByte; - using OVR::SByte; - using OVR::UInt16; - using OVR::SInt16; - using OVR::UInt32; - using OVR::SInt32; - using OVR::UInt64; - using OVR::SInt64; -} // OVR::BaseTypes } // 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 // @@ -302,19 +356,9 @@ namespace BaseTypes #define OVR_BIG_ENDIAN 2 -// Force inline substitute - goes before function declaration -#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 - - -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) - // ***** Win32 + // ***** Windows and non-desktop platforms // Byte order #define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN @@ -369,56 +413,415 @@ namespace BaseTypes #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_DEBUG_BREAK, OVR_ASSERT +// ***** 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 // -// If not in debug build, macros do nothing -#ifndef OVR_BUILD_DEBUG +// Force inline substitute - goes before function declaration +// Example usage: +// OVR_FORCE_INLINE void Test(); -# define OVR_DEBUG_CODE(c) c -# define OVR_DEBUG_BREAK ((void)0) -# define OVR_ASSERT(p) ((void)0) +#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 -#else -// Microsoft Win32 specific debugging support -#if defined(OVR_OS_WIN32) -# ifdef OVR_CPU_X86 -# if defined(__cplusplus_cli) -# define OVR_DEBUG_BREAK do { __debugbreak(); } while(0) -# elif defined(OVR_CC_GNU) -# define OVR_DEBUG_BREAK do { OVR_ASM("int $3\n\t"); } while(0) -# else -# define OVR_DEBUG_BREAK do { OVR_ASM int 3 } while (0) -# endif -# else -# define OVR_DEBUG_BREAK do { __debugbreak(); } while(0) -# endif -// Unix specific debugging support -#elif defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) -# define OVR_DEBUG_BREAK do { OVR_ASM("int $3\n\t"); } while(0) +// ------------------------------------------------------------------------ +// ***** 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_DEBUG_BREAK do { *((int *) 0) = 1; } while(0) + #define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(class_::member_)) #endif -#define OVR_DEBUG_CODE(c) -// This will cause compiler breakpoint -#define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; } } while(0) +//----------------------------------------------------------------------------------- +// ***** 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 -// Compile-time assert; produces compiler error if condition is false -#define OVR_COMPILER_ASSERT(x) { int zero = 0; switch(zero) {case 0: case x:;} } +// 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_UNUSED - Unused Argument handling +// ***** 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 @@ -438,8 +841,10 @@ namespace BaseTypes //----------------------------------------------------------------------------------- // ***** Configuration Macros +// +// Expands to the current build type as a const char string literal. +// Acts as the following declaration: const char OVR_BUILD_STRING[]; -// SF Build type #ifdef OVR_BUILD_DEBUG # define OVR_BUILD_STRING "Debug" #else @@ -471,4 +876,34 @@ namespace BaseTypes // +//----------------------------------------------------------------------------------- +// ***** 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 index f8aa697..68e58ea 100644 --- a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp +++ b/LibOVR/Src/Kernel/OVR_UTF8Util.cpp @@ -7,16 +7,16 @@ 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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -30,10 +30,10 @@ limitations under the License. namespace OVR { namespace UTF8Util { -SPInt OVR_STDCALL GetLength(const char* buf, SPInt buflen) +intptr_t OVR_STDCALL GetLength(const char* buf, intptr_t buflen) { const char* p = buf; - SPInt length = 0; + intptr_t length = 0; if (buflen != -1) { @@ -53,10 +53,10 @@ SPInt OVR_STDCALL GetLength(const char* buf, SPInt buflen) return length; } -UInt32 OVR_STDCALL GetCharAt(SPInt index, const char* putf8str, SPInt length) +uint32_t OVR_STDCALL GetCharAt(intptr_t index, const char* putf8str, intptr_t length) { const char* buf = putf8str; - UInt32 c = 0; + uint32_t c = 0; if (length != -1) { @@ -87,7 +87,7 @@ UInt32 OVR_STDCALL GetCharAt(SPInt index, const char* putf8str, SPInt length) return c; } -SPInt OVR_STDCALL GetByteIndex(SPInt index, const char *putf8str, SPInt length) +intptr_t OVR_STDCALL GetByteIndex(intptr_t index, const char *putf8str, intptr_t length) { const char* buf = putf8str; @@ -104,7 +104,7 @@ SPInt OVR_STDCALL GetByteIndex(SPInt index, const char *putf8str, SPInt length) while (index > 0) { - UInt32 c = UTF8Util::DecodeNextChar_Advance0(&buf); + uint32_t c = UTF8Util::DecodeNextChar_Advance0(&buf); index--; if (c == 0) @@ -114,7 +114,7 @@ SPInt OVR_STDCALL GetByteIndex(SPInt index, const char *putf8str, SPInt length) return buf-putf8str; } -int OVR_STDCALL GetEncodeCharSize(UInt32 ucs_character) +int OVR_STDCALL GetEncodeCharSize(uint32_t ucs_character) { if (ucs_character <= 0x7F) return 1; @@ -132,9 +132,9 @@ int OVR_STDCALL GetEncodeCharSize(UInt32 ucs_character) return 0; } -UInt32 OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer) +uint32_t OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer) { - UInt32 uc; + uint32_t uc; char c; // Security considerations: @@ -171,7 +171,7 @@ UInt32 OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer) if (c == 0) return 0; // End of buffer. - if ((c & 0x80) == 0) return (UInt32) c; // Conventional 7-bit ASCII. + if ((c & 0x80) == 0) return (uint32_t) c; // Conventional 7-bit ASCII. // Multi-byte sequences. if ((c & 0xE0) == 0xC0) @@ -236,7 +236,7 @@ UInt32 OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer) } -void OVR_STDCALL EncodeChar(char* pbuffer, SPInt* pindex, UInt32 ucs_character) +void OVR_STDCALL EncodeChar(char* pbuffer, intptr_t* pindex, uint32_t ucs_character) { if (ucs_character <= 0x7F) { @@ -289,9 +289,9 @@ void OVR_STDCALL EncodeChar(char* pbuffer, SPInt* pindex, UInt32 ucs_character) } } -SPInt OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, SPInt length) +intptr_t OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, intptr_t length) { - SPInt len = 0; + intptr_t len = 0; if (length != -1) for (int i = 0; i < length; i++) { @@ -307,9 +307,9 @@ SPInt OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, SPInt length) return len; } -void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, SPInt length) +void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, intptr_t length) { - SPInt ofs = 0; + intptr_t ofs = 0; if (length != -1) { for (int i = 0; i < length; i++) @@ -329,14 +329,14 @@ void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, SPInt length) pbuff[ofs] = 0; } -UPInt OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytesLen) +size_t OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, intptr_t bytesLen) { wchar_t *pbegin = pbuff; if (bytesLen == -1) { while (1) { - UInt32 ch = DecodeNextChar_Advance0(&putf8str); + uint32_t ch = DecodeNextChar_Advance0(&putf8str); if (ch == 0) break; else if (ch >= 0xFFFF) @@ -349,7 +349,7 @@ UPInt OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytes const char* p = putf8str; while ((p - putf8str) < bytesLen) { - UInt32 ch = DecodeNextChar_Advance0(&p); + uint32_t ch = DecodeNextChar_Advance0(&p); if (ch >= 0xFFFF) ch = 0xFFFD; *pbuff++ = wchar_t(ch); @@ -384,12 +384,12 @@ UPInt OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytes #include -bool check_equal(const char* utf8_in, const UInt32* ucs_in) +bool check_equal(const char* utf8_in, const uint32_t* ucs_in) { for (;;) { - UInt32 next_ucs = *ucs_in++; - UInt32 next_ucs_from_utf8 = utf8::decode_next_unicode_character(&utf8_in); + 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; @@ -429,11 +429,11 @@ void log_ascii(const char* line) } -void log_ucs(const UInt32* line) +void log_ucs(const uint32_t* line) { for (;;) { - UInt32 uc = *line++; + uint32_t uc = *line++; if (uc == 0) { // End of line. @@ -458,7 +458,7 @@ int main(int argc, const char* argv[]) { { const char* test8 = "Ignacio Castaño"; - const UInt32 test32[] = + const uint32_t test32[] = { 0x49, 0x67, 0x6E, 0x61, 0x63, 0x69, 0x6F, 0x20, 0x43, 0x61, @@ -484,7 +484,7 @@ int main(int argc, const char* argv[]) const int LINE_SIZE = 200; // max line size char line_buffer_utf8[LINE_SIZE]; char reencoded_utf8[6 * LINE_SIZE]; - UInt32 line_buffer_ucs[LINE_SIZE]; + uint32_t line_buffer_ucs[LINE_SIZE]; int byte_counter = 0; for (;;) @@ -503,10 +503,10 @@ int main(int argc, const char* argv[]) // Decode into UCS. const char* p = line_buffer_utf8; - UInt32* q = line_buffer_ucs; + uint32_t* q = line_buffer_ucs; for (;;) { - UInt32 uc = UTF8Util::DecodeNextChar(&p); + uint32_t uc = UTF8Util::DecodeNextChar(&p); *q++ = uc; OVR_ASSERT(q < line_buffer_ucs + LINE_SIZE); @@ -520,7 +520,7 @@ int main(int argc, const char* argv[]) int index = 0; for (;;) { - UInt32 uc = *q++; + uint32_t uc = *q++; OVR_ASSERT(index < LINE_SIZE * 6 - 6); int last_index = index; UTF8Util::EncodeChar(reencoded_utf8, &index, uc); diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.h b/LibOVR/Src/Kernel/OVR_UTF8Util.h index 6a596012..3b640f0 100644 --- a/LibOVR/Src/Kernel/OVR_UTF8Util.h +++ b/LibOVR/Src/Kernel/OVR_UTF8Util.h @@ -1,21 +1,21 @@ /************************************************************************************ -PublicHeader: OVR.h +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, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -38,56 +38,56 @@ namespace OVR { namespace UTF8Util { // Determines the length of UTF8 string in characters. // If source length is specified (in bytes), null 0 character is counted properly. -SPInt OVR_STDCALL GetLength(const char* putf8str, SPInt length = -1); +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 OVR_STDCALL GetCharAt(SPInt index, const char* putf8str, SPInt length = -1); +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. -SPInt OVR_STDCALL GetByteIndex(SPInt index, const char* putf8str, SPInt length = -1); +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. -SPInt OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, SPInt length = -1); +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, SPInt length = -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) -UPInt OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytesLen = -1); +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 ucsCharacter); +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, SPInt* poffset, UInt32 ucsCharacter); +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 OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer); +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 DecodeNextChar(const char** putf8Buffer) +inline uint32_t DecodeNextChar(const char** putf8Buffer) { - UInt32 ch = DecodeNextChar_Advance0(putf8Buffer); + uint32_t ch = DecodeNextChar_Advance0(putf8Buffer); if (ch == 0) (*putf8Buffer)--; return ch; diff --git a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c b/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c new file mode 100644 index 0000000..142faf1 --- /dev/null +++ b/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c @@ -0,0 +1,2955 @@ +/* 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 new file mode 100644 index 0000000..4a1bcf0 --- /dev/null +++ b/LibOVR/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/LibOVR/Src/Net/OVR_BitStream.cpp b/LibOVR/Src/Net/OVR_BitStream.cpp new file mode 100644 index 0000000..b565f22 --- /dev/null +++ b/LibOVR/Src/Net/OVR_BitStream.cpp @@ -0,0 +1,1151 @@ +/************************************************************************************ + +Filename : OVR_BitStream.cpp +Content : A generic serialization toolkit for packing data to a binary stream. +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_BitStream.h" + +#ifdef OVR_OS_WIN32 +#include +#else +#include +#endif + +namespace OVR { namespace Net { + + +//----------------------------------------------------------------------------- +// BitStream + +BitStream::BitStream() +{ + numberOfBitsUsed = 0; + //numberOfBitsAllocated = 32 * 8; + numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8; + readOffset = 0; + //data = ( unsigned char* ) OVR_ALLOC( 32); + data = ( unsigned char* ) stackData; + +#ifdef _DEBUG + // OVR_ASSERT( data ); +#endif + //memset(data, 0, 32); + copyData = true; +} + +BitStream::BitStream( const unsigned int initialBytesToAllocate ) +{ + numberOfBitsUsed = 0; + readOffset = 0; + if (initialBytesToAllocate <= BITSTREAM_STACK_ALLOCATION_SIZE) + { + data = ( unsigned char* ) stackData; + numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8; + } + else + { + data = ( unsigned char* ) OVR_ALLOC( (size_t) initialBytesToAllocate); + numberOfBitsAllocated = initialBytesToAllocate << 3; + } +#ifdef _DEBUG + OVR_ASSERT( data ); +#endif + // memset(data, 0, initialBytesToAllocate); + copyData = true; +} + +BitStream::BitStream( char* _data, const unsigned int lengthInBytes, bool _copyData ) +{ + numberOfBitsUsed = lengthInBytes << 3; + readOffset = 0; + copyData = _copyData; + numberOfBitsAllocated = lengthInBytes << 3; + + if ( copyData ) + { + if ( lengthInBytes > 0 ) + { + if (lengthInBytes < BITSTREAM_STACK_ALLOCATION_SIZE) + { + data = ( unsigned char* ) stackData; + numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE << 3; + } + else + { + data = ( unsigned char* ) OVR_ALLOC( (size_t) lengthInBytes); + } +#ifdef _DEBUG + OVR_ASSERT( data ); +#endif + memcpy( data, _data, (size_t) lengthInBytes ); + } + else + data = 0; + } + else + 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 ) +{ +#ifdef _DEBUG + OVR_ASSERT( lengthInBits >= ( BitSize_t ) numberOfBitsAllocated ); +#endif + numberOfBitsAllocated = lengthInBits; +} + +BitStream::~BitStream() +{ + 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 +} + +void BitStream::Reset( void ) +{ + // Note: Do NOT reallocate memory because BitStream is used + // in places to serialize/deserialize a buffer. Reallocation + // is a dangerous operation (may result in leaks). + + if ( numberOfBitsUsed > 0 ) + { + // memset(data, 0, BITS_TO_BYTES(numberOfBitsUsed)); + } + + // Don't free memory here for speed efficiency + //free(data); // Use realloc and free so we are more efficient than delete and new for resizing + numberOfBitsUsed = 0; + + //numberOfBitsAllocated=8; + readOffset = 0; + + //data=(unsigned char*)OVR_ALLOC(1, _FILE_AND_LINE_); + // if (numberOfBitsAllocated>0) + // memset(data, 0, BITS_TO_BYTES(numberOfBitsAllocated)); +} + +// Write an array or casted stream +void BitStream::Write( const char* inputByteArray, const unsigned int numberOfBytes ) +{ + if (numberOfBytes==0) + return; + + // Optimization: + if ((numberOfBitsUsed & 7) == 0) + { + AddBitsAndReallocate( BYTES_TO_BITS(numberOfBytes) ); + memcpy(data+BITS_TO_BYTES(numberOfBitsUsed), inputByteArray, (size_t) numberOfBytes); + numberOfBitsUsed+=BYTES_TO_BITS(numberOfBytes); + } + else + { + WriteBits( ( unsigned char* ) inputByteArray, numberOfBytes * 8, true ); + } + +} +void BitStream::Write( BitStream *bitStream) +{ + Write(bitStream, bitStream->GetNumberOfBitsUsed()-bitStream->GetReadOffset()); +} +void BitStream::Write( BitStream *bitStream, BitSize_t numberOfBits ) +{ + AddBitsAndReallocate( numberOfBits ); + BitSize_t numberOfBitsMod8; + + if ((bitStream->GetReadOffset()&7)==0 && (numberOfBitsUsed&7)==0) + { + int readOffsetBytes=bitStream->GetReadOffset()/8; + int numBytes=numberOfBits/8; + memcpy(data + (numberOfBitsUsed >> 3), bitStream->GetData()+readOffsetBytes, numBytes); + numberOfBits-=BYTES_TO_BITS(numBytes); + bitStream->SetReadOffset(BYTES_TO_BITS(numBytes+readOffsetBytes)); + numberOfBitsUsed+=BYTES_TO_BITS(numBytes); + } + + while (numberOfBits-->0 && bitStream->readOffset + 1 <= bitStream->numberOfBitsUsed) + { + numberOfBitsMod8 = numberOfBitsUsed & 7; + if ( numberOfBitsMod8 == 0 ) + { + // New byte + if (bitStream->data[ bitStream->readOffset >> 3 ] & ( 0x80 >> ( bitStream->readOffset & 7 ) ) ) + { + // Write 1 + data[ numberOfBitsUsed >> 3 ] = 0x80; + } + else + { + // Write 0 + data[ numberOfBitsUsed >> 3 ] = 0; + } + + } + else + { + // Existing byte + if (bitStream->data[ bitStream->readOffset >> 3 ] & ( 0x80 >> ( bitStream->readOffset & 7 ) ) ) + data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 ); // Set the bit to 1 + // else 0, do nothing + } + + bitStream->readOffset++; + numberOfBitsUsed++; + } +} +void BitStream::Write( BitStream &bitStream, BitSize_t numberOfBits ) +{ + Write(&bitStream, numberOfBits); +} +void BitStream::Write( BitStream &bitStream ) +{ + Write(&bitStream); +} +bool BitStream::Read( BitStream *bitStream, BitSize_t numberOfBits ) +{ + if (GetNumberOfUnreadBits() < numberOfBits) + return false; + bitStream->Write(this, numberOfBits); + return true; +} +bool BitStream::Read( BitStream *bitStream ) +{ + bitStream->Write(this); + return true; +} +bool BitStream::Read( BitStream &bitStream, BitSize_t numberOfBits ) +{ + if (GetNumberOfUnreadBits() < numberOfBits) + return false; + bitStream.Write(this, numberOfBits); + return true; +} +bool BitStream::Read( BitStream &bitStream ) +{ + bitStream.Write(this); + return true; +} + +// Read an array or casted stream +bool BitStream::Read( char* outByteArray, const unsigned int numberOfBytes ) +{ + // Optimization: + if ((readOffset & 7) == 0) + { + if ( readOffset + ( numberOfBytes << 3 ) > numberOfBitsUsed ) + return false; + + // Write the data + memcpy( outByteArray, data + ( readOffset >> 3 ), (size_t) numberOfBytes ); + + readOffset += numberOfBytes << 3; + return true; + } + else + { + return ReadBits( ( unsigned char* ) outByteArray, numberOfBytes * 8 ); + } +} + +// Sets the read pointer back to the beginning of your data. +void BitStream::ResetReadPointer( void ) +{ + readOffset = 0; +} + +// Sets the write pointer back to the beginning of your data. +void BitStream::ResetWritePointer( void ) +{ + numberOfBitsUsed = 0; +} + +// Write a 0 +void BitStream::Write0( void ) +{ + AddBitsAndReallocate( 1 ); + + // New bytes need to be zeroed + if ( ( numberOfBitsUsed & 7 ) == 0 ) + data[ numberOfBitsUsed >> 3 ] = 0; + + numberOfBitsUsed++; +} + +// Write a 1 +void BitStream::Write1( void ) +{ + AddBitsAndReallocate( 1 ); + + BitSize_t numberOfBitsMod8 = numberOfBitsUsed & 7; + + if ( numberOfBitsMod8 == 0 ) + data[ numberOfBitsUsed >> 3 ] = 0x80; + else + data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 ); // Set the bit to 1 + + numberOfBitsUsed++; +} + +// Returns true if the next data read is a 1, false if it is a 0 +bool BitStream::ReadBit( void ) +{ + bool result = ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) !=0; + readOffset++; + return result; +} + +// Align the bitstream to the byte boundary and then write the specified number of bits. +// This is faster than WriteBits but wastes the bits to do the alignment and requires you to call +// SetReadToByteAlignment at the corresponding read position +void BitStream::WriteAlignedBytes( const unsigned char* inByteArray, const unsigned int numberOfBytesToWrite ) +{ + AlignWriteToByteBoundary(); + Write((const char*) inByteArray, numberOfBytesToWrite); +} +void BitStream::EndianSwapBytes( int byteOffset, int length ) +{ + if (DoEndianSwap()) + { + ReverseBytesInPlace(data+byteOffset, length); + } +} +/// Aligns the bitstream, writes inputLength, and writes input. Won't write beyond maxBytesToWrite +void BitStream::WriteAlignedBytesSafe( const char *inByteArray, const unsigned int inputLength, const unsigned int maxBytesToWrite ) +{ + if (inByteArray==0 || inputLength==0) + { + WriteCompressed((unsigned int)0); + return; + } + WriteCompressed(inputLength); + WriteAlignedBytes((const unsigned char*) inByteArray, inputLength < maxBytesToWrite ? inputLength : maxBytesToWrite); +} + +// Read bits, starting at the next aligned bits. Note that the modulus 8 starting offset of the +// sequence must be the same as was used with WriteBits. This will be a problem with packet coalescence +// unless you byte align the coalesced packets. +bool BitStream::ReadAlignedBytes( unsigned char* inOutByteArray, const unsigned int numberOfBytesToRead ) +{ +#ifdef _DEBUG + OVR_ASSERT( numberOfBytesToRead > 0 ); +#endif + + if ( numberOfBytesToRead <= 0 ) + return false; + + // Byte align + AlignReadToByteBoundary(); + + if ( readOffset + ( numberOfBytesToRead << 3 ) > numberOfBitsUsed ) + return false; + + // Write the data + memcpy( inOutByteArray, data + ( readOffset >> 3 ), (size_t) numberOfBytesToRead ); + + readOffset += numberOfBytesToRead << 3; + + return true; +} +bool BitStream::ReadAlignedBytesSafe( char *inOutByteArray, int &inputLength, const int maxBytesToRead ) +{ + return ReadAlignedBytesSafe(inOutByteArray,(unsigned int&) inputLength,(unsigned int)maxBytesToRead); +} +bool BitStream::ReadAlignedBytesSafe( char *inOutByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead ) +{ + if (ReadCompressed(inputLength)==false) + return false; + if (inputLength > maxBytesToRead) + inputLength=maxBytesToRead; + if (inputLength==0) + return true; + return ReadAlignedBytes((unsigned char*) inOutByteArray, inputLength); +} +bool BitStream::ReadAlignedBytesSafeAlloc( char **outByteArray, int &inputLength, const unsigned int maxBytesToRead ) +{ + return ReadAlignedBytesSafeAlloc(outByteArray,(unsigned int&) inputLength, maxBytesToRead); +} +bool BitStream::ReadAlignedBytesSafeAlloc( char ** outByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead ) +{ + OVR_FREE(*outByteArray); + *outByteArray=0; + if (ReadCompressed(inputLength)==false) + return false; + if (inputLength > maxBytesToRead) + inputLength=maxBytesToRead; + if (inputLength==0) + return true; + *outByteArray = (char*) OVR_ALLOC( (size_t) inputLength); + return ReadAlignedBytes((unsigned char*) *outByteArray, inputLength); +} + +// Write numberToWrite bits from the input source +void BitStream::WriteBits( const unsigned char* inByteArray, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits ) +{ +// if (numberOfBitsToWrite<=0) +// return; + + AddBitsAndReallocate( numberOfBitsToWrite ); + + const BitSize_t numberOfBitsUsedMod8 = numberOfBitsUsed & 7; + + // If currently aligned and numberOfBits is a multiple of 8, just memcpy for speed + if (numberOfBitsUsedMod8==0 && (numberOfBitsToWrite&7)==0) + { + memcpy( data + ( numberOfBitsUsed >> 3 ), inByteArray, numberOfBitsToWrite>>3); + numberOfBitsUsed+=numberOfBitsToWrite; + return; + } + + unsigned char dataByte; + const unsigned char* inputPtr=inByteArray; + + // Faster to put the while at the top surprisingly enough + while ( numberOfBitsToWrite > 0 ) + //do + { + dataByte = *( inputPtr++ ); + + if ( numberOfBitsToWrite < 8 && rightAlignedBits ) // rightAlignedBits means in the case of a partial byte, the bits are aligned from the right (bit 0) rather than the left (as in the normal internal representation) + dataByte <<= 8 - numberOfBitsToWrite; // shift left to get the bits on the left, as in our internal representation + + // Writing to a new byte each time + if ( numberOfBitsUsedMod8 == 0 ) + * ( data + ( numberOfBitsUsed >> 3 ) ) = dataByte; + else + { + // Copy over the new data. + *( data + ( numberOfBitsUsed >> 3 ) ) |= dataByte >> ( numberOfBitsUsedMod8 ); // First half + + if ( 8 - ( numberOfBitsUsedMod8 ) < 8 && 8 - ( numberOfBitsUsedMod8 ) < numberOfBitsToWrite ) // If we didn't write it all out in the first half (8 - (numberOfBitsUsed%8) is the number we wrote in the first half) + { + *( data + ( numberOfBitsUsed >> 3 ) + 1 ) = (unsigned char) ( dataByte << ( 8 - ( numberOfBitsUsedMod8 ) ) ); // Second half (overlaps byte boundary) + } + } + + if ( numberOfBitsToWrite >= 8 ) + { + numberOfBitsUsed += 8; + numberOfBitsToWrite -= 8; + } + else + { + numberOfBitsUsed += numberOfBitsToWrite; + numberOfBitsToWrite=0; + } + } + // } while(numberOfBitsToWrite>0); +} + +// Set the stream to some initial data. For internal use +void BitStream::SetData( unsigned char *inByteArray ) +{ + data=inByteArray; + copyData=false; +} + +// Assume the input source points to a native type, compress and write it +void BitStream::WriteCompressed( const unsigned char* inByteArray, + const unsigned int size, const bool unsignedData ) +{ + BitSize_t currentByte = ( size >> 3 ) - 1; // PCs + + unsigned char byteMatch; + + if ( unsignedData ) + { + byteMatch = 0; + } + + else + { + byteMatch = 0xFF; + } + + // Write upper bytes with a single 1 + // From high byte to low byte, if high byte is a byteMatch then write a 1 bit. Otherwise write a 0 bit and then write the remaining bytes + while ( currentByte > 0 ) + { + if ( inByteArray[ currentByte ] == byteMatch ) // If high byte is byteMatch (0 of 0xff) then it would have the same value shifted + { + bool b = true; + Write( b ); + } + else + { + // Write the remainder of the data after writing 0 + bool b = false; + Write( b ); + + WriteBits( inByteArray, ( currentByte + 1 ) << 3, true ); + // currentByte--; + + + return ; + } + + currentByte--; + } + + // If the upper half of the last byte is a 0 (positive) or 16 (negative) then write a 1 and the remaining 4 bits. Otherwise write a 0 and the 8 bites. + if ( ( unsignedData && ( ( *( inByteArray + currentByte ) ) & 0xF0 ) == 0x00 ) || + ( unsignedData == false && ( ( *( inByteArray + currentByte ) ) & 0xF0 ) == 0xF0 ) ) + { + bool b = true; + Write( b ); + WriteBits( inByteArray + currentByte, 4, true ); + } + + else + { + bool b = false; + Write( b ); + WriteBits( inByteArray + currentByte, 8, true ); + } +} + +// Read numberOfBitsToRead bits to the output source +// alignBitsToRight should be set to true to convert internal bitstream data to userdata +// It should be false if you used WriteBits with rightAlignedBits false +bool BitStream::ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsToRead, const bool alignBitsToRight ) +{ +#ifdef _DEBUG + // OVR_ASSERT( numberOfBitsToRead > 0 ); +#endif + if (numberOfBitsToRead<=0) + return false; + + if ( readOffset + numberOfBitsToRead > numberOfBitsUsed ) + return false; + + + const BitSize_t readOffsetMod8 = readOffset & 7; + + // If currently aligned and numberOfBits is a multiple of 8, just memcpy for speed + if (readOffsetMod8==0 && (numberOfBitsToRead&7)==0) + { + memcpy( inOutByteArray, data + ( readOffset >> 3 ), numberOfBitsToRead>>3); + readOffset+=numberOfBitsToRead; + return true; + } + + + + BitSize_t offset = 0; + + memset( inOutByteArray, 0, (size_t) BITS_TO_BYTES( numberOfBitsToRead ) ); + + while ( numberOfBitsToRead > 0 ) + { + *( inOutByteArray + offset ) |= *( data + ( readOffset >> 3 ) ) << ( readOffsetMod8 ); // First half + + if ( readOffsetMod8 > 0 && numberOfBitsToRead > 8 - ( readOffsetMod8 ) ) // If we have a second half, we didn't read enough bytes in the first half + *( inOutByteArray + offset ) |= *( data + ( readOffset >> 3 ) + 1 ) >> ( 8 - ( readOffsetMod8 ) ); // Second half (overlaps byte boundary) + + if (numberOfBitsToRead>=8) + { + numberOfBitsToRead -= 8; + readOffset += 8; + offset++; + } + else + { + int neg = (int) numberOfBitsToRead - 8; + + if ( neg < 0 ) // Reading a partial byte for the last byte, shift right so the data is aligned on the right + { + + if ( alignBitsToRight ) + * ( inOutByteArray + offset ) >>= -neg; + + readOffset += 8 + neg; + } + else + readOffset += 8; + + offset++; + + numberOfBitsToRead=0; + } + } + + return true; +} + +// Assume the input source points to a compressed native type. Decompress and read it +bool BitStream::ReadCompressed( unsigned char* inOutByteArray, + const unsigned int size, const bool unsignedData ) +{ + unsigned int currentByte = ( size >> 3 ) - 1; + + + unsigned char byteMatch, halfByteMatch; + + if ( unsignedData ) + { + byteMatch = 0; + halfByteMatch = 0; + } + + else + { + byteMatch = 0xFF; + halfByteMatch = 0xF0; + } + + // Upper bytes are specified with a single 1 if they match byteMatch + // From high byte to low byte, if high byte is a byteMatch then write a 1 bit. Otherwise write a 0 bit and then write the remaining bytes + while ( currentByte > 0 ) + { + // If we read a 1 then the data is byteMatch. + + bool b; + + if ( Read( b ) == false ) + return false; + + if ( b ) // Check that bit + { + inOutByteArray[ currentByte ] = byteMatch; + currentByte--; + } + else + { + // Read the rest of the bytes + + if ( ReadBits( inOutByteArray, ( currentByte + 1 ) << 3 ) == false ) + return false; + + return true; + } + } + + // All but the first bytes are byteMatch. If the upper half of the last byte is a 0 (positive) or 16 (negative) then what we read will be a 1 and the remaining 4 bits. + // Otherwise we read a 0 and the 8 bytes + //OVR_ASSERT(readOffset+1 <=numberOfBitsUsed); // If this assert is hit the stream wasn't long enough to read from + if ( readOffset + 1 > numberOfBitsUsed ) + return false; + + bool b=false; + + if ( Read( b ) == false ) + return false; + + if ( b ) // Check that bit + { + + if ( ReadBits( inOutByteArray + currentByte, 4 ) == false ) + return false; + + inOutByteArray[ currentByte ] |= halfByteMatch; // We have to set the high 4 bits since these are set to 0 by ReadBits + } + else + { + if ( ReadBits( inOutByteArray + currentByte, 8 ) == false ) + return false; + } + + return true; +} + +// Reallocates (if necessary) in preparation of writing numberOfBitsToWrite +void BitStream::AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite ) +{ + BitSize_t newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed; + + if ( numberOfBitsToWrite + numberOfBitsUsed > 0 && ( ( numberOfBitsAllocated - 1 ) >> 3 ) < ( ( newNumberOfBitsAllocated - 1 ) >> 3 ) ) // If we need to allocate 1 or more new bytes + { +#ifdef _DEBUG + // If this assert hits then we need to specify true for the third parameter in the constructor + // It needs to reallocate to hold all the data and can't do it unless we allocated to begin with + // Often hits if you call Write or Serialize on a read-only bitstream + OVR_ASSERT( copyData == true ); +#endif + + // Less memory efficient but saves on news and deletes + /// Cap to 1 meg buffer to save on huge allocations + newNumberOfBitsAllocated = ( numberOfBitsToWrite + numberOfBitsUsed ) * 2; + if (newNumberOfBitsAllocated - ( numberOfBitsToWrite + numberOfBitsUsed ) > 1048576 ) + newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed + 1048576; + + // BitSize_t newByteOffset = BITS_TO_BYTES( numberOfBitsAllocated ); + // Use realloc and free so we are more efficient than delete and new for resizing + BitSize_t amountToAllocate = BITS_TO_BYTES( newNumberOfBitsAllocated ); + if (data==(unsigned char*)stackData) + { + if (amountToAllocate > BITSTREAM_STACK_ALLOCATION_SIZE) + { + data = ( unsigned char* ) OVR_ALLOC( (size_t) amountToAllocate); + OVR_ASSERT(data); + if (data) + { + // need to copy the stack data over to our new memory area too + memcpy ((void *)data, (void *)stackData, (size_t) BITS_TO_BYTES( numberOfBitsAllocated )); + } + } + } + else + { + data = ( unsigned char* ) OVR_REALLOC( data, (size_t) amountToAllocate); + } + +#ifdef _DEBUG + OVR_ASSERT( data ); // Make sure realloc succeeded +#endif + // memset(data+newByteOffset, 0, ((newNumberOfBitsAllocated-1)>>3) - ((numberOfBitsAllocated-1)>>3)); // Set the new data block to 0 + } + + if ( newNumberOfBitsAllocated > numberOfBitsAllocated ) + numberOfBitsAllocated = newNumberOfBitsAllocated; +} +BitSize_t BitStream::GetNumberOfBitsAllocated(void) const +{ + return numberOfBitsAllocated; +} +void BitStream::PadWithZeroToByteLength( unsigned int bytes ) +{ + if (GetNumberOfBytesUsed() < bytes) + { + AlignWriteToByteBoundary(); + unsigned int numToWrite = bytes - GetNumberOfBytesUsed(); + AddBitsAndReallocate( BYTES_TO_BITS(numToWrite) ); + memset(data+BITS_TO_BYTES(numberOfBitsUsed), 0, (size_t) numToWrite); + numberOfBitsUsed+=BYTES_TO_BITS(numToWrite); + } +} + +/* +// Julius Goryavsky's version of Harley's algorithm. +// 17 elementary ops plus an indexed load, if the machine +// has "and not." + +int nlz10b(unsigned x) { + + static char table[64] = + {32,20,19, u, u,18, u, 7, 10,17, u, u,14, u, 6, u, + u, 9, u,16, u, u, 1,26, u,13, u, u,24, 5, u, u, + u,21, u, 8,11, u,15, u, u, u, u, 2,27, 0,25, u, + 22, u,12, u, u, 3,28, u, 23, u, 4,29, u, u,30,31}; + + x = x | (x >> 1); // Propagate leftmost + x = x | (x >> 2); // 1-bit to the right. + x = x | (x >> 4); + x = x | (x >> 8); + x = x & ~(x >> 16); + x = x*0xFD7049FF; // Activate this line or the following 3. +// x = (x << 9) - x; // Multiply by 511. +// x = (x << 11) - x; // Multiply by 2047. +// x = (x << 14) - x; // Multiply by 16383. + return table[x >> 26]; +} +*/ +int BitStream::NumberOfLeadingZeroes( int8_t x ) {return NumberOfLeadingZeroes((uint8_t)x);} +int BitStream::NumberOfLeadingZeroes( uint8_t x ) +{ + uint8_t y; + int n; + + n = 8; + y = x >> 4; if (y != 0) {n = n - 4; x = y;} + y = x >> 2; if (y != 0) {n = n - 2; x = y;} + y = x >> 1; if (y != 0) return n - 2; + return (int)(n - x); +} +int BitStream::NumberOfLeadingZeroes( int16_t x ) {return NumberOfLeadingZeroes((uint16_t)x);} +int BitStream::NumberOfLeadingZeroes( uint16_t x ) +{ + uint16_t y; + int n; + + n = 16; + y = x >> 8; if (y != 0) {n = n - 8; x = y;} + y = x >> 4; if (y != 0) {n = n - 4; x = y;} + y = x >> 2; if (y != 0) {n = n - 2; x = y;} + y = x >> 1; if (y != 0) return n - 2; + return (int)(n - x); +} +int BitStream::NumberOfLeadingZeroes( int32_t x ) {return NumberOfLeadingZeroes((uint32_t)x);} +int BitStream::NumberOfLeadingZeroes( uint32_t x ) +{ + uint32_t y; + int n; + + n = 32; + y = x >>16; if (y != 0) {n = n -16; x = y;} + y = x >> 8; if (y != 0) {n = n - 8; x = y;} + y = x >> 4; if (y != 0) {n = n - 4; x = y;} + y = x >> 2; if (y != 0) {n = n - 2; x = y;} + y = x >> 1; if (y != 0) return n - 2; + return (int)(n - x); +} +int BitStream::NumberOfLeadingZeroes( int64_t x ) {return NumberOfLeadingZeroes((uint64_t)x);} +int BitStream::NumberOfLeadingZeroes( uint64_t x ) +{ + uint64_t y; + int n; + + n = 64; + y = x >>32; if (y != 0) {n = n -32; x = y;} + y = x >>16; if (y != 0) {n = n -16; x = y;} + y = x >> 8; if (y != 0) {n = n - 8; x = y;} + y = x >> 4; if (y != 0) {n = n - 4; x = y;} + y = x >> 2; if (y != 0) {n = n - 2; x = y;} + y = x >> 1; if (y != 0) return n - 2; + return (int)(n - x); +} + +// Should hit if reads didn't match writes +void BitStream::AssertStreamEmpty( void ) +{ + OVR_ASSERT( readOffset == numberOfBitsUsed ); +} +void BitStream::PrintBits( char *out ) const +{ + if ( numberOfBitsUsed <= 0 ) + { + OVR_strcpy(out, 128, "No bits\n" ); + return; + } + + unsigned int strIndex=0; + for ( BitSize_t counter = 0; counter < BITS_TO_BYTES( numberOfBitsUsed ) && strIndex < 2000 ; counter++ ) + { + BitSize_t stop; + + if ( counter == ( numberOfBitsUsed - 1 ) >> 3 ) + stop = 8 - ( ( ( numberOfBitsUsed - 1 ) & 7 ) + 1 ); + else + stop = 0; + + for ( BitSize_t counter2 = 7; counter2 >= stop; counter2-- ) + { + if ( ( data[ counter ] >> counter2 ) & 1 ) + out[strIndex++]='1'; + else + out[strIndex++]='0'; + + if (counter2==0) + break; + } + + out[strIndex++]=' '; + } + + out[strIndex++]='\n'; + + out[strIndex++]=0; +} +void BitStream::PrintBits( void ) const +{ + char out[2048]; + PrintBits(out); + printf("%s", out); +} +void BitStream::PrintHex( char *out ) const +{ + BitSize_t i; + for ( i=0; i < GetNumberOfBytesUsed(); i++) + { + OVR_sprintf(out+i*3, 128, "%02x ", data[i]); + } +} +void BitStream::PrintHex( void ) const +{ + char out[2048]; + PrintHex(out); + printf("%s", out); +} + +// Exposes the data for you to look at, like PrintBits does. +// Data will point to the stream. Returns the length in bits of the stream. +BitSize_t BitStream::CopyData( unsigned char** _data ) const +{ +#ifdef _DEBUG + OVR_ASSERT( numberOfBitsUsed > 0 ); +#endif + + *_data = (unsigned char*) OVR_ALLOC( (size_t) BITS_TO_BYTES( numberOfBitsUsed )); + memcpy( *_data, data, sizeof(unsigned char) * (size_t) ( BITS_TO_BYTES( numberOfBitsUsed ) ) ); + return numberOfBitsUsed; +} + +// Ignore data we don't intend to read +void BitStream::IgnoreBits( const BitSize_t numberOfBits ) +{ + readOffset += numberOfBits; +} + +void BitStream::IgnoreBytes( const unsigned int numberOfBytes ) +{ + IgnoreBits(BYTES_TO_BITS(numberOfBytes)); +} + +// Move the write pointer to a position on the array. Dangerous if you don't know what you are doing! +// Doesn't work with non-aligned data! +void BitStream::SetWriteOffset( const BitSize_t offset ) +{ + numberOfBitsUsed = offset; +} + +/* +BitSize_t BitStream::GetWriteOffset( void ) const +{ +return numberOfBitsUsed; +} + +// Returns the length in bits of the stream +BitSize_t BitStream::GetNumberOfBitsUsed( void ) const +{ +return GetWriteOffset(); +} + +// Returns the length in bytes of the stream +BitSize_t BitStream::GetNumberOfBytesUsed( void ) const +{ +return BITS_TO_BYTES( numberOfBitsUsed ); +} + +// Returns the number of bits into the stream that we have read +BitSize_t BitStream::GetReadOffset( void ) const +{ +return readOffset; +} + + +// Sets the read bit index +void BitStream::SetReadOffset( const BitSize_t newReadOffset ) +{ +readOffset=newReadOffset; +} + +// Returns the number of bits left in the stream that haven't been read +BitSize_t BitStream::GetNumberOfUnreadBits( void ) const +{ +return numberOfBitsUsed - readOffset; +} +// Exposes the internal data +unsigned char* BitStream::GetData( void ) const +{ +return data; +} + +*/ +// If we used the constructor version with copy data off, this makes sure it is set to on and the data pointed to is copied. +void BitStream::AssertCopyData( void ) +{ + if ( copyData == false ) + { + copyData = true; + + if ( numberOfBitsAllocated > 0 ) + { + unsigned char * newdata = ( unsigned char* ) OVR_ALLOC( (size_t) BITS_TO_BYTES( numberOfBitsAllocated )); +#ifdef _DEBUG + + OVR_ASSERT( data ); +#endif + + memcpy( newdata, data, (size_t) BITS_TO_BYTES( numberOfBitsAllocated ) ); + data = newdata; + } + + else + data = 0; + } +} +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 +} +void BitStream::ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length) +{ + for (BitSize_t i=0; i < length; i++) + inOutByteArray[i]=inByteArray[length-i-1]; +} +void BitStream::ReverseBytesInPlace(unsigned char *inOutData,const unsigned int length) +{ + unsigned char temp; + BitSize_t i; + for (i=0; i < (length>>1); i++) + { + temp = inOutData[i]; + inOutData[i]=inOutData[length-i-1]; + inOutData[length-i-1]=temp; + } +} + +void BitStream::WriteAlignedVar8(const char *inByteArray) +{ + OVR_ASSERT((numberOfBitsUsed&7)==0); + AddBitsAndReallocate(1*8); + data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[0]; + numberOfBitsUsed+=1*8; +} +bool BitStream::ReadAlignedVar8(char *inOutByteArray) +{ + OVR_ASSERT((readOffset&7)==0); + if ( readOffset + 1*8 > numberOfBitsUsed ) + return false; + + inOutByteArray[0] = data[( readOffset >> 3 ) + 0]; + readOffset+=1*8; + return true; +} +void BitStream::WriteAlignedVar16(const char *inByteArray) +{ + OVR_ASSERT((numberOfBitsUsed&7)==0); + AddBitsAndReallocate(2*8); +#ifndef __BITSTREAM_NATIVE_END + if (DoEndianSwap()) + { + data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[1]; + data[( numberOfBitsUsed >> 3 ) + 1] = inByteArray[0]; + } + else +#endif + { + data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[0]; + data[( numberOfBitsUsed >> 3 ) + 1] = inByteArray[1]; + } + + numberOfBitsUsed+=2*8; +} +bool BitStream::ReadAlignedVar16(char *inOutByteArray) +{ + OVR_ASSERT((readOffset&7)==0); + if ( readOffset + 2*8 > numberOfBitsUsed ) + return false; +#ifndef __BITSTREAM_NATIVE_END + if (DoEndianSwap()) + { + inOutByteArray[0] = data[( readOffset >> 3 ) + 1]; + inOutByteArray[1] = data[( readOffset >> 3 ) + 0]; + } + else +#endif + { + inOutByteArray[0] = data[( readOffset >> 3 ) + 0]; + inOutByteArray[1] = data[( readOffset >> 3 ) + 1]; + } + + readOffset+=2*8; + return true; +} +void BitStream::WriteAlignedVar32(const char *inByteArray) +{ + OVR_ASSERT((numberOfBitsUsed&7)==0); + AddBitsAndReallocate(4*8); +#ifndef __BITSTREAM_NATIVE_END + if (DoEndianSwap()) + { + data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[3]; + data[( numberOfBitsUsed >> 3 ) + 1] = inByteArray[2]; + data[( numberOfBitsUsed >> 3 ) + 2] = inByteArray[1]; + data[( numberOfBitsUsed >> 3 ) + 3] = inByteArray[0]; + } + else +#endif + { + data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[0]; + data[( numberOfBitsUsed >> 3 ) + 1] = inByteArray[1]; + data[( numberOfBitsUsed >> 3 ) + 2] = inByteArray[2]; + data[( numberOfBitsUsed >> 3 ) + 3] = inByteArray[3]; + } + + numberOfBitsUsed+=4*8; +} +bool BitStream::ReadAlignedVar32(char *inOutByteArray) +{ + OVR_ASSERT((readOffset&7)==0); + if ( readOffset + 4*8 > numberOfBitsUsed ) + return false; +#ifndef __BITSTREAM_NATIVE_END + if (DoEndianSwap()) + { + inOutByteArray[0] = data[( readOffset >> 3 ) + 3]; + inOutByteArray[1] = data[( readOffset >> 3 ) + 2]; + inOutByteArray[2] = data[( readOffset >> 3 ) + 1]; + inOutByteArray[3] = data[( readOffset >> 3 ) + 0]; + } + else +#endif + { + inOutByteArray[0] = data[( readOffset >> 3 ) + 0]; + inOutByteArray[1] = data[( readOffset >> 3 ) + 1]; + inOutByteArray[2] = data[( readOffset >> 3 ) + 2]; + inOutByteArray[3] = data[( readOffset >> 3 ) + 3]; + } + + readOffset+=4*8; + return true; +} +bool BitStream::ReadFloat16( float &outFloat, float floatMin, float floatMax ) +{ + uint16_t percentile; + if (Read(percentile)) + { + OVR_ASSERT(floatMax>floatMin); + outFloat = floatMin + ((float) percentile / 65535.0f) * (floatMax-floatMin); + if (outFloatfloatMax) + outFloat=floatMax; + return true; + } + return false; +} +bool BitStream::SerializeFloat16(bool writeToBitstream, float &inOutFloat, float floatMin, float floatMax) +{ + if (writeToBitstream) + WriteFloat16(inOutFloat, floatMin, floatMax); + else + return ReadFloat16(inOutFloat, floatMin, floatMax); + return true; +} +void BitStream::WriteFloat16( float inOutFloat, float floatMin, float floatMax ) +{ + OVR_ASSERT(floatMax>floatMin); + if (inOutFloat>floatMax+.001) + { + OVR_ASSERT(inOutFloat<=floatMax+.001); + } + if (inOutFloat=floatMin-.001); + } + float percentile=65535.0f * (inOutFloat-floatMin)/(floatMax-floatMin); + if (percentile<0.0) + percentile=0.0; + if (percentile>65535.0f) + percentile=65535.0f; + Write((uint16_t)percentile); +} + + +}} // OVR::Net diff --git a/LibOVR/Src/Net/OVR_BitStream.h b/LibOVR/Src/Net/OVR_BitStream.h new file mode 100644 index 0000000..b1ddc8f --- /dev/null +++ b/LibOVR/Src/Net/OVR_BitStream.h @@ -0,0 +1,1744 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_BitStream.h +Content : A generic serialization toolkit for packing data to a binary stream. +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_Bitstream_h +#define OVR_Bitstream_h + +#include +#include "../Kernel/OVR_Types.h" +#include "../Kernel/OVR_Std.h" +#include "../Kernel/OVR_String.h" + +namespace OVR { namespace Net { + +typedef uint32_t BitSize_t; +#define BITSTREAM_STACK_ALLOCATION_SIZE 256 +#define BITS_TO_BYTES(x) (((x)+7)>>3) +#define BYTES_TO_BITS(x) ((x)<<3) + + +//----------------------------------------------------------------------------- +// BitStream + +// Generic serialization class to binary stream +class BitStream : public NewOverrideBase +{ +public: + /// Default Constructor + BitStream(); + + /// \brief Create the bitstream, with some number of bytes to immediately allocate. + /// \details There is no benefit to calling this, unless you know exactly how many bytes you need and it is greater than BITSTREAM_STACK_ALLOCATION_SIZE. + /// In that case all it does is save you one or more realloc calls. + /// \param[in] initialBytesToAllocate the number of bytes to pre-allocate. + BitStream( const unsigned int initialBytesToAllocate ); + + /// \brief Initialize the BitStream, immediately setting the data it contains to a predefined pointer. + /// \details Set \a _copyData to true if you want to make an internal copy of the data you are passing. Set it to false to just save a pointer to the data. + /// You shouldn't call Write functions with \a _copyData as false, as this will write to unallocated memory + /// 99% of the time you will use this function to cast Packet::data to a bitstream for reading, in which case you should write something as follows: + /// \code + /// RakNet::BitStream bs(packet->data, packet->length, false); + /// \endcode + /// \param[in] _data An array of bytes. + /// \param[in] lengthInBytes Size of the \a _data. + /// \param[in] _copyData true or false to make a copy of \a _data or not. + BitStream( char* _data, const unsigned int lengthInBytes, bool _copyData ); + + // Destructor + ~BitStream(); + +public: + /// Resets the bitstream for reuse. + void Reset( void ); + + /// \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 + /// \param[in] inOutTemplateVar The value to write + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + template + bool Serialize(bool writeToBitstream, templateType &inOutTemplateVar); + + /// \brief Bidirectional serialize/deserialize any integral type to/from a bitstream. + /// \details If the current value is different from the last value + /// the current value will be written. Otherwise, a single bit will be written + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] inOutCurrentValue The current value to write + /// \param[in] lastValue The last value to compare against. Only used if \a writeToBitstream is true. + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + template + bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue); + + /// \brief Bidirectional version of SerializeDelta when you don't know what the last value is, or there is no last value. + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] inOutCurrentValue The current value to write + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + template + bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue); + + /// \brief Bidirectional serialize/deserialize any integral type to/from a bitstream. + /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping. + /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte + /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. + /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] inOutTemplateVar The value to write + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + template + bool SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar); + + /// \brief Bidirectional serialize/deserialize any integral type to/from a bitstream. + /// \details If the current value is different from the last value + /// the current value will be written. Otherwise, a single bit will be written + /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. + /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type + /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] inOutCurrentValue The current value to write + /// \param[in] lastValue The last value to compare against. Only used if \a writeToBitstream is true. + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + template + bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue); + + /// \brief Save as SerializeCompressedDelta(templateType ¤tValue, const templateType &lastValue) when we have an unknown second parameter + /// \return true on data read. False on insufficient data in bitstream + template + bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutTemplateVar); + + /// \brief Bidirectional serialize/deserialize an array or casted stream or raw data. This does NOT do 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 + /// \param[in] inOutByteArray a byte buffer + /// \param[in] numberOfBytes the size of \a input in bytes + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + bool Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes ); + + /// \brief Serialize a float into 2 bytes, spanning the range between \a floatMin and \a floatMax + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] inOutFloat The float to write + /// \param[in] floatMin Predetermined minimum value of f + /// \param[in] floatMax Predetermined maximum value of f + bool SerializeFloat16(bool writeToBitstream, float &inOutFloat, float floatMin, float floatMax); + + /// Serialize one type casted to another (smaller) type, to save bandwidth + /// serializationType should be uint8_t, uint16_t, uint24_t, or uint32_t + /// Example: int num=53; SerializeCasted(true, num); would use 1 byte to write what would otherwise be an integer (4 or 8 bytes) + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] value The value to serialize + template + bool SerializeCasted( bool writeToBitstream, sourceType &value ); + + /// Given the minimum and maximum values for an integer type, figure out the minimum number of bits to represent the range + /// Then serialize only those bits + /// \note A static is used so that the required number of bits for (maximum-minimum) is only calculated once. This does require that \a minimum and \maximum are fixed values for a given line of code for the life of the program + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] value Integer value to write, which should be between \a minimum and \a maximum + /// \param[in] minimum Minimum value of \a value + /// \param[in] maximum Maximum value of \a value + /// \param[in] allowOutsideRange If true, all sends will take an extra bit, however value can deviate from outside \a minimum and \a maximum. If false, will assert if the value deviates + template + bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false ); + /// \param[in] requiredBits Primarily for internal use, called from above function() after calculating number of bits needed to represent maximum-minimum + template + bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false ); + + /// \brief Bidirectional serialize/deserialize a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12-24 bytes. + /// \details Will further compress y or z axis aligned vectors. + /// Accurate to 1/32767.5. + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + template // templateType for this function must be a float or double + bool SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z ); + + /// \brief Bidirectional serialize/deserialize a vector, using 10 bytes instead of 12. + /// \details Loses accuracy to about 3/10ths and only saves 2 bytes, so only use if accuracy is not important. + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + template // templateType for this function must be a float or double + bool SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z ); + + /// \brief Bidirectional serialize/deserialize a normalized quaternion in 6 bytes + 4 bits instead of 16 bytes. Slightly lossy. + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] w w + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + template // templateType for this function must be a float or double + bool SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z); + + /// \brief Bidirectional serialize/deserialize an orthogonal matrix by creating a quaternion, and writing 3 components of the quaternion in 2 bytes each. + /// \details Use 6 bytes instead of 36 + /// Lossy, although the result is renormalized + /// \return true on success, false on failure. + template // templateType for this function must be a float or double + bool SerializeOrthMatrix( + bool writeToBitstream, + templateType &m00, templateType &m01, templateType &m02, + templateType &m10, templateType &m11, templateType &m12, + templateType &m20, templateType &m21, templateType &m22 ); + + /// \brief Bidirectional serialize/deserialize numberToSerialize bits to/from the input. + /// \details Right aligned data means in the case of a partial byte, the bits are aligned + /// from the right (bit 0) rather than the left (as in the normal + /// internal representation) You would set this to true when + /// writing user data, and false when copying bitstream data, such + /// as writing one bitstream to another + /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data + /// \param[in] inOutByteArray The data + /// \param[in] numberOfBitsToSerialize The number of bits to write + /// \param[in] rightAlignedBits if true data will be right aligned + /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful. + bool SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits = true ); + + /// \brief Write any integral type to a bitstream. + /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping. + /// \param[in] inTemplateVar The value to write + template + void Write(const templateType &inTemplateVar); + + /// \brief Write the dereferenced pointer to any integral type to a bitstream. + /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping. + /// \param[in] inTemplateVar The value to write + template + void WritePtr(templateType *inTemplateVar); + + /// \brief Write any integral type to a bitstream. + /// \details If the current value is different from the last value + /// the current value will be written. Otherwise, a single bit will be written + /// \param[in] currentValue The current value to write + /// \param[in] lastValue The last value to compare against + template + void WriteDelta(const templateType ¤tValue, const templateType &lastValue); + + /// \brief WriteDelta when you don't know what the last value is, or there is no last value. + /// \param[in] currentValue The current value to write + template + void WriteDelta(const templateType ¤tValue); + + /// \brief Write any integral type to a bitstream. + /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping. + /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte + /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. + /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type + /// \param[in] inTemplateVar The value to write + template + void WriteCompressed(const templateType &inTemplateVar); + + /// \brief Write any integral type to a bitstream. + /// \details If the current value is different from the last value + /// the current value will be written. Otherwise, a single bit will be written + /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. + /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type + /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte + /// \param[in] currentValue The current value to write + /// \param[in] lastValue The last value to compare against + template + void WriteCompressedDelta(const templateType ¤tValue, const templateType &lastValue); + + /// \brief Save as WriteCompressedDelta(const templateType ¤tValue, const templateType &lastValue) when we have an unknown second parameter + template + void WriteCompressedDelta(const templateType ¤tValue); + + /// \brief Read any integral type from a bitstream. + /// \details Define __BITSTREAM_NATIVE_END if you need endian swapping. + /// \param[in] outTemplateVar The value to read + /// \return true on success, false on failure. + template + bool Read(templateType &outTemplateVar); + + /// \brief Read any integral type from a bitstream. + /// \details If the written value differed from the value compared against in the write function, + /// var will be updated. Otherwise it will retain the current value. + /// ReadDelta is only valid from a previous call to WriteDelta + /// \param[in] outTemplateVar The value to read + /// \return true on success, false on failure. + template + bool ReadDelta(templateType &outTemplateVar); + + /// \brief Read any integral type from a bitstream. + /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping. + /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. + /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type + /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte + /// \param[in] outTemplateVar The value to read + /// \return true on success, false on failure. + template + bool ReadCompressed(templateType &outTemplateVar); + + /// \brief Read any integral type from a bitstream. + /// \details If the written value differed from the value compared against in the write function, + /// var will be updated. Otherwise it will retain the current value. + /// the current value will be updated. + /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. + /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type + /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte + /// ReadCompressedDelta is only valid from a previous call to WriteDelta + /// \param[in] outTemplateVar The value to read + /// \return true on success, false on failure. + template + bool ReadCompressedDelta(templateType &outTemplateVar); + + /// \brief Read one bitstream to another. + /// \param[in] numberOfBits bits to read + /// \param bitStream the bitstream to read into from + /// \return true on success, false on failure. + bool Read( BitStream *bitStream, BitSize_t numberOfBits ); + bool Read( BitStream *bitStream ); + bool Read( BitStream &bitStream, BitSize_t numberOfBits ); + bool Read( BitStream &bitStream ); + + /// \brief Write an array or casted stream or raw data. This does NOT do endian swapping. + /// \param[in] inputByteArray a byte buffer + /// \param[in] numberOfBytes the size of \a input in bytes + void Write( const char* inputByteArray, const unsigned int numberOfBytes ); + + /// \brief Write one bitstream to another. + /// \param[in] numberOfBits bits to write + /// \param bitStream the bitstream to copy from + void Write( BitStream *bitStream, BitSize_t numberOfBits ); + void Write( BitStream *bitStream ); + void Write( BitStream &bitStream, BitSize_t numberOfBits ); + void Write( BitStream &bitStream );\ + + /// \brief Write a float into 2 bytes, spanning the range between \a floatMin and \a floatMax + /// \param[in] x The float to write + /// \param[in] floatMin Predetermined minimum value of f + /// \param[in] floatMax Predetermined maximum value of f + void WriteFloat16( float x, float floatMin, float floatMax ); + + /// Write one type serialized as another (smaller) type, to save bandwidth + /// serializationType should be uint8_t, uint16_t, uint24_t, or uint32_t + /// Example: int num=53; WriteCasted(num); would use 1 byte to write what would otherwise be an integer (4 or 8 bytes) + /// \param[in] value The value to write + template + void WriteCasted( const sourceType &value ); + + /// Given the minimum and maximum values for an integer type, figure out the minimum number of bits to represent the range + /// Then write only those bits + /// \note A static is used so that the required number of bits for (maximum-minimum) is only calculated once. This does require that \a minimum and \maximum are fixed values for a given line of code for the life of the program + /// \param[in] value Integer value to write, which should be between \a minimum and \a maximum + /// \param[in] minimum Minimum value of \a value + /// \param[in] maximum Maximum value of \a value + /// \param[in] allowOutsideRange If true, all sends will take an extra bit, however value can deviate from outside \a minimum and \a maximum. If false, will assert if the value deviates. This should match the corresponding value passed to Read(). + template + void WriteBitsFromIntegerRange( const templateType value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false ); + /// \param[in] requiredBits Primarily for internal use, called from above function() after calculating number of bits needed to represent maximum-minimum + template + void WriteBitsFromIntegerRange( const templateType value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false ); + + /// \brief Write a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12-24 bytes. + /// \details Will further compress y or z axis aligned vectors. + /// Accurate to 1/32767.5. + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + template // templateType for this function must be a float or double + void WriteNormVector( templateType x, templateType y, templateType z ); + + /// \brief Write a vector, using 10 bytes instead of 12. + /// \details Loses accuracy to about 3/10ths and only saves 2 bytes, + /// so only use if accuracy is not important. + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + template // templateType for this function must be a float or double + void WriteVector( templateType x, templateType y, templateType z ); + + /// \brief Write a normalized quaternion in 6 bytes + 4 bits instead of 16 bytes. Slightly lossy. + /// \param[in] w w + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + template // templateType for this function must be a float or double + void WriteNormQuat( templateType w, templateType x, templateType y, templateType z); + + /// \brief Write an orthogonal matrix by creating a quaternion, and writing 3 components of the quaternion in 2 bytes each. + /// \details Use 6 bytes instead of 36 + /// Lossy, although the result is renormalized + template // templateType for this function must be a float or double + void WriteOrthMatrix( + templateType m00, templateType m01, templateType m02, + templateType m10, templateType m11, templateType m12, + templateType m20, templateType m21, templateType m22 ); + + /// \brief Read an array or casted stream of byte. + /// \details The array is raw data. There is no automatic endian conversion with this function + /// \param[in] output The result byte array. It should be larger than @em numberOfBytes. + /// \param[in] numberOfBytes The number of byte to read + /// \return true on success false if there is some missing bytes. + bool Read( char* output, const unsigned int numberOfBytes ); + + /// \brief Read a float into 2 bytes, spanning the range between \a floatMin and \a floatMax + /// \param[in] outFloat The float to read + /// \param[in] floatMin Predetermined minimum value of f + /// \param[in] floatMax Predetermined maximum value of f + bool ReadFloat16( float &outFloat, float floatMin, float floatMax ); + + /// Read one type serialized to another (smaller) type, to save bandwidth + /// serializationType should be uint8_t, uint16_t, uint24_t, or uint32_t + /// Example: int num; ReadCasted(num); would read 1 bytefrom the stream, and put the value in an integer + /// \param[in] value The value to write + template + bool ReadCasted( sourceType &value ); + + /// Given the minimum and maximum values for an integer type, figure out the minimum number of bits to represent the range + /// Then read only those bits + /// \note A static is used so that the required number of bits for (maximum-minimum) is only calculated once. This does require that \a minimum and \maximum are fixed values for a given line of code for the life of the program + /// \param[in] value Integer value to read, which should be between \a minimum and \a maximum + /// \param[in] minimum Minimum value of \a value + /// \param[in] maximum Maximum value of \a value + /// \param[in] allowOutsideRange If true, all sends will take an extra bit, however value can deviate from outside \a minimum and \a maximum. If false, will assert if the value deviates. This should match the corresponding value passed to Write(). + template + bool ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false ); + /// \param[in] requiredBits Primarily for internal use, called from above function() after calculating number of bits needed to represent maximum-minimum + template + bool ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false ); + + /// \brief Read a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12-24 bytes. + /// \details Will further compress y or z axis aligned vectors. + /// Accurate to 1/32767.5. + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + /// \return true on success, false on failure. + template // templateType for this function must be a float or double + bool ReadNormVector( templateType &x, templateType &y, templateType &z ); + + /// \brief Read 3 floats or doubles, using 10 bytes, where those float or doubles comprise a vector. + /// \details Loses accuracy to about 3/10ths and only saves 2 bytes, + /// so only use if accuracy is not important. + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + /// \return true on success, false on failure. + template // templateType for this function must be a float or double + bool ReadVector( templateType &x, templateType &y, templateType &z ); + + /// \brief Read a normalized quaternion in 6 bytes + 4 bits instead of 16 bytes. + /// \param[in] w w + /// \param[in] x x + /// \param[in] y y + /// \param[in] z z + /// \return true on success, false on failure. + template // templateType for this function must be a float or double + bool ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z); + + /// \brief Read an orthogonal matrix from a quaternion, reading 3 components of the quaternion in 2 bytes each and extrapolatig the 4th. + /// \details Use 6 bytes instead of 36 + /// Lossy, although the result is renormalized + /// \return true on success, false on failure. + template // templateType for this function must be a float or double + bool ReadOrthMatrix( + templateType &m00, templateType &m01, templateType &m02, + templateType &m10, templateType &m11, templateType &m12, + templateType &m20, templateType &m21, templateType &m22 ); + + /// \brief Sets the read pointer back to the beginning of your data. + void ResetReadPointer( void ); + + /// \brief Sets the write pointer back to the beginning of your data. + void ResetWritePointer( void ); + + /// \brief This is good to call when you are done with the stream to make + /// sure you didn't leave any data left over void + void AssertStreamEmpty( void ); + + /// \brief RAKNET_DEBUG_PRINTF the bits in the stream. Great for debugging. + void PrintBits( char *out ) const; + void PrintBits( void ) const; + void PrintHex( char *out ) const; + void PrintHex( void ) const; + + /// \brief Ignore data we don't intend to read + /// \param[in] numberOfBits The number of bits to ignore + void IgnoreBits( const BitSize_t numberOfBits ); + + /// \brief Ignore data we don't intend to read + /// \param[in] numberOfBits The number of bytes to ignore + void IgnoreBytes( const unsigned int numberOfBytes ); + + /// \brief Move the write pointer to a position on the array. + /// \param[in] offset the offset from the start of the array. + /// \attention + /// \details Dangerous if you don't know what you are doing! + /// For efficiency reasons you can only write mid-stream if your data is byte aligned. + void SetWriteOffset( const BitSize_t offset ); + + /// \brief Returns the length in bits of the stream + inline BitSize_t GetNumberOfBitsUsed( void ) const {return GetWriteOffset();} + inline BitSize_t GetWriteOffset( void ) const {return numberOfBitsUsed;} + + /// \brief Returns the length in bytes of the stream + inline BitSize_t GetNumberOfBytesUsed( void ) const {return BITS_TO_BYTES( numberOfBitsUsed );} + + /// \brief Returns the number of bits into the stream that we have read + inline BitSize_t GetReadOffset( void ) const {return readOffset;} + + /// \brief Sets the read bit index + void SetReadOffset( const BitSize_t newReadOffset ) {readOffset=newReadOffset;} + + /// \brief Returns the number of bits left in the stream that haven't been read + inline BitSize_t GetNumberOfUnreadBits( void ) const {return numberOfBitsUsed - readOffset;} + + /// \brief Makes a copy of the internal data for you \a _data will point to + /// the stream. Partial bytes are left aligned. + /// \param[out] _data The allocated copy of GetData() + /// \return The length in bits of the stream. + BitSize_t CopyData( unsigned char** _data ) const; + + /// \internal + /// Set the stream to some initial data. + void SetData( unsigned char *inByteArray ); + + /// Gets the data that BitStream is writing to / reading from. + /// Partial bytes are left aligned. + /// \return A pointer to the internal state + inline char* GetData( void ) const {return (char*) data;} + + /// \brief Write numberToWrite bits from the input source. + /// \details Right aligned data means in the case of a partial byte, the bits are aligned + /// from the right (bit 0) rather than the left (as in the normal + /// internal representation) You would set this to true when + /// writing user data, and false when copying bitstream data, such + /// as writing one bitstream to another. + /// \param[in] inByteArray The data + /// \param[in] numberOfBitsToWrite The number of bits to write + /// \param[in] rightAlignedBits if true data will be right aligned + void WriteBits( const unsigned char* inByteArray, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits = true ); + + /// \brief Align the bitstream to the byte boundary and then write the + /// specified number of bits. + /// \details This is faster than WriteBits but + /// wastes the bits to do the alignment and requires you to call + /// ReadAlignedBits at the corresponding read position. + /// \param[in] inByteArray The data + /// \param[in] numberOfBytesToWrite The size of input. + void WriteAlignedBytes( const unsigned char *inByteArray, const unsigned int numberOfBytesToWrite ); + + // Endian swap bytes already in the bitstream + void EndianSwapBytes( int byteOffset, int length ); + + /// \brief Aligns the bitstream, writes inputLength, and writes input. Won't write beyond maxBytesToWrite + /// \param[in] inByteArray The data + /// \param[in] inputLength The size of input. + /// \param[in] maxBytesToWrite Max bytes to write + void WriteAlignedBytesSafe( const char *inByteArray, const unsigned int inputLength, const unsigned int maxBytesToWrite ); + + /// \brief Read bits, starting at the next aligned bits. + /// \details Note that the modulus 8 starting offset of the sequence must be the same as + /// was used with WriteBits. This will be a problem with packet + /// coalescence unless you byte align the coalesced packets. + /// \param[in] inOutByteArray The byte array larger than @em numberOfBytesToRead + /// \param[in] numberOfBytesToRead The number of byte to read from the internal state + /// \return true if there is enough byte. + bool ReadAlignedBytes( unsigned char *inOutByteArray, const unsigned int numberOfBytesToRead ); + + /// \brief Reads what was written by WriteAlignedBytesSafe. + /// \param[in] inOutByteArray The data + /// \param[in] maxBytesToRead Maximum number of bytes to read + /// \return true on success, false on failure. + bool ReadAlignedBytesSafe( char *inOutByteArray, int &inputLength, const int maxBytesToRead ); + bool ReadAlignedBytesSafe( char *inOutByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead ); + + /// \brief Same as ReadAlignedBytesSafe() but allocates the memory for you using new, rather than assuming it is safe to write to + /// \param[in] outByteArray outByteArray will be deleted if it is not a pointer to 0 + /// \return true on success, false on failure. + bool ReadAlignedBytesSafeAlloc( char **outByteArray, int &inputLength, const unsigned int maxBytesToRead ); + bool ReadAlignedBytesSafeAlloc( char **outByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead ); + + /// \brief Align the next write and/or read to a byte boundary. + /// \details This can be used to 'waste' bits to byte align for efficiency reasons It + /// can also be used to force coalesced bitstreams to start on byte + /// boundaries so so WriteAlignedBits and ReadAlignedBits both + /// calculate the same offset when aligning. + inline void AlignWriteToByteBoundary( void ) {numberOfBitsUsed += 8 - ( (( numberOfBitsUsed - 1 ) & 7) + 1 );} + + /// \brief Align the next write and/or read to a byte boundary. + /// \details This can be used to 'waste' bits to byte align for efficiency reasons It + /// can also be used to force coalesced bitstreams to start on byte + /// boundaries so so WriteAlignedBits and ReadAlignedBits both + /// calculate the same offset when aligning. + inline void AlignReadToByteBoundary( void ) {readOffset += 8 - ( (( readOffset - 1 ) & 7 ) + 1 );} + + /// \brief Read \a numberOfBitsToRead bits to the output source. + /// \details alignBitsToRight should be set to true to convert internal + /// bitstream data to userdata. It should be false if you used + /// WriteBits with rightAlignedBits false + /// \param[in] inOutByteArray The resulting bits array + /// \param[in] numberOfBitsToRead The number of bits to read + /// \param[in] alignBitsToRight if true bits will be right aligned. + /// \return true if there is enough bits to read + bool ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsToRead, const bool alignBitsToRight = true ); + + /// \brief Write a 0 + void Write0( void ); + + /// \brief Write a 1 + void Write1( void ); + + /// \brief Reads 1 bit and returns true if that bit is 1 and false if it is 0. + bool ReadBit( void ); + + /// \brief If we used the constructor version with copy data off, this + /// *makes sure it is set to on and the data pointed to is copied. + void AssertCopyData( void ); + + /// \brief Use this if you pass a pointer copy to the constructor + /// *(_copyData==false) and want to overallocate to prevent + /// reallocation. + void SetNumberOfBitsAllocated( const BitSize_t lengthInBits ); + + /// \brief Reallocates (if necessary) in preparation of writing numberOfBitsToWrite + void AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite ); + + /// \internal + /// \return How many bits have been allocated internally + BitSize_t GetNumberOfBitsAllocated(void) const; + + /// Write zeros until the bitstream is filled up to \a bytes + void PadWithZeroToByteLength( unsigned int bytes ); + + /// Get the number of leading zeros for a number + /// \param[in] x Number to test + static int NumberOfLeadingZeroes( uint8_t x ); + static int NumberOfLeadingZeroes( uint16_t x ); + static int NumberOfLeadingZeroes( uint32_t x ); + static int NumberOfLeadingZeroes( uint64_t x ); + static int NumberOfLeadingZeroes( int8_t x ); + static int NumberOfLeadingZeroes( int16_t x ); + static int NumberOfLeadingZeroes( int32_t x ); + static int NumberOfLeadingZeroes( int64_t x ); + + /// \internal Unrolled inner loop, for when performance is critical + void WriteAlignedVar8(const char *inByteArray); + /// \internal Unrolled inner loop, for when performance is critical + bool ReadAlignedVar8(char *inOutByteArray); + /// \internal Unrolled inner loop, for when performance is critical + void WriteAlignedVar16(const char *inByteArray); + /// \internal Unrolled inner loop, for when performance is critical + bool ReadAlignedVar16(char *inOutByteArray); + /// \internal Unrolled inner loop, for when performance is critical + void WriteAlignedVar32(const char *inByteArray); + /// \internal Unrolled inner loop, for when performance is critical + bool ReadAlignedVar32(char *inOutByteArray); + + inline void Write(const char * const inStringVar) + { + uint16_t l = (uint16_t) OVR_strlen(inStringVar); + Write(l); + WriteAlignedBytes((const unsigned char*) inStringVar, (const unsigned int) l); + } + inline void Write(const unsigned char * const inTemplateVar) + { + Write((const char*)inTemplateVar); + } + inline void Write(char * const inTemplateVar) + { + Write((const char*)inTemplateVar); + } + inline void Write(unsigned char * const inTemplateVar) + { + Write((const char*)inTemplateVar); + } + + /// ---- Member function template specialization declarations ---- + // Used for VC7 +#if defined(OVR_CC_MSVC) && _MSC_VER == 1300 + /// Write a bool to a bitstream. + /// \param[in] var The value to write + template <> + void Write(const bool &var); + + /// Write a RakNetGUID to a bitsteam + /// \param[in] var The value to write + template <> + void Write(const RakNetGuid &var); + + /// Write a string to a bitstream + /// \param[in] var The value to write + template <> + void Write(const char* const &var); + template <> + void Write(const unsigned char* const &var); + template <> + void Write(char* const &var); + template <> + void Write(unsigned char* const &var); + template <> + void Write(const OVR::String &var); + + /// \brief Write a bool delta. + /// \details Same thing as just calling Write + /// \param[in] currentValue The current value to write + /// \param[in] lastValue The last value to compare against + template <> + void WriteDelta(const bool ¤tValue, const bool &lastValue); + + template <> + void WriteCompressed(const bool &var); + + /// For values between -1 and 1 + template <> + void WriteCompressed(const float &var); + + /// For values between -1 and 1 + template <> + void WriteCompressed(const double &var); + + /// \brief Write a bool delta. + /// \details Same thing as just calling Write + /// \param[in] currentValue The current value to write + /// \param[in] lastValue The last value to compare against + template <> + void WriteCompressedDelta(const bool ¤tValue, const bool &lastValue); + + /// \brief Save as WriteCompressedDelta(bool currentValue, const templateType &lastValue) + /// when we have an unknown second bool + template <> + void WriteCompressedDelta(const bool ¤tValue); + + /// \brief Read a bool from a bitstream. + /// \param[in] var The value to read + /// \return true on success, false on failure. + template <> + bool Read(bool &var); + + /// \brief Read a String from a bitstream. + /// \param[in] var The value to read + /// \return true on success, false on failure. + template <> + bool Read(char *&var); + template <> + bool Read(wchar_t *&var); + template <> + bool Read(unsigned char *&var); + + /// \brief Read a bool from a bitstream. + /// \param[in] var The value to read + /// \return true on success, false on failure. + template <> + bool ReadDelta(bool &var); + + template <> + bool ReadCompressed(bool &var); + + template <> + bool ReadCompressed(float &var); + + /// For values between -1 and 1 + /// \return true on success, false on failure. + template <> + bool ReadCompressed(double &var); + + template <> + bool ReadCompressed(char* &var); + template <> + bool ReadCompressed(wchar_t* &var); + template <> + bool ReadCompressed(unsigned char *&var); + template <> + bool ReadCompressed(OVR::String &var); + + /// \brief Read a bool from a bitstream. + /// \param[in] var The value to read + /// \return true on success, false on failure. + template <> + bool ReadCompressedDelta(bool &var); +#endif + + inline static bool DoEndianSwap(void) { +#ifndef __BITSTREAM_NATIVE_END + return IsNetworkOrder()==false; +#else + return false; +#endif + } + inline static bool IsBigEndian(void) + { + return IsNetworkOrder(); + } + inline static bool IsNetworkOrder(void) {bool r = IsNetworkOrderInternal(); return r;} + // Not inline, won't compile on PC due to winsock include errors + static bool IsNetworkOrderInternal(void); + static void ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length); + static void ReverseBytesInPlace(unsigned char *inOutData,const unsigned int length); + +private: + + BitStream( const BitStream & /*invalid*/) : numberOfBitsUsed(0), numberOfBitsAllocated(0), readOffset(0),data(NULL), copyData(false) { + OVR_ASSERT(0); + } + + BitStream& operator = ( const BitStream& /*invalid*/ ) { + OVR_ASSERT(0); + static BitStream i; + return i; + } + + /// \brief Assume the input source points to a native type, compress and write it. + void WriteCompressed( const unsigned char* inByteArray, const unsigned int size, const bool unsignedData ); + + /// \brief Assume the input source points to a compressed native type. Decompress and read it. + bool ReadCompressed( unsigned char* inOutByteArray, const unsigned int size, const bool unsignedData ); + + + BitSize_t numberOfBitsUsed; + + BitSize_t numberOfBitsAllocated; + + BitSize_t readOffset; + + unsigned char *data; + + /// true if the internal buffer is copy of the data passed to the constructor + bool copyData; + + /// BitStreams that use less than BITSTREAM_STACK_ALLOCATION_SIZE use the stack, rather than the heap to store data. It switches over if BITSTREAM_STACK_ALLOCATION_SIZE is exceeded + unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE]; +}; + +template +inline bool BitStream::Serialize(bool writeToBitstream, templateType &inOutTemplateVar) +{ + if (writeToBitstream) + Write(inOutTemplateVar); + else + return Read(inOutTemplateVar); + return true; +} + +template +inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue) +{ + if (writeToBitstream) + WriteDelta(inOutCurrentValue, lastValue); + else + return ReadDelta(inOutCurrentValue); + return true; +} + +template +inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue) +{ + if (writeToBitstream) + WriteDelta(inOutCurrentValue); + else + return ReadDelta(inOutCurrentValue); + return true; +} + +template +inline bool BitStream::SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar) +{ + if (writeToBitstream) + WriteCompressed(inOutTemplateVar); + else + return ReadCompressed(inOutTemplateVar); + return true; +} + +template +inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue) +{ + if (writeToBitstream) + WriteCompressedDelta(inOutCurrentValue,lastValue); + else + return ReadCompressedDelta(inOutCurrentValue); + return true; +} +//Stoppedhere +template +inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue) +{ + if (writeToBitstream) + WriteCompressedDelta(inOutCurrentValue); + else + return ReadCompressedDelta(inOutCurrentValue); + return true; +} + +inline bool BitStream::Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes ) +{ + if (writeToBitstream) + Write(inOutByteArray, numberOfBytes); + else + return Read(inOutByteArray, numberOfBytes); + return true; +} + +template +bool BitStream::SerializeCasted( bool writeToBitstream, sourceType &value ) +{ + if (writeToBitstream) WriteCasted(value); + else return ReadCasted(value); + return true; +} + +template +bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange ) +{ + int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum)); + return SerializeBitsFromIntegerRange(writeToBitstream,value,minimum,maximum,requiredBits,allowOutsideRange); +} +template +bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange ) +{ + if (writeToBitstream) WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange); + else return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange); + return true; +} + +template +inline bool BitStream::SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z ) +{ + if (writeToBitstream) + WriteNormVector(x,y,z); + else + return ReadNormVector(x,y,z); + return true; +} + +template +inline bool BitStream::SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z ) +{ + if (writeToBitstream) + WriteVector(x,y,z); + else + return ReadVector(x,y,z); + return true; +} + +template +inline bool BitStream::SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z) +{ + if (writeToBitstream) + WriteNormQuat(w,x,y,z); + else + return ReadNormQuat(w,x,y,z); + return true; +} + +template +inline bool BitStream::SerializeOrthMatrix( + bool writeToBitstream, + templateType &m00, templateType &m01, templateType &m02, + templateType &m10, templateType &m11, templateType &m12, + templateType &m20, templateType &m21, templateType &m22 ) +{ + if (writeToBitstream) + WriteOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22); + else + return ReadOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22); + return true; +} + +inline bool BitStream::SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits ) +{ + if (writeToBitstream) + WriteBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits); + else + return ReadBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits); + return true; +} + +template +inline void BitStream::Write(const templateType &inTemplateVar) +{ +#ifdef OVR_CC_MSVC +#pragma warning(disable:4127) // conditional expression is constant +#endif + if (sizeof(inTemplateVar)==1) + WriteBits( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true ); + else + { +#ifndef __BITSTREAM_NATIVE_END + if (DoEndianSwap()) + { + unsigned char output[sizeof(templateType)]; + ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType)); + WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ); + } + else +#endif + WriteBits( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true ); + } +} + +template +inline void BitStream::WritePtr(templateType *inTemplateVar) +{ +#ifdef OVR_CC_MSVC +#pragma warning(disable:4127) // conditional expression is constant +#endif + if (sizeof(templateType)==1) + WriteBits( ( unsigned char* ) inTemplateVar, sizeof( templateType ) * 8, true ); + else + { +#ifndef __BITSTREAM_NATIVE_END + if (DoEndianSwap()) + { + unsigned char output[sizeof(templateType)]; + ReverseBytes((unsigned char*) inTemplateVar, output, sizeof(templateType)); + WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ); + } + else +#endif + WriteBits( ( unsigned char* ) inTemplateVar, sizeof(templateType) * 8, true ); + } +} + +/// \brief Write a bool to a bitstream. +/// \param[in] inTemplateVar The value to write +template <> +inline void BitStream::Write(const bool &inTemplateVar) +{ + if ( inTemplateVar ) + Write1(); + else + Write0(); +} + + +/// \brief Write a string to a bitstream. +/// \param[in] var The value to write +template <> +inline void BitStream::Write(const OVR::String &inTemplateVar) +{ + uint16_t l = (uint16_t) inTemplateVar.GetLength(); + Write(l); + WriteAlignedBytes((const unsigned char*) inTemplateVar.ToCStr(), (const unsigned int) l); +} +template <> +inline void BitStream::Write(const char * const &inStringVar) +{ + uint16_t l = (uint16_t) strlen(inStringVar); + Write(l); + WriteAlignedBytes((const unsigned char*) inStringVar, (const unsigned int) l); +} +template <> +inline void BitStream::Write(const unsigned char * const &inTemplateVar) +{ + Write((const char*)inTemplateVar); +} +template <> +inline void BitStream::Write(char * const &inTemplateVar) +{ + Write((const char*)inTemplateVar); +} +template <> +inline void BitStream::Write(unsigned char * const &inTemplateVar) +{ + Write((const char*)inTemplateVar); +} + +/// \brief Write any integral type to a bitstream. +/// \details If the current value is different from the last value +/// the current value will be written. Otherwise, a single bit will be written +/// \param[in] currentValue The current value to write +/// \param[in] lastValue The last value to compare against +template +inline void BitStream::WriteDelta(const templateType ¤tValue, const templateType &lastValue) +{ + if (currentValue==lastValue) + { + Write(false); + } + else + { + Write(true); + Write(currentValue); + } +} + +/// \brief Write a bool delta. Same thing as just calling Write +/// \param[in] currentValue The current value to write +/// \param[in] lastValue The last value to compare against +template <> +inline void BitStream::WriteDelta(const bool ¤tValue, const bool &lastValue) +{ + (void) lastValue; + + Write(currentValue); +} + +/// \brief WriteDelta when you don't know what the last value is, or there is no last value. +/// \param[in] currentValue The current value to write +template +inline void BitStream::WriteDelta(const templateType ¤tValue) +{ + Write(true); + Write(currentValue); +} + +/// \brief Write any integral type to a bitstream. +/// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping. +/// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. +/// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type +/// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte +/// \param[in] inTemplateVar The value to write +template +inline void BitStream::WriteCompressed(const templateType &inTemplateVar) +{ +#ifdef OVR_CC_MSVC +#pragma warning(disable:4127) // conditional expression is constant +#endif + if (sizeof(inTemplateVar)==1) + WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true ); + else + { +#ifndef __BITSTREAM_NATIVE_END +#ifdef OVR_CC_MSVC +#pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'uint16_t', possible loss of data +#endif + + if (DoEndianSwap()) + { + unsigned char output[sizeof(templateType)]; + ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType)); + WriteCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true ); + } + else +#endif + WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true ); + } +} + +template <> +inline void BitStream::WriteCompressed(const bool &inTemplateVar) +{ + Write(inTemplateVar); +} + +/// For values between -1 and 1 +template <> +inline void BitStream::WriteCompressed(const float &inTemplateVar) +{ + OVR_ASSERT(inTemplateVar > -1.01f && inTemplateVar < 1.01f); + float varCopy=inTemplateVar; + if (varCopy < -1.0f) + varCopy=-1.0f; + if (varCopy > 1.0f) + varCopy=1.0f; + Write((uint16_t)((varCopy+1.0f)*32767.5f)); +} + +/// For values between -1 and 1 +template <> +inline void BitStream::WriteCompressed(const double &inTemplateVar) +{ + OVR_ASSERT(inTemplateVar > -1.01 && inTemplateVar < 1.01); + double varCopy=inTemplateVar; + if (varCopy < -1.0f) + varCopy=-1.0f; + if (varCopy > 1.0f) + varCopy=1.0f; + Write((uint32_t)((varCopy+1.0)*2147483648.0)); +} + +/// \brief Write any integral type to a bitstream. +/// \details If the current value is different from the last value +/// the current value will be written. Otherwise, a single bit will be written +/// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. +/// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type +/// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte +/// \param[in] currentValue The current value to write +/// \param[in] lastValue The last value to compare against +template +inline void BitStream::WriteCompressedDelta(const templateType ¤tValue, const templateType &lastValue) +{ + if (currentValue==lastValue) + { + Write(false); + } + else + { + Write(true); + WriteCompressed(currentValue); + } +} + +/// \brief Write a bool delta. Same thing as just calling Write +/// \param[in] currentValue The current value to write +/// \param[in] lastValue The last value to compare against +template <> +inline void BitStream::WriteCompressedDelta(const bool ¤tValue, const bool &lastValue) +{ + (void) lastValue; + + Write(currentValue); +} + +/// \brief Save as WriteCompressedDelta(const templateType ¤tValue, const templateType &lastValue) +/// when we have an unknown second parameter +template +inline void BitStream::WriteCompressedDelta(const templateType ¤tValue) +{ + Write(true); + WriteCompressed(currentValue); +} + +/// \brief Save as WriteCompressedDelta(bool currentValue, const templateType &lastValue) +/// when we have an unknown second bool +template <> +inline void BitStream::WriteCompressedDelta(const bool ¤tValue) +{ + Write(currentValue); +} + +/// \brief Read any integral type from a bitstream. Define __BITSTREAM_NATIVE_END if you need endian swapping. +/// \param[in] outTemplateVar The value to read +template +inline bool BitStream::Read(templateType &outTemplateVar) +{ +#ifdef OVR_CC_MSVC +#pragma warning(disable:4127) // conditional expression is constant +#endif + if (sizeof(outTemplateVar)==1) + return ReadBits( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true ); + else + { +#ifndef __BITSTREAM_NATIVE_END +#ifdef OVR_CC_MSVC +#pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'uint16_t', possible loss of data +#endif + if (DoEndianSwap()) + { + unsigned char output[sizeof(templateType)]; + if (ReadBits( ( unsigned char* ) output, sizeof(templateType) * 8, true )) + { + ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType)); + return true; + } + return false; + } + else +#endif + return ReadBits( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true ); + } +} + +/// \brief Read a bool from a bitstream. +/// \param[in] outTemplateVar The value to read +template <> +inline bool BitStream::Read(bool &outTemplateVar) +{ + if ( readOffset + 1 > numberOfBitsUsed ) + return false; + + if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) // Is it faster to just write it out here? + outTemplateVar = true; + else + outTemplateVar = false; + + // Has to be on a different line for Mac + readOffset++; + + return true; +} + +template <> +inline bool BitStream::Read(OVR::String &outTemplateVar) +{ + bool b; + uint16_t l; + b=Read(l); + if (b && l>0) + { + AlignReadToByteBoundary(); + outTemplateVar.AssignString((const char*) (data + ( readOffset >> 3 )), (size_t) l); + IgnoreBytes(l); + } + else + { + AlignReadToByteBoundary(); + } + return b; +} +template <> +inline bool BitStream::Read(char *&varString) +{ + bool b; + uint16_t l; + b=Read(l); + if (b && l>0) + { + memcpy(varString, data + ( readOffset >> 3 ), l); + IgnoreBytes(l); + } + else + { + AlignReadToByteBoundary(); + } + return b; +} +template <> +inline bool BitStream::Read(unsigned char *&varString) +{ + bool b; + uint16_t l; + b=Read(l); + if (b && l>0) + { + memcpy(varString, data + ( readOffset >> 3 ), l); + IgnoreBytes(l); + } + else + { + AlignReadToByteBoundary(); + } + return b; +} + +/// \brief Read any integral type from a bitstream. +/// \details If the written value differed from the value compared against in the write function, +/// var will be updated. Otherwise it will retain the current value. +/// ReadDelta is only valid from a previous call to WriteDelta +/// \param[in] outTemplateVar The value to read +template +inline bool BitStream::ReadDelta(templateType &outTemplateVar) +{ + bool dataWritten; + bool success; + success=Read(dataWritten); + if (dataWritten) + success=Read(outTemplateVar); + return success; +} + +/// \brief Read a bool from a bitstream. +/// \param[in] outTemplateVar The value to read +template <> +inline bool BitStream::ReadDelta(bool &outTemplateVar) +{ + return Read(outTemplateVar); +} + +/// \brief Read any integral type from a bitstream. +/// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping. +/// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. +/// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type +/// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte +/// \param[in] outTemplateVar The value to read +template +inline bool BitStream::ReadCompressed(templateType &outTemplateVar) +{ +#ifdef OVR_CC_MSVC +#pragma warning(disable:4127) // conditional expression is constant +#endif + if (sizeof(outTemplateVar)==1) + return ReadCompressed( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true ); + else + { +#ifndef __BITSTREAM_NATIVE_END + if (DoEndianSwap()) + { + unsigned char output[sizeof(templateType)]; + if (ReadCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true )) + { + ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType)); + return true; + } + return false; + } + else +#endif + return ReadCompressed( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true ); + } +} + +template <> +inline bool BitStream::ReadCompressed(bool &outTemplateVar) +{ + return Read(outTemplateVar); +} + +/// For values between -1 and 1 +template <> +inline bool BitStream::ReadCompressed(float &outTemplateVar) +{ + uint16_t compressedFloat; + if (Read(compressedFloat)) + { + outTemplateVar = ((float)compressedFloat / 32767.5f - 1.0f); + return true; + } + return false; +} + +/// For values between -1 and 1 +template <> +inline bool BitStream::ReadCompressed(double &outTemplateVar) +{ + uint32_t compressedFloat; + if (Read(compressedFloat)) + { + outTemplateVar = ((double)compressedFloat / 2147483648.0 - 1.0); + return true; + } + return false; +} + +/// \brief Read any integral type from a bitstream. +/// \details If the written value differed from the value compared against in the write function, +/// var will be updated. Otherwise it will retain the current value. +/// the current value will be updated. +/// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1. +/// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type +/// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte +/// ReadCompressedDelta is only valid from a previous call to WriteDelta +/// \param[in] outTemplateVar The value to read +template +inline bool BitStream::ReadCompressedDelta(templateType &outTemplateVar) +{ + bool dataWritten; + bool success; + success=Read(dataWritten); + if (dataWritten) + success=ReadCompressed(outTemplateVar); + return success; +} + +/// \brief Read a bool from a bitstream. +/// \param[in] outTemplateVar The value to read +template <> +inline bool BitStream::ReadCompressedDelta(bool &outTemplateVar) +{ + return Read(outTemplateVar); +} + +template +void BitStream::WriteCasted( const sourceType &value ) +{ + destinationType val = (destinationType) value; + Write(val); +} + +template +void BitStream::WriteBitsFromIntegerRange( const templateType value, const templateType minimum,const templateType maximum, bool allowOutsideRange ) +{ + int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum)); + WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange); +} +template +void BitStream::WriteBitsFromIntegerRange( const templateType value, const templateType minimum,const templateType maximum, const int requiredBits, bool allowOutsideRange ) +{ + OVR_ASSERT(maximum>=minimum); + OVR_ASSERT(allowOutsideRange==true || (value>=minimum && value<=maximum)); + if (allowOutsideRange) + { + if (valuemaximum) + { + Write(true); + Write(value); + return; + } + Write(false); + } + templateType valueOffMin=value-minimum; + if (IsBigEndian()==true) + { + unsigned char output[sizeof(templateType)]; + ReverseBytes((unsigned char*)&valueOffMin, output, sizeof(templateType)); + WriteBits(output,requiredBits); + } + else + { + WriteBits((unsigned char*) &valueOffMin,requiredBits); + } +} + +template // templateType for this function must be a float or double +void BitStream::WriteNormVector( templateType x, templateType y, templateType z ) +{ +#ifdef _DEBUG + OVR_ASSERT(x <= 1.01 && y <= 1.01 && z <= 1.01 && x >= -1.01 && y >= -1.01 && z >= -1.01); +#endif + + WriteFloat16((float)x,-1.0f,1.0f); + WriteFloat16((float)y,-1.0f,1.0f); + WriteFloat16((float)z,-1.0f,1.0f); +} + +template // templateType for this function must be a float or double +void BitStream::WriteVector( templateType x, templateType y, templateType z ) +{ + templateType magnitude = sqrt(x * x + y * y + z * z); + Write((float)magnitude); + if (magnitude > 0.00001f) + { + WriteCompressed((float)(x/magnitude)); + WriteCompressed((float)(y/magnitude)); + WriteCompressed((float)(z/magnitude)); + // Write((uint16_t)((x/magnitude+1.0f)*32767.5f)); + // Write((uint16_t)((y/magnitude+1.0f)*32767.5f)); + // Write((uint16_t)((z/magnitude+1.0f)*32767.5f)); + } +} + +template // templateType for this function must be a float or double +void BitStream::WriteNormQuat( templateType w, templateType x, templateType y, templateType z) +{ + Write((bool)(w<0.0)); + Write((bool)(x<0.0)); + Write((bool)(y<0.0)); + Write((bool)(z<0.0)); + Write((uint16_t)(fabs(x)*65535.0)); + Write((uint16_t)(fabs(y)*65535.0)); + Write((uint16_t)(fabs(z)*65535.0)); + // Leave out w and calculate it on the target +} + +template // templateType for this function must be a float or double +void BitStream::WriteOrthMatrix( + templateType m00, templateType m01, templateType m02, + templateType m10, templateType m11, templateType m12, + templateType m20, templateType m21, templateType m22 ) +{ + + double qw; + double qx; + double qy; + double qz; + + // Convert matrix to quat + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ + float sum; + sum = 1 + m00 + m11 + m22; + if (sum < 0.0f) sum=0.0f; + qw = sqrt( sum ) / 2; + sum = 1 + m00 - m11 - m22; + if (sum < 0.0f) sum=0.0f; + qx = sqrt( sum ) / 2; + sum = 1 - m00 + m11 - m22; + if (sum < 0.0f) sum=0.0f; + qy = sqrt( sum ) / 2; + sum = 1 - m00 - m11 + m22; + if (sum < 0.0f) sum=0.0f; + qz = sqrt( sum ) / 2; + if (qw < 0.0) qw=0.0; + if (qx < 0.0) qx=0.0; + if (qy < 0.0) qy=0.0; + if (qz < 0.0) qz=0.0; +#ifdef OVR_OS_WIN32 + qx = _copysign( (double) qx, (double) (m21 - m12) ); + qy = _copysign( (double) qy, (double) (m02 - m20) ); + qz = _copysign( (double) qz, (double) (m10 - m01) ); +#else + qx = copysign( (double) qx, (double) (m21 - m12) ); + qy = copysign( (double) qy, (double) (m02 - m20) ); + qz = copysign( (double) qz, (double) (m10 - m01) ); +#endif + + WriteNormQuat(qw,qx,qy,qz); +} + +template +bool BitStream::ReadCasted( sourceType &value ) +{ + serializationType val; + bool success = Read(val); + value=(sourceType) val; + return success; +} + +template +bool BitStream::ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange ) +{ + int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum)); + return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange); +} +template +bool BitStream::ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange ) +{ + OVR_ASSERT_AND_UNUSED(maximum>=minimum, maximum); + if (allowOutsideRange) + { + bool isOutsideRange; + Read(isOutsideRange); + if (isOutsideRange) + return Read(value); + } + unsigned char output[sizeof(templateType)]; + memset(output,0,sizeof(output)); + bool success = ReadBits(output,requiredBits); + if (success) + { + if (IsBigEndian()==true) + ReverseBytesInPlace(output,sizeof(output)); + memcpy(&value,output,sizeof(output)); + + value+=minimum; + } + + return success; +} + +template // templateType for this function must be a float or double +bool BitStream::ReadNormVector( templateType &x, templateType &y, templateType &z ) +{ + float xIn,yIn,zIn; + ReadFloat16(xIn,-1.0f,1.0f); + ReadFloat16(yIn,-1.0f,1.0f); + ReadFloat16(zIn,-1.0f,1.0f); + x=xIn; + y=yIn; + z=zIn; + return true; +} + +template // templateType for this function must be a float or double +bool BitStream::ReadVector( templateType &x, templateType &y, templateType &z ) +{ + float magnitude; + //uint16_t sx,sy,sz; + if (!Read(magnitude)) + return false; + if (magnitude>0.00001f) + { + // Read(sx); + // Read(sy); + // if (!Read(sz)) + // return false; + // x=((float)sx / 32767.5f - 1.0f) * magnitude; + // y=((float)sy / 32767.5f - 1.0f) * magnitude; + // z=((float)sz / 32767.5f - 1.0f) * magnitude; + float cx=0.0f,cy=0.0f,cz=0.0f; + ReadCompressed(cx); + ReadCompressed(cy); + if (!ReadCompressed(cz)) + return false; + x=cx; + y=cy; + z=cz; + x*=magnitude; + y*=magnitude; + z*=magnitude; + } + else + { + x=0.0; + y=0.0; + z=0.0; + } + return true; +} + +template // templateType for this function must be a float or double +bool BitStream::ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z) +{ + bool cwNeg=false, cxNeg=false, cyNeg=false, czNeg=false; + uint16_t cx,cy,cz; + Read(cwNeg); + Read(cxNeg); + Read(cyNeg); + Read(czNeg); + Read(cx); + Read(cy); + if (!Read(cz)) + return false; + + // Calculate w from x,y,z + x=(templateType)(cx/65535.0); + y=(templateType)(cy/65535.0); + z=(templateType)(cz/65535.0); + if (cxNeg) x=-x; + if (cyNeg) y=-y; + if (czNeg) z=-z; + float difference = 1.0f - x*x - y*y - z*z; + if (difference < 0.0f) + difference=0.0f; + w = (templateType)(sqrt(difference)); + if (cwNeg) + w=-w; + + return true; +} + +template // templateType for this function must be a float or double +bool BitStream::ReadOrthMatrix( + templateType &m00, templateType &m01, templateType &m02, + templateType &m10, templateType &m11, templateType &m12, + templateType &m20, templateType &m21, templateType &m22 ) +{ + float qw,qx,qy,qz; + if (!ReadNormQuat(qw,qx,qy,qz)) + return false; + + // Quat to orthogonal rotation matrix + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm + double sqw = (double)qw*(double)qw; + double sqx = (double)qx*(double)qx; + double sqy = (double)qy*(double)qy; + double sqz = (double)qz*(double)qz; + m00 = (templateType)(sqx - sqy - sqz + sqw); // since sqw + sqx + sqy + sqz =1 + m11 = (templateType)(-sqx + sqy - sqz + sqw); + m22 = (templateType)(-sqx - sqy + sqz + sqw); + + double tmp1 = (double)qx*(double)qy; + double tmp2 = (double)qz*(double)qw; + m10 = (templateType)(2.0 * (tmp1 + tmp2)); + m01 = (templateType)(2.0 * (tmp1 - tmp2)); + + tmp1 = (double)qx*(double)qz; + tmp2 = (double)qy*(double)qw; + m20 =(templateType)(2.0 * (tmp1 - tmp2)); + m02 = (templateType)(2.0 * (tmp1 + tmp2)); + tmp1 = (double)qy*(double)qz; + tmp2 = (double)qx*(double)qw; + m21 = (templateType)(2.0 * (tmp1 + tmp2)); + m12 = (templateType)(2.0 * (tmp1 - tmp2)); + + return true; +} + +template +BitStream& operator<<(BitStream& out, templateType& c) +{ + out.Write(c); + return out; +} +template +BitStream& operator>>(BitStream& in, templateType& c) +{ + bool success = in.Read(c); + (void)success; + + OVR_ASSERT(success); + return in; +} + + +}} // OVR::Net + +#endif diff --git a/LibOVR/Src/Net/OVR_MessageIDTypes.h b/LibOVR/Src/Net/OVR_MessageIDTypes.h new file mode 100644 index 0000000..849f63a --- /dev/null +++ b/LibOVR/Src/Net/OVR_MessageIDTypes.h @@ -0,0 +1,39 @@ +/************************************************************************************ + +Filename : OVR_MessageIDTypes.h +Content : Enumeration list indicating what type of message is being sent +Created : July 3, 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. + +************************************************************************************/ + +namespace OVR { namespace Net { + +/// First byte of a network message +typedef unsigned char MessageID; + +enum DefaultMessageIDTypes +{ + OVRID_RPC1, + OVRID_END = 128, + OVRID_LATENCY_TESTER_1, +}; + +}} // namespace OVR::Net diff --git a/LibOVR/Src/Net/OVR_NetworkPlugin.cpp b/LibOVR/Src/Net/OVR_NetworkPlugin.cpp new file mode 100644 index 0000000..a693499 --- /dev/null +++ b/LibOVR/Src/Net/OVR_NetworkPlugin.cpp @@ -0,0 +1,70 @@ +/************************************************************************************ + +Filename : OVR_NetworkPlugin.cpp +Content : Base class for an extension to the network objects. +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_NetworkPlugin.h" + +namespace OVR { namespace Net { namespace Plugins { + + +//----------------------------------------------------------------------------- +// Plugin identifier to assign next + +//static uint8_t pluginIdNext = 0; + + +//----------------------------------------------------------------------------- +// NetworkPlugin + +NetworkPlugin::NetworkPlugin() +{ + pSession = 0; + //PluginId = pluginIdNext++; +} + +NetworkPlugin::~NetworkPlugin() +{ +} + +void NetworkPlugin::OnAddedToSession(Session* _pSession) +{ + if (pSession != 0) + { + pSession->RemoveSessionListener(this); + } + + pSession = _pSession; +} + +void NetworkPlugin::OnRemovedFromSession(Session* _pSession) +{ + OVR_UNUSED(_pSession); + OVR_ASSERT(_pSession == pSession); + + pSession = 0; +} + + +}}} // OVR::Net::Plugins diff --git a/LibOVR/Src/Net/OVR_NetworkPlugin.h b/LibOVR/Src/Net/OVR_NetworkPlugin.h new file mode 100644 index 0000000..b03b86c --- /dev/null +++ b/LibOVR/Src/Net/OVR_NetworkPlugin.h @@ -0,0 +1,60 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_NetworkPlugin.h +Content : Base class for an extension to the network objects. +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_NetworkPlugin_h +#define OVR_NetworkPlugin_h + +#include "OVR_Session.h" + +namespace OVR { namespace Net { namespace Plugins { + + +//----------------------------------------------------------------------------- +// NetworkPlugin + +// NetworkPlugins use Session and SessionListener to provide network functionality +// independent of the transport medium. +// Uses the chain of command design pattern such that plugins can invoke or intercept +// network events via the Session. +class NetworkPlugin : public SessionListener +{ +public: + NetworkPlugin(); + virtual ~NetworkPlugin(); + +protected: + virtual void OnAddedToSession(Session* _pSession); + virtual void OnRemovedFromSession(Session* _pSession); + + Session *pSession; + //uint8_t PluginId; +}; + + +}}} // OVR::Net::Plugins + +#endif diff --git a/LibOVR/Src/Net/OVR_NetworkTypes.h b/LibOVR/Src/Net/OVR_NetworkTypes.h new file mode 100644 index 0000000..401f53a --- /dev/null +++ b/LibOVR/Src/Net/OVR_NetworkTypes.h @@ -0,0 +1,42 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_NetworkTypes.h +Content : Shared header for network types +Created : June 12, 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_NetworkTypes_h +#define OVR_NetworkTypes_h + +#include "../Kernel/OVR_Types.h" + +namespace OVR { namespace Net { + + +typedef uint64_t NetworkID; +const NetworkID InvalidNetworkID = ~((NetworkID)0); + + +} } // OVR::Net + +#endif diff --git a/LibOVR/Src/Net/OVR_PacketizedTCPSocket.cpp b/LibOVR/Src/Net/OVR_PacketizedTCPSocket.cpp new file mode 100644 index 0000000..6352480 --- /dev/null +++ b/LibOVR/Src/Net/OVR_PacketizedTCPSocket.cpp @@ -0,0 +1,215 @@ +/************************************************************************************ + +Filename : OVR_PacketizedTCPSocket.cpp +Content : TCP with automated message framing. +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_PacketizedTCPSocket.h" + +namespace OVR { namespace Net { + + +//----------------------------------------------------------------------------- +// Constants + +static const int LENGTH_FIELD_BYTES = 4; + + +//----------------------------------------------------------------------------- +// PacketizedTCPSocket + +PacketizedTCPSocket::PacketizedTCPSocket() +{ + pRecvBuff = 0; + pRecvBuffSize = 0; + Transport = TransportType_PacketizedTCP; +} + +PacketizedTCPSocket::PacketizedTCPSocket(SocketHandle _sock, bool isListenSocket) : PacketizedTCPSocketBase(_sock, isListenSocket) +{ + pRecvBuff = 0; + pRecvBuffSize = 0; + Transport = TransportType_PacketizedTCP; +} + +PacketizedTCPSocket::~PacketizedTCPSocket() +{ + OVR_FREE(pRecvBuff); +} + +int PacketizedTCPSocket::Send(const void* pData, int bytes) +{ + Lock::Locker locker(&sendLock); + + if (bytes <= 0) + { + return -1; + } + + // Convert length to 4 endian-neutral bytes + uint32_t lengthWord = bytes; + uint8_t lengthBytes[LENGTH_FIELD_BYTES] = { + (uint8_t)lengthWord, + (uint8_t)(lengthWord >> 8), + (uint8_t)(lengthWord >> 16), + (uint8_t)(lengthWord >> 24) + }; + + int s = PacketizedTCPSocketBase::Send(lengthBytes, LENGTH_FIELD_BYTES); + if (s > 0) + { + return PacketizedTCPSocketBase::Send(pData,bytes); + } + else + { + return s; + } +} + +int PacketizedTCPSocket::SendAndConcatenate(const void** pDataArray, int* dataLengthArray, int arrayCount) +{ + Lock::Locker locker(&sendLock); + + if (arrayCount == 0) + return 0; + + int totalBytes = 0; + for (int i = 0; i < arrayCount; i++) + totalBytes += dataLengthArray[i]; + + // Convert length to 4 endian-neutral bytes + uint32_t lengthWord = totalBytes; + uint8_t lengthBytes[LENGTH_FIELD_BYTES] = { + (uint8_t)lengthWord, + (uint8_t)(lengthWord >> 8), + (uint8_t)(lengthWord >> 16), + (uint8_t)(lengthWord >> 24) + }; + + int s = PacketizedTCPSocketBase::Send(lengthBytes, LENGTH_FIELD_BYTES); + if (s > 0) + { + for (int i = 0; i < arrayCount; i++) + { + PacketizedTCPSocketBase::Send(pDataArray[i], dataLengthArray[i]); + } + } + + return s; +} + +void PacketizedTCPSocket::OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, int bytesRead) +{ + uint8_t* dataSource = NULL; + int dataSourceSize = 0; + + recvBuffLock.DoLock(); + + if (pRecvBuff == NULL) + { + dataSource = pData; + dataSourceSize = bytesRead; + } + else + { + uint8_t* pRecvBuffNew = (uint8_t*)OVR_REALLOC(pRecvBuff, bytesRead + pRecvBuffSize); + if (!pRecvBuffNew) + { + OVR_FREE(pRecvBuff); + pRecvBuff = NULL; + pRecvBuffSize = 0; + recvBuffLock.Unlock(); + return; + } + else + { + pRecvBuff = pRecvBuffNew; + + memcpy(pRecvBuff + pRecvBuffSize, pData, bytesRead); + + dataSourceSize = pRecvBuffSize + bytesRead; + dataSource = pRecvBuff; + } + } + + int bytesReadFromStream; + while (bytesReadFromStream = BytesFromStream(dataSource, dataSourceSize), + LENGTH_FIELD_BYTES + bytesReadFromStream <= dataSourceSize) + { + dataSource += LENGTH_FIELD_BYTES; + dataSourceSize -= LENGTH_FIELD_BYTES; + + TCPSocket::OnRecv(eventHandler, dataSource, bytesReadFromStream); + + dataSource += bytesReadFromStream; + dataSourceSize -= bytesReadFromStream; + } + + if (dataSourceSize > 0) + { + if (dataSource != NULL) + { + if (pRecvBuff == NULL) + { + pRecvBuff = (uint8_t*)OVR_ALLOC(dataSourceSize); + if (!pRecvBuff) + { + pRecvBuffSize = 0; + recvBuffLock.Unlock(); + return; + } + else + { + memcpy(pRecvBuff, dataSource, dataSourceSize); + } + } + else + { + memmove(pRecvBuff, dataSource, dataSourceSize); + } + } + } + else + { + if (pRecvBuff != NULL) + OVR_FREE(pRecvBuff); + + pRecvBuff = NULL; + } + pRecvBuffSize = dataSourceSize; + + recvBuffLock.Unlock(); +} + +int PacketizedTCPSocket::BytesFromStream(uint8_t* pData, int bytesRead) +{ + if (pData != 0 && bytesRead >= LENGTH_FIELD_BYTES) + { + return pData[0] | ((uint32_t)pData[1] << 8) | ((uint32_t)pData[2] << 16) | ((uint32_t)pData[3] << 24); + } + + return 0; +} + + +}} // OVR::Net diff --git a/LibOVR/Src/Net/OVR_PacketizedTCPSocket.h b/LibOVR/Src/Net/OVR_PacketizedTCPSocket.h new file mode 100644 index 0000000..8052bd3 --- /dev/null +++ b/LibOVR/Src/Net/OVR_PacketizedTCPSocket.h @@ -0,0 +1,87 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_PacketizedTCPSocket.cpp +Content : TCP with automated message framing. +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_PacketizedTCPSocket_h +#define OVR_PacketizedTCPSocket_h + +#include "OVR_Socket.h" +#include "../Kernel/OVR_Allocator.h" +#include "../Kernel/OVR_Atomic.h" + +#ifdef OVR_OS_WIN32 +#include "OVR_Win32_Socket.h" +#else +#include "OVR_Unix_Socket.h" +#endif + +namespace OVR { namespace Net { + + +//----------------------------------------------------------------------------- +// NetworkPlugin + +// Packetized TCP base socket +class PacketizedTCPSocketBase : public TCPSocket +{ +public: + PacketizedTCPSocketBase() {} + PacketizedTCPSocketBase(SocketHandle _sock, bool isListenSocket) : TCPSocket(_sock, isListenSocket) {} +}; + + +//----------------------------------------------------------------------------- +// PacketizedTCPSocket + +// Uses TCP but is message aligned rather than stream aligned +// Alternative to reliable UDP +class PacketizedTCPSocket : public PacketizedTCPSocketBase +{ +public: + PacketizedTCPSocket(); + PacketizedTCPSocket(SocketHandle _sock, bool isListenSocket); + virtual ~PacketizedTCPSocket(); + +public: + virtual int Send(const void* pData, int bytes); + virtual int SendAndConcatenate(const void** pDataArray, int *dataLengthArray, int arrayCount); + +protected: + virtual void OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, int bytesRead); + + int BytesFromStream(uint8_t* pData, int bytesRead); + + Lock sendLock; + Lock recvBuffLock; + + uint8_t* pRecvBuff; // Queued receive buffered data + int pRecvBuffSize; // Size of receive queue in bytes +}; + + +}} // OVR::Net + +#endif diff --git a/LibOVR/Src/Net/OVR_RPC1.cpp b/LibOVR/Src/Net/OVR_RPC1.cpp new file mode 100644 index 0000000..12afb09 --- /dev/null +++ b/LibOVR/Src/Net/OVR_RPC1.cpp @@ -0,0 +1,270 @@ +/************************************************************************************ + +Filename : OVR_RPC1.cpp +Content : A network plugin that provides remote procedure call functionality. +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_RPC1.h" +#include "OVR_BitStream.h" +#include "../Kernel/OVR_Threads.h" // Thread::MSleep +#include "OVR_MessageIDTypes.h" + +namespace OVR { namespace Net { namespace Plugins { + + +//----------------------------------------------------------------------------- +// Types + +enum { + ID_RPC4_SIGNAL, + CALL_BLOCKING, + RPC_ERROR_FUNCTION_NOT_REGISTERED, + ID_RPC4_RETURN, +}; + + +//----------------------------------------------------------------------------- +// RPC1 + +RPC1::RPC1() +{ + blockingOnThisConnection = 0; + blockingReturnValue = new BitStream(); +} + +RPC1::~RPC1() +{ + slotHash.Clear(); + delete blockingReturnValue; +} + +void RPC1::RegisterSlot(OVR::String sharedIdentifier, OVR::Observer* rpcSlotObserver ) +{ + slotHash.AddObserverToSubject(sharedIdentifier, rpcSlotObserver); +} + +bool RPC1::RegisterBlockingFunction(OVR::String uniqueID, RPCDelegate blockingFunction) +{ + if (registeredBlockingFunctions.Get(uniqueID)) + return false; + + registeredBlockingFunctions.Set(uniqueID, blockingFunction); + return true; +} + +void RPC1::UnregisterBlockingFunction(OVR::String uniqueID) +{ + registeredBlockingFunctions.Remove(uniqueID); +} + +bool RPC1::CallBlocking( OVR::String uniqueID, OVR::Net::BitStream* bitStream, Ptr pConnection, OVR::Net::BitStream* returnData ) +{ + // If invalid parameters, + if (!pConnection) + { + // Note: This may happen if the endpoint disconnects just before the call + return false; + } + + OVR::Net::BitStream out; + out.Write((MessageID) OVRID_RPC1); + out.Write((MessageID) CALL_BLOCKING); + out.Write(uniqueID); + if (bitStream) + { + bitStream->ResetReadPointer(); + out.AlignWriteToByteBoundary(); + out.Write(bitStream); + } + + SendParameters sp(pConnection, out.GetData(), out.GetNumberOfBytesUsed()); + + if (returnData) + { + returnData->Reset(); + } + + // Only one thread call at a time + Lock::Locker singleRPCLocker(&singleRPCLock); + + // Note this does not prevent multiple calls at a time because .Wait will unlock it below. + // The purpose of this mutex is to synchronize the polling thread and this one, not prevent + // multiple threads from invoking RPC. + Mutex::Locker locker(&callBlockingMutex); + + blockingReturnValue->Reset(); + blockingOnThisConnection = pConnection; + + int bytesSent = pSession->Send(&sp); + if (bytesSent == sp.Bytes) + { + while (blockingOnThisConnection == pConnection) + { + callBlockingWait.Wait(&callBlockingMutex); + } + } + else + { + return false; + } + + if (returnData) + { + returnData->Write(blockingReturnValue); + returnData->ResetReadPointer(); + } + + return true; +} + +bool RPC1::Signal(OVR::String sharedIdentifier, OVR::Net::BitStream* bitStream, Ptr pConnection) +{ + OVR::Net::BitStream out; + out.Write((MessageID) OVRID_RPC1); + out.Write((MessageID) ID_RPC4_SIGNAL); + //out.Write(PluginId); + out.Write(sharedIdentifier); + if (bitStream) + { + bitStream->ResetReadPointer(); + out.AlignWriteToByteBoundary(); + out.Write(bitStream); + } + SendParameters sp(pConnection, out.GetData(), out.GetNumberOfBytesUsed()); + int32_t bytesSent = pSession->Send(&sp); + return bytesSent == sp.Bytes; +} +void RPC1::BroadcastSignal(OVR::String sharedIdentifier, OVR::Net::BitStream* bitStream) +{ + OVR::Net::BitStream out; + out.Write((MessageID) OVRID_RPC1); + out.Write((MessageID) ID_RPC4_SIGNAL); + //out.Write(PluginId); + out.Write(sharedIdentifier); + if (bitStream) + { + bitStream->ResetReadPointer(); + out.AlignWriteToByteBoundary(); + out.Write(bitStream); + } + BroadcastParameters p(out.GetData(), out.GetNumberOfBytesUsed()); + pSession->Broadcast(&p); +} +void RPC1::OnReceive(ReceivePayload *pPayload, ListenerReceiveResult *lrrOut) +{ + OVR_UNUSED(lrrOut); + + if (pPayload->pData[0] == OVRID_RPC1) + { + OVR_ASSERT(pPayload->Bytes >= 2); + + OVR::Net::BitStream bsIn((char*)pPayload->pData, pPayload->Bytes, false); + bsIn.IgnoreBytes(2); + + if (pPayload->pData[1] == RPC_ERROR_FUNCTION_NOT_REGISTERED) + { + Mutex::Locker locker(&callBlockingMutex); + + blockingReturnValue->Reset(); + blockingOnThisConnection = 0; + callBlockingWait.NotifyAll(); + } + else if (pPayload->pData[1] == ID_RPC4_RETURN) + { + Mutex::Locker locker(&callBlockingMutex); + + blockingReturnValue->Reset(); + blockingReturnValue->Write(bsIn); + blockingOnThisConnection = 0; + callBlockingWait.NotifyAll(); + } + else if (pPayload->pData[1] == CALL_BLOCKING) + { + OVR::String uniqueId; + bsIn.Read(uniqueId); + + RPCDelegate *bf = registeredBlockingFunctions.Get(uniqueId); + if (bf==0) + { + OVR::Net::BitStream bsOut; + bsOut.Write((unsigned char) OVRID_RPC1); + bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED); + + SendParameters sp(pPayload->pConnection, bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); + pSession->Send(&sp); + + return; + } + + OVR::Net::BitStream returnData; + bsIn.AlignReadToByteBoundary(); + (*bf)(&bsIn, &returnData, pPayload); + + OVR::Net::BitStream out; + out.Write((MessageID) OVRID_RPC1); + out.Write((MessageID) ID_RPC4_RETURN); + returnData.ResetReadPointer(); + out.AlignWriteToByteBoundary(); + out.Write(returnData); + + SendParameters sp(pPayload->pConnection, out.GetData(), out.GetNumberOfBytesUsed()); + pSession->Send(&sp); + } + else if (pPayload->pData[1]==ID_RPC4_SIGNAL) + { + OVR::String sharedIdentifier; + bsIn.Read(sharedIdentifier); + + Observer *o = slotHash.GetSubject(sharedIdentifier); + + if (o) + { + bsIn.AlignReadToByteBoundary(); + + if (o) + { + OVR::Net::BitStream serializedParameters(bsIn.GetData() + bsIn.GetReadOffset()/8, bsIn.GetNumberOfUnreadBits()/8, false); + + o->Call(&serializedParameters, pPayload); + } + } + } + } +} + +void RPC1::OnDisconnected(Connection* conn) +{ + if (blockingOnThisConnection == conn) + { + blockingOnThisConnection = 0; + callBlockingWait.NotifyAll(); + } +} + +void RPC1::OnConnected(Connection* conn) +{ + OVR_UNUSED(conn); +} + + +}}} // OVR::Net::Plugins diff --git a/LibOVR/Src/Net/OVR_RPC1.h b/LibOVR/Src/Net/OVR_RPC1.h new file mode 100644 index 0000000..6104ccf --- /dev/null +++ b/LibOVR/Src/Net/OVR_RPC1.h @@ -0,0 +1,105 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_RPC1.h +Content : A network plugin that provides remote procedure call functionality. +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_Net_RPC_h +#define OVR_Net_RPC_h + +#include "OVR_NetworkPlugin.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" + +namespace OVR { namespace Net { namespace Plugins { + + +typedef Delegate3 RPCDelegate; +typedef Delegate2 RPCSlot; +// typedef void ( *Slot ) ( OVR::Net::BitStream *userData, OVR::Net::ReceivePayload *pPayload ); + +/// NetworkPlugin that maps strings to function pointers. Can invoke the functions using blocking calls with return values, or signal/slots. Networked parameters serialized with BitStream +class RPC1 : public NetworkPlugin, public NewOverrideBase +{ +public: + RPC1(); + virtual ~RPC1(); + + /// Register a slot, which is a function pointer to one or more implementations that supports this function signature + /// When a signal occurs, all slots with the same identifier are called. + /// \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); + + /// \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); + + /// \brief Same as UnregisterFunction, except for a blocking function + void UnregisterBlockingFunction(OVR::String uniqueID); + + // \brief Same as call, but don't return until the remote system replies. + /// Broadcasting parameter does not exist, this can only call one remote system + /// \note This function does not return until the remote system responds, disconnects, or was never connected to begin with + /// \param[in] Identifier originally passed to RegisterBlockingFunction() on the remote system(s) + /// \param[in] bitStream bitStream encoded data to send to the function callback + /// \param[in] pConnection connection to send on + /// \param[out] returnData Written to by the function registered with RegisterBlockingFunction. + /// \return true if successfully called. False on disconnect, function not registered, or not connected to begin with + bool CallBlocking( OVR::String uniqueID, OVR::Net::BitStream * bitStream, Ptr pConnection, OVR::Net::BitStream *returnData = NULL ); + + /// Calls zero or more functions identified by sharedIdentifier registered with RegisterSlot() + /// \param[in] sharedIdentifier parameter of the same name passed to RegisterSlot() on the remote system + /// \param[in] bitStream bitStream encoded data to send to the function callback + /// \param[in] pConnection connection to send on + bool Signal(OVR::String sharedIdentifier, OVR::Net::BitStream * bitStream, Ptr pConnection); + void BroadcastSignal(OVR::String sharedIdentifier, OVR::Net::BitStream * bitStream); + + +protected: + virtual void OnReceive(ReceivePayload *pPayload, ListenerReceiveResult *lrrOut); + + virtual void OnDisconnected(Connection* conn); + virtual void OnConnected(Connection* conn); + + Hash< String, RPCDelegate, String::HashFunctor > registeredBlockingFunctions; + ObserverHash< RPCSlot > slotHash; + + // Synchronization for RPC caller + Lock singleRPCLock; + Mutex callBlockingMutex; + WaitCondition callBlockingWait; + + Net::BitStream* blockingReturnValue; + Ptr blockingOnThisConnection; +}; + + +}}} // OVR::Net::Plugins + +#endif // OVR_Net_RPC_h diff --git a/LibOVR/Src/Net/OVR_Session.cpp b/LibOVR/Src/Net/OVR_Session.cpp new file mode 100644 index 0000000..508f0c9 --- /dev/null +++ b/LibOVR/Src/Net/OVR_Session.cpp @@ -0,0 +1,736 @@ +/************************************************************************************ + +Filename : OVR_Session.h +Content : One network session that provides connection/disconnection events. +Created : June 10, 2014 +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 "OVR_Session.h" +#include "OVR_PacketizedTCPSocket.h" +#include "../Kernel/OVR_Log.h" +#include "../Service/Service_NetSessionCommon.h" + +namespace OVR { namespace Net { + + +//----------------------------------------------------------------------------- +// Protocol + +static const char* OfficialHelloString = "OculusVR_Hello"; +static const char* OfficialAuthorizedString = "OculusVR_Authorized"; + +void RPC_C2S_Hello::Generate(Net::BitStream* bs) +{ + RPC_C2S_Hello hello; + hello.HelloString = OfficialHelloString; + hello.MajorVersion = RPCVersion_Major; + hello.MinorVersion = RPCVersion_Minor; + hello.PatchVersion = RPCVersion_Patch; + hello.Serialize(bs); +} + +bool RPC_C2S_Hello::Validate() +{ + return MajorVersion == RPCVersion_Major && + MinorVersion <= RPCVersion_Minor && + HelloString.CompareNoCase(OfficialHelloString) == 0; +} + +void RPC_S2C_Authorization::Generate(Net::BitStream* bs, String errorString) +{ + RPC_S2C_Authorization auth; + if (errorString.IsEmpty()) + { + auth.AuthString = OfficialAuthorizedString; + } + else + { + auth.AuthString = errorString; + } + auth.MajorVersion = RPCVersion_Major; + auth.MinorVersion = RPCVersion_Minor; + auth.PatchVersion = RPCVersion_Patch; + auth.Serialize(bs); +} + +bool RPC_S2C_Authorization::Validate() +{ + return AuthString.CompareNoCase(OfficialAuthorizedString) == 0; +} + + +//----------------------------------------------------------------------------- +// Session + +void Session::Shutdown() +{ + { + Lock::Locker locker(&SocketListenersLock); + + const int count = SocketListeners.GetSizeI(); + for (int i = 0; i < count; ++i) + { + SocketListeners[i]->Close(); + } + } + + Lock::Locker locker(&ConnectionsLock); + + const int count = AllConnections.GetSizeI(); + for (int i = 0; i < count; ++i) + { + Connection* arrayItem = AllConnections[i].GetPtr(); + + if (arrayItem->Transport == TransportType_PacketizedTCP) + { + PacketizedTCPConnection* ptcp = (PacketizedTCPConnection*)arrayItem; + + ptcp->pSocket->Close(); + } + } +} + +SessionResult Session::Listen(ListenerDescription* pListenerDescription) +{ + 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); + SocketListeners.PushBack(tcpSocket); + } + else if (pListenerDescription->Transport == TransportType_Loopback) + { + HasLoopbackListener = true; + } + else + { + OVR_ASSERT(false); + } + + return SessionResult_OK; +} + +SessionResult Session::Connect(ConnectParameters *cp) +{ + if (cp->Transport == TransportType_PacketizedTCP) + { + ConnectParametersBerkleySocket* cp2 = (ConnectParametersBerkleySocket*)cp; + Ptr c; + + { + Lock::Locker locker(&ConnectionsLock); + + int connIndex; + Ptr conn = findConnectionBySocket(AllConnections, cp2->BoundSocketToConnectWith, &connIndex); + if (conn) + { + return SessionResult_AlreadyConnected; + } + + TCPSocketBase* tcpSock = (TCPSocketBase*)cp2->BoundSocketToConnectWith.GetPtr(); + + int ret = tcpSock->Connect(&cp2->RemoteAddress); + if (ret < 0) + { + return SessionResult_ConnectFailure; + } + + Ptr newConnection = AllocConnection(cp2->Transport); + if (!newConnection) + { + return SessionResult_ConnectFailure; + } + + c = (PacketizedTCPConnection*)newConnection.GetPtr(); + c->pSocket = (TCPSocket*) cp2->BoundSocketToConnectWith.GetPtr(); + c->Address = cp2->RemoteAddress; + c->Transport = cp2->Transport; + c->SetState(Client_Connecting); + + AllConnections.PushBack(c); + + } + + if (cp2->Blocking) + { + c->WaitOnConnecting(); + } + + if (c->State == State_Connected) + { + return SessionResult_OK; + } + else if (c->State == Client_Connecting) + { + return SessionResult_ConnectInProgress; + } + else + { + 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; +} + +SessionResult Session::ListenPTCP(OVR::Net::BerkleyBindParameters *bbp) +{ + Ptr listenSocket = *new OVR::Net::PacketizedTCPSocket(); + if (listenSocket->Bind(bbp) == INVALID_SOCKET) + { + return SessionResult_BindFailure; + } + + BerkleyListenerDescription bld; + bld.BoundSocketToListenWith = listenSocket.GetPtr(); + bld.Transport = TransportType_PacketizedTCP; + + return Listen(&bld); +} + +SessionResult Session::ConnectPTCP(OVR::Net::BerkleyBindParameters* bbp, SockAddr* remoteAddress, bool blocking) +{ + ConnectParametersBerkleySocket cp(NULL, remoteAddress, blocking, TransportType_PacketizedTCP); + Ptr connectSocket = *new PacketizedTCPSocket(); + + cp.BoundSocketToConnectWith = connectSocket.GetPtr(); + if (connectSocket->Bind(bbp) == INVALID_SOCKET) + { + return SessionResult_BindFailure; + } + + return Connect(&cp); +} + +Ptr Session::findConnectionBySockAddr(SockAddr* address) +{ + const int count = AllConnections.GetSizeI(); + for (int i = 0; i < count; ++i) + { + Connection* arrayItem = AllConnections[i].GetPtr(); + + if (arrayItem->Transport == TransportType_PacketizedTCP) + { + PacketizedTCPConnection* conn = (PacketizedTCPConnection*)arrayItem; + + if (conn->Address == *address) + { + return conn; + } + } + } + + return 0; +} + +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 + { + OVR_ASSERT(false); + } + + return 0; +} +void Session::Broadcast(BroadcastParameters *payload) +{ + SendParameters sp; + sp.Bytes=payload->Bytes; + sp.pData=payload->pData; + + { + Lock::Locker locker(&ConnectionsLock); + + const int connectionCount = FullConnections.GetSizeI(); + for (int i = 0; i < connectionCount; ++i) + { + sp.pConnection = FullConnections[i]; + Send(&sp); + } + } +} +// DO NOT CALL Poll() FROM MULTIPLE THREADS due to allBlockingTcpSockets being a member +void Session::Poll(bool listeners) +{ + allBlockingTcpSockets.Clear(); + + if (listeners) + { + Lock::Locker locker(&SocketListenersLock); + + const int listenerCount = SocketListeners.GetSizeI(); + for (int i = 0; i < listenerCount; ++i) + { + allBlockingTcpSockets.PushBack(SocketListeners[i]); + } + } + + { + Lock::Locker locker(&ConnectionsLock); + + const int connectionCount = AllConnections.GetSizeI(); + for (int i = 0; i < connectionCount; ++i) + { + Connection* arrayItem = AllConnections[i].GetPtr(); + + if (arrayItem->Transport == TransportType_PacketizedTCP) + { + PacketizedTCPConnection* ptcp = (PacketizedTCPConnection*)arrayItem; + + allBlockingTcpSockets.PushBack(ptcp->pSocket); + } + else + { + OVR_ASSERT(false); + } + } + } + + 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(); + + // If socket handle is invalid, + if (sock->GetSocketHandle() == INVALID_SOCKET) + { + OVR_DEBUG_LOG(("[Session] Detected an invalid socket handle - Treating it as a disconnection.")); + sock->IsConnecting = false; + TCP_OnClosed(sock); + } + else + { + state.Add(sock); + } + } + + // If polling returns with an event, + 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); + } + } + } +} + +void Session::AddSessionListener(SessionListener* se) +{ + Lock::Locker locker(&SessionListenersLock); + + const int count = SessionListeners.GetSizeI(); + for (int i = 0; i < count; ++i) + { + if (SessionListeners[i] == se) + { + // Already added + return; + } + } + + SessionListeners.PushBack(se); + se->OnAddedToSession(this); +} + +void Session::RemoveSessionListener(SessionListener* se) +{ + Lock::Locker locker(&SessionListenersLock); + + const int count = SessionListeners.GetSizeI(); + for (int i = 0; i < count; ++i) + { + if (SessionListeners[i] == se) + { + se->OnRemovedFromSession(this); + + SessionListeners.RemoveAtUnordered(i); + break; + } + } +} +SInt32 Session::GetActiveSocketsCount() +{ + Lock::Locker locker1(&SocketListenersLock); + Lock::Locker locker2(&ConnectionsLock); + return SocketListeners.GetSize() + AllConnections.GetSize()>0; +} +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: + OVR_ASSERT(false); + break; + } + + return NULL; +} + +Ptr Session::findConnectionBySocket(Array< Ptr >& connectionArray, Socket* s, int *connectionIndex) +{ + const int count = connectionArray.GetSizeI(); + for (int i = 0; i < count; ++i) + { + Connection* arrayItem = connectionArray[i].GetPtr(); + + if (arrayItem->Transport == TransportType_PacketizedTCP) + { + PacketizedTCPConnection* ptc = (PacketizedTCPConnection*)arrayItem; + + if (ptc->pSocket == s) + { + if (connectionIndex) + { + *connectionIndex = i; + } + return ptc; + } + } + } + + return NULL; +} + +int Session::invokeSessionListeners(ReceivePayload* rp) +{ + Lock::Locker locker(&SessionListenersLock); + + const int count = SessionListeners.GetSizeI(); + for (int j = 0; j < count; ++j) + { + ListenerReceiveResult lrr = LRR_CONTINUE; + SessionListeners[j]->OnReceive(rp, &lrr); + + if (lrr == LRR_RETURN || lrr == LRR_BREAK) + { + break; + } + } + + return rp->Bytes; +} + +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); + + // Look for the connection in the full connection list first + int connIndex; + ConnectionsLock.DoLock(); + Ptr conn = findConnectionBySocket(AllConnections, pSocket, &connIndex); + ConnectionsLock.Unlock(); + if (conn) + { + if (conn->State == State_Connected) + { + ReceivePayload rp; + rp.Bytes = bytesRead; + rp.pConnection = conn; + rp.pData = pData; + + // Call listeners + invokeSessionListeners(&rp); + } + else if (conn->State == Client_ConnectedWait) + { + // Check the version data from the message + BitStream bsIn((char*)pData, bytesRead, false); + + RPC_S2C_Authorization auth; + if (!auth.Deserialize(&bsIn) || + !auth.Validate()) + { + LogError("{ERR-001} [Session] REJECTED: OVRService did not authorize us: %s", auth.AuthString.ToCStr()); + + conn->SetState(State_Zombie); + invokeSessionEvent(&SessionListener::OnIncompatibleProtocol, conn); + } + else + { + // Read remote version + conn->RemoteMajorVersion = auth.MajorVersion; + conn->RemoteMinorVersion = auth.MinorVersion; + conn->RemotePatchVersion = auth.PatchVersion; + + // 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(); + invokeSessionEvent(&SessionListener::OnConnectionRequestAccepted, conn); + } + } + else if (conn->State == Server_ConnectedWait) + { + // Check the version data from the message + BitStream bsIn((char*)pData, bytesRead, false); + + RPC_C2S_Hello hello; + if (!hello.Deserialize(&bsIn) || + !hello.Validate()) + { + 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); + + 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()); + } + else + { + // Read remote version + conn->RemoteMajorVersion = hello.MajorVersion; + conn->RemoteMinorVersion = hello.MinorVersion; + conn->RemotePatchVersion = hello.PatchVersion; + + // Send auth response + BitStream bsOut; + RPC_S2C_Authorization::Generate(&bsOut); + conn->pSocket->Send(bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); + + // 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(); + invokeSessionEvent(&SessionListener::OnNewIncomingConnection, conn); + + } + } + else + { + OVR_ASSERT(false); + } + } +} + +void Session::TCP_OnClosed(TCPSocket* s) +{ + Lock::Locker locker(&ConnectionsLock); + + // If found in the full connection list, + int connIndex; + Ptr conn = findConnectionBySocket(AllConnections, s, &connIndex); + if (conn) + { + AllConnections.RemoveAtUnordered(connIndex); + + // If in the full connection list, + if (findConnectionBySocket(FullConnections, s, &connIndex)) + { + FullConnections.RemoveAtUnordered(connIndex); + } + + // Generate an appropriate event for the current state + switch (conn->State) + { + case Client_Connecting: + invokeSessionEvent(&SessionListener::OnConnectionAttemptFailed, conn); + break; + case Client_ConnectedWait: + case Server_ConnectedWait: + invokeSessionEvent(&SessionListener::OnHandshakeAttemptFailed, conn); + break; + case State_Connected: + case State_Zombie: + invokeSessionEvent(&SessionListener::OnDisconnected, conn); + break; + default: + OVR_ASSERT(false); + break; + } + + conn->SetState(State_Zombie); + } +} + +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); + // If pSockAddr is not localhost, then close newSock + if (pSockAddr->IsLocalhost()==false) + { + newSocket->Close(); + return; + } + + if (newSocket) + { + Ptr b = AllocConnection(TransportType_PacketizedTCP); + Ptr c = (PacketizedTCPConnection*)b.GetPtr(); + c->pSocket = newSocket; + c->Address = *pSockAddr; + c->State = Server_ConnectedWait; + + { + Lock::Locker locker(&ConnectionsLock); + AllConnections.PushBack(c); + } + + // Server does not send the first packet. It waits for the client to send its version + } +} + +void Session::TCP_OnConnected(TCPSocket *s) +{ + Lock::Locker locker(&ConnectionsLock); + + // If connection was found, + PacketizedTCPConnection* conn = findConnectionBySocket(AllConnections, s); + if (conn) + { + OVR_ASSERT(conn->State == Client_Connecting); + + // Send hello message + BitStream bsOut; + RPC_C2S_Hello::Generate(&bsOut); + conn->pSocket->Send(bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); + + // Just update state but do not generate any notifications yet + conn->State = Client_ConnectedWait; + } +} + +void Session::invokeSessionEvent(void(SessionListener::*f)(Connection*), Connection* conn) +{ + Lock::Locker locker(&SessionListenersLock); + + const int count = SessionListeners.GetSizeI(); + for (int i = 0; i < count; ++i) + { + (SessionListeners[i]->*f)(conn); + } +} + +Ptr Session::GetConnectionAtIndex(int index) +{ + Lock::Locker locker(&ConnectionsLock); + + const int count = FullConnections.GetSizeI(); + + if (index < count) + { + return FullConnections[index]; + } + + return NULL; +} + + +}} // OVR::Net diff --git a/LibOVR/Src/Net/OVR_Session.h b/LibOVR/Src/Net/OVR_Session.h new file mode 100644 index 0000000..b6ef07b --- /dev/null +++ b/LibOVR/Src/Net/OVR_Session.h @@ -0,0 +1,513 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_Session.h +Content : One network session that provides connection/disconnection events. +Created : June 10, 2014 +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_Session_h +#define OVR_Session_h + +#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" + +namespace OVR { namespace Net { + +class Session; + + +//----------------------------------------------------------------------------- +// Based on Semantic Versioning ( http://semver.org/ ) +// +// 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) +//----------------------------------------------------------------------------- + +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_Patch = 0; // PATCH version when you make backwards-compatible bug fixes. + +// Client starts communication by sending its version number. +struct RPC_C2S_Hello +{ + RPC_C2S_Hello() : + MajorVersion(0), + MinorVersion(0), + PatchVersion(0) + { + } + + String HelloString; + + // Client 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); + + bool Validate(); +}; + +// Server responds with an authorization accepted message, including the server's version number +struct RPC_S2C_Authorization +{ + RPC_S2C_Authorization() : + MajorVersion(0), + MinorVersion(0), + PatchVersion(0) + { + } + + String AuthString; + + // 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); + } + + 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(); +}; + + +//----------------------------------------------------------------------------- +// Result of a session function +enum SessionResult +{ + SessionResult_OK, + SessionResult_BindFailure, + SessionResult_ListenFailure, + SessionResult_ConnectFailure, + SessionResult_ConnectInProgress, + SessionResult_AlreadyConnected, +}; + + +//----------------------------------------------------------------------------- +// Connection state +enum EConnectionState +{ + State_Zombie, // Disconnected + + // Client-only: + Client_Connecting, // Waiting for TCP connection + Client_ConnectedWait, // Connected! Waiting for server to authorize + + // Server-only: + Server_ConnectedWait, // Connected! Waiting for client handshake + + State_Connected // Connected +}; + + +//----------------------------------------------------------------------------- +// Generic connection over any transport +class Connection : public RefCountBase +{ +public: + Connection() : + Transport(TransportType_None), + State(State_Zombie), + RemoteMajorVersion(0), + RemoteMinorVersion(0), + RemotePatchVersion(0) + { + } + virtual ~Connection() // Allow delete from base + { + } + +public: + virtual void SetState(EConnectionState s) {State = s;} + + TransportType Transport; + EConnectionState State; + + // Version number read from remote host just before connection completes + int RemoteMajorVersion; + int RemoteMinorVersion; + int RemotePatchVersion; +}; + + +//----------------------------------------------------------------------------- +// Generic network connection over any network transport +class NetworkConnection : public Connection +{ +protected: + NetworkConnection() + { + } + virtual ~NetworkConnection() + { + } + +public: + virtual void SetState(EConnectionState s) + { + if (s != State) + { + Mutex::Locker locker(&StateMutex); + + if (s != State) + { + State = s; + + if (State != Client_Connecting) + { + ConnectingWait.NotifyAll(); + } + } + } + } + + void WaitOnConnecting() + { + Mutex::Locker locker(&StateMutex); + + while (State == Client_Connecting) + { + ConnectingWait.Wait(&StateMutex); + } + } + + SockAddr Address; + Mutex StateMutex; + WaitCondition ConnectingWait; +}; + + +//----------------------------------------------------------------------------- +// TCP Connection +class TCPConnection : public NetworkConnection +{ +public: + TCPConnection() + { + } + virtual ~TCPConnection() + { + } + +public: + Ptr pSocket; +}; + + +//----------------------------------------------------------------------------- +// Packetized TCP Connection +class PacketizedTCPConnection : public TCPConnection +{ +public: + PacketizedTCPConnection() + { + Transport = TransportType_PacketizedTCP; + } + virtual ~PacketizedTCPConnection() + { + } +}; + + +//----------------------------------------------------------------------------- +// Generic socket listener description +class ListenerDescription +{ +public: + ListenerDescription() : + Transport(TransportType_None) + { + } + + TransportType Transport; +}; + + +//----------------------------------------------------------------------------- +// Description for a Berkley socket listener +class BerkleyListenerDescription : public ListenerDescription +{ +public: + static const int DefaultMaxIncomingConnections = 64; + static const int DefaultMaxConnections = 128; + + BerkleyListenerDescription() : + MaxIncomingConnections(DefaultMaxIncomingConnections), + MaxConnections(DefaultMaxConnections) + { + } + + Ptr BoundSocketToListenWith; + int MaxIncomingConnections; + int MaxConnections; +}; + + +//----------------------------------------------------------------------------- +// Receive payload +struct ReceivePayload +{ + Connection* pConnection; // Source connection + uint8_t* pData; // Pointer to data received + int Bytes; // Number of bytes of data received +}; + +//----------------------------------------------------------------------------- +// Broadcast parameters +class BroadcastParameters +{ +public: + BroadcastParameters() : + pData(NULL), + Bytes(0) + { + } + + BroadcastParameters(const void* _pData, int _bytes) : + pData(_pData), + Bytes(_bytes) + { + } + +public: + const void* pData; // Pointer to data to send + int Bytes; // Number of bytes of data received +}; + +//----------------------------------------------------------------------------- +// Send parameters +class SendParameters +{ +public: + 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 +}; + + +//----------------------------------------------------------------------------- +// Parameters to connect +struct ConnectParameters +{ +public: + ConnectParameters() : + Transport(TransportType_None) + { + } + + TransportType Transport; +}; + +struct ConnectParametersBerkleySocket : public ConnectParameters +{ + SockAddr RemoteAddress; + Ptr BoundSocketToConnectWith; + bool Blocking; + + ConnectParametersBerkleySocket(BerkleySocket* s, SockAddr* addr, bool blocking, + TransportType transport) : + RemoteAddress(*addr), + BoundSocketToConnectWith(s), + Blocking(blocking) + { + Transport = transport; + } +}; + + +//----------------------------------------------------------------------------- +// Listener receive result +enum ListenerReceiveResult +{ + /// 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, + + /// This message will be processed by other SessionListeners, and at last by the user. + LRR_CONTINUE, +}; + + +//----------------------------------------------------------------------------- +// SessionListener + +// Callback interface for network events such as connecting, disconnecting, getting data, independent of the transport medium +class SessionListener +{ +public: + virtual ~SessionListener(){} + + // Data events + virtual void OnReceive(ReceivePayload* pPayload, ListenerReceiveResult* lrrOut) { OVR_UNUSED2(pPayload, lrrOut); } + + // Connection was closed + virtual void OnDisconnected(Connection* conn) = 0; + + // Connection was created (some data was exchanged to verify protocol compatibility too) + virtual void OnConnected(Connection* conn) = 0; + + // Server accepted client + virtual void OnNewIncomingConnection(Connection* conn) { OnConnected(conn); } + // Client was accepted + virtual void OnConnectionRequestAccepted(Connection* conn) { OnConnected(conn); } + + // Connection attempt failed for some reason + virtual void OnConnectionAttemptFailed(Connection* conn) { OnDisconnected(conn); } + + // Incompatible protocol + virtual void OnIncompatibleProtocol(Connection* conn) { OnConnectionAttemptFailed(conn); } + // Disconnected during initial handshake + virtual void OnHandshakeAttemptFailed(Connection* conn) { OnConnectionAttemptFailed(conn); } + + // Other + virtual void OnAddedToSession(Session* session) { OVR_UNUSED(session); } + virtual void OnRemovedFromSession(Session* session) { OVR_UNUSED(session); } +}; + + +//----------------------------------------------------------------------------- +// Session + +// 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) + { + } + virtual ~Session() + { + // Ensure memory backing the sockets array is released + allBlockingTcpSockets.ClearAndRelease(); + } + + 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 + virtual void Poll(bool listeners = true); + virtual void AddSessionListener(SessionListener* se); + virtual void RemoveSessionListener(SessionListener* se); + virtual SInt32 GetActiveSocketsCount(); + + // Packetized TCP convenience functions + virtual SessionResult ListenPTCP(BerkleyBindParameters* bbp); + virtual SessionResult ConnectPTCP(BerkleyBindParameters* bbp, SockAddr* RemoteAddress, bool blocking); + + // Closes all the sockets; useful for interrupting the socket polling during shutdown + void Shutdown(); + + // Get count of successful connections (past handshake point) + int GetConnectionCount() const + { + return FullConnections.GetSizeI(); + } + Ptr GetConnectionAtIndex(int index); + +protected: + virtual Ptr AllocConnection(TransportType transportType); + + Lock SocketListenersLock, ConnectionsLock, SessionListenersLock; + bool HasLoopbackListener; // Has loopback listener installed? + 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 + + // Tools + Ptr findConnectionBySocket(Array< Ptr >& connectionArray, Socket* s, int *connectionIndex = NULL); // Call with ConnectionsLock held + Ptr findConnectionBySockAddr(SockAddr* address); // Call with ConnectionsLock held + 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); +}; + + +}} // OVR::Net + +#endif diff --git a/LibOVR/Src/Net/OVR_Socket.cpp b/LibOVR/Src/Net/OVR_Socket.cpp new file mode 100644 index 0000000..d0b4e77 --- /dev/null +++ b/LibOVR/Src/Net/OVR_Socket.cpp @@ -0,0 +1,94 @@ +/************************************************************************************ + +Filename : OVR_Socket.cpp +Content : Socket common data shared between all platforms. +Created : June 10, 2014 +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 "OVR_Socket.h" + +namespace OVR { namespace Net { + + +//----------------------------------------------------------------------------- +// Socket + +Socket::Socket() : + Transport(TransportType_None) +{ +} + + +//----------------------------------------------------------------------------- +// BerkleyBindParameters + +BerkleyBindParameters::BerkleyBindParameters() : + Port(0), + Address(), + blockingTimeout(0x7fffffff) +{ +} + +//----------------------------------------------------------------------------- +// BerkleySocket + +BerkleySocket::BerkleySocket() : + TheSocket(INVALID_SOCKET) + //TimeoutUsec(0) // Initialized by SetBlockingTimeout + //TimeoutSec(0) // " +{ + SetBlockingTimeout(1000); +} + +BerkleySocket::~BerkleySocket() +{ + // Close socket on destruction + Close(); +} + + +//----------------------------------------------------------------------------- +// UDPSocketBase + +UDPSocketBase::UDPSocketBase() +{ + Transport = TransportType_UDP; +} + + +//----------------------------------------------------------------------------- +// TCPSocketBase + +TCPSocketBase::TCPSocketBase() + : IsListenSocket(false) +{ + Transport = TransportType_TCP; +} + +TCPSocketBase::TCPSocketBase(SocketHandle handle) + : IsListenSocket(false) +{ + TheSocket = handle; +} + + +}} // OVR::Net diff --git a/LibOVR/Src/Net/OVR_Socket.h b/LibOVR/Src/Net/OVR_Socket.h new file mode 100644 index 0000000..b02e038 --- /dev/null +++ b/LibOVR/Src/Net/OVR_Socket.h @@ -0,0 +1,242 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_Socket.h +Content : Socket common data shared between all platforms. +Created : June 10, 2014 +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_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" + +// OS-specific socket headers +#if defined(OVR_OS_WIN32) +#include +#include +#define WIN32_LEAN_AND_MEAN +#include +#else +# include +# include +# include +#ifdef OVR_OS_ANDROID +#include +#endif +#endif + +namespace OVR { namespace Net { + +class SockAddr; +class UDPSocket; +class TCPSocket; + + +//----------------------------------------------------------------------------- +// Portable numeric Socket handle +#if defined(OVR_OS_WIN32) +typedef SOCKET SocketHandle; +#else +typedef int SocketHandle; +static const SocketHandle INVALID_SOCKET = -1; +static const int SOCKET_ERROR = -1; +#endif + + +//----------------------------------------------------------------------------- +// Types of network transport +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 +}; + + +//----------------------------------------------------------------------------- +// Abstraction for a network socket. Inheritance hierarchy +// modeled after RakNet so that future support can be added +// for Linux, Windows RT, consoles, etc. +class Socket : public RefCountBase +{ +public: + Socket(); + virtual void Close() = 0; + +public: + TransportType Transport; // Type of transport +}; + + +//----------------------------------------------------------------------------- +// Bind parameters for Berkley sockets +struct BerkleyBindParameters +{ +public: + BerkleyBindParameters(); + +public: + uint16_t Port; // Port + String Address; + uint32_t blockingTimeout; +}; + + +//----------------------------------------------------------------------------- +// Berkley socket +class BerkleySocket : public Socket +{ +public: + BerkleySocket(); + virtual ~BerkleySocket(); + + virtual void Close(); + virtual int32_t GetSockname(SockAddr* pSockAddrOut); + virtual void SetBlockingTimeout(int timeoutMs) // milliseconds + { + TimeoutSec = timeoutMs / 1000; + TimeoutUsec = (timeoutMs % 1000) * 1000; + } + int GetBlockingTimeoutUsec() const + { + return TimeoutUsec; + } + int GetBlockingTimeoutSec() const + { + return TimeoutSec; + } + SocketHandle GetSocketHandle() const + { + return TheSocket; + } + +protected: + SocketHandle TheSocket; // Socket handle + int TimeoutUsec, TimeoutSec; +}; + + +//----------------------------------------------------------------------------- +// UDP socket events +class SocketEvent_UDP +{ +public: + virtual ~SocketEvent_UDP(){} + + virtual void UDP_OnRecv(Socket* pSocket, uint8_t* pData, + uint32_t bytesRead, SockAddr* pSockAddr) + { + OVR_UNUSED4(pSocket, pData, bytesRead, pSockAddr); + } +}; + + +//----------------------------------------------------------------------------- +// TCP socket events +class SocketEvent_TCP +{ +public: + virtual ~SocketEvent_TCP(){} + + virtual void TCP_OnRecv (Socket* pSocket, + uint8_t* pData, + int bytesRead) + { + OVR_UNUSED3(pSocket, pData, bytesRead); + } + virtual void TCP_OnClosed (TCPSocket* pSocket) + { + OVR_UNUSED(pSocket); + } + virtual void TCP_OnAccept (TCPSocket* pListener, + SockAddr* pSockAddr, + SocketHandle newSock) + { + OVR_UNUSED3(pListener, pSockAddr, newSock); + } + virtual void TCP_OnConnected(TCPSocket* pSocket) + { + OVR_UNUSED(pSocket); + } +}; + + +//----------------------------------------------------------------------------- +// UDP Berkley socket + +// Base class for UDP sockets, code shared between platforms +class UDPSocketBase : public BerkleySocket +{ +public: + UDPSocketBase(); + +public: + virtual SocketHandle Bind(BerkleyBindParameters* pBindParameters) = 0; + virtual int Send(const void* pData, + int bytes, + SockAddr* pSockAddr) = 0; + virtual void Poll(SocketEvent_UDP* eventHandler) = 0; + +protected: + virtual void OnRecv(SocketEvent_UDP* eventHandler, + uint8_t* pData, + int bytesRead, + SockAddr* address) = 0; +}; + + +//----------------------------------------------------------------------------- +// TCP Berkley socket + +// Base class for TCP sockets, code shared between platforms +class TCPSocketBase : public BerkleySocket +{ +public: + TCPSocketBase(); + TCPSocketBase(SocketHandle handle); + +public: + virtual SocketHandle Bind(BerkleyBindParameters* pBindParameters) = 0; + virtual int Listen() = 0; + virtual int Connect(SockAddr* pSockAddr) = 0; + virtual int Send(const void* pData, + int bytes) = 0; +protected: + virtual void OnRecv(SocketEvent_TCP* eventHandler, + uint8_t* pData, + int bytesRead) = 0; + +protected: + bool IsListenSocket; // Is the socket listening (acting as a server)? +}; + + +}} // OVR::Net + +#endif diff --git a/LibOVR/Src/Net/OVR_Unix_Socket.cpp b/LibOVR/Src/Net/OVR_Unix_Socket.cpp new file mode 100644 index 0000000..6f2a678 --- /dev/null +++ b/LibOVR/Src/Net/OVR_Unix_Socket.cpp @@ -0,0 +1,600 @@ +/************************************************************************************ + +Filename : OVR_Unix_Socket.cpp +Content : Berkley sockets networking implementation +Created : July 1, 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_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 + +namespace OVR { namespace Net { + +//----------------------------------------------------------------------------- +// BerkleySocket + +void BerkleySocket::Close() +{ + if (TheSocket != INVALID_SOCKET) + { + close(TheSocket); + TheSocket = INVALID_SOCKET; + } +} + +SInt32 BerkleySocket::GetSockname(SockAddr *pSockAddrOut) +{ + struct sockaddr_in6 sa; + memset(&sa,0,sizeof(sa)); + socklen_t size = sizeof(sa); + SInt32 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() +{ +} + +SockAddr::SockAddr(SockAddr* address) +{ + Set(&address->Addr6); +} + +SockAddr::SockAddr(sockaddr_storage* storage) +{ + Set(storage); +} + +SockAddr::SockAddr(sockaddr_in6* address) +{ + Set(address); +} + +SockAddr::SockAddr(const char* hostAddress, UInt16 port, int sockType) +{ + 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 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 ; + + if (SOCK_DGRAM == sockType) + { + hints.ai_protocol = IPPROTO_UDP; + } + else if (SOCK_STREAM == sockType) + { + hints.ai_protocol = IPPROTO_TCP; + } + + 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("getaddrinfo error: %s", gai_strerror(errcode)); + } + + OVR_ASSERT(servinfo); + + if (servinfo) + { + memcpy(&Addr6, servinfo->ai_addr, sizeof(Addr6)); + + freeaddrinfo(servinfo); + } +} + +UInt16 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; +} + + +// Returns true on success +static bool SetSocketOptions(SocketHandle sock) +{ + bool failed = false; + int sock_opt; + int sockError = 0; + + // This doubles the max throughput rate + sock_opt=1024*256; + sockError = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) ); + if (sockError != 0) + { + int errsv = errno; + OVR::LogError("[Socket] Failed SO_RCVBUF setsockopt, errno: %d", errsv); + failed = true; + } + + // This doesn't make much difference: 10% maybe + // Not supported on console 2 + sock_opt=1024*16; + sockError = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) ); + if (sockError != 0) + { + int errsv = errno; + OVR::LogError("[Socket] Failed SO_SNDBUF setsockopt, errno: %d", errsv); + failed = true; + } + + // NOTE: This should be OVR_OS_BSD, not Mac. +#ifdef OVR_OS_MAC + int value = 1; + sockError = setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value)); + if (sockError != 0) + { + int errsv = errno; + OVR::LogError("[Socket] Failed SO_NOSIGPIPE setsockopt, errno: %d", errsv); + failed = true; + } +#endif + + // Reuse address is only needed for posix platforms, as it is the default + // on Windows platforms. + int optval = 1; + sockError = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)); + if (sockError != 0) + { + int errsv = errno; + OVR::LogError("[Socket] Failed SO_REUSEADDR setsockopt, errno: %d", errsv); + failed = true; + } + + return !failed; +} + +void _Ioctlsocket(SocketHandle sock, unsigned long nonblocking) +{ + int flags = fcntl(sock, F_GETFL, 0); + if (flags < 0) return; // return false + if (nonblocking == 0) { flags &= ~O_NONBLOCK; } + else { flags |= O_NONBLOCK; } + fcntl(sock, F_SETFL, flags); +} + +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("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 != 0) + { + SetSocketOptions(sock); + int ret = bind( sock, aip->ai_addr, (int) aip->ai_addrlen ); + if (ret>=0) + { + // The actual socket is always non-blocking + // I control blocking or not using WSAEventSelect + _Ioctlsocket(sock, 1); + freeaddrinfo(servinfo); + return sock; + } + else + { + close(sock); + } + } + } + + if (servinfo) { freeaddrinfo(servinfo); } + return INVALID_SOCKET; +} + + +//----------------------------------------------------------------------------- +// UDPSocket + +UDPSocket::UDPSocket() +{ + RecvBuf = new UByte[RecvBufSize]; +} + +UDPSocket::~UDPSocket() +{ + delete[] RecvBuf; +} + +SocketHandle UDPSocket::Bind(BerkleyBindParameters *pBindParameters) +{ + SocketHandle s = BindShared(AF_INET6, SOCK_DGRAM, pBindParameters); + if (s < 0) + return s; + + Close(); + TheSocket = s; + + return TheSocket; +} + +void UDPSocket::OnRecv(SocketEvent_UDP* eventHandler, UByte* pData, int bytesRead, SockAddr* address) +{ + eventHandler->UDP_OnRecv(this, pData, bytesRead, address); +} + +int UDPSocket::Send(const void* pData, int bytes, SockAddr* address) +{ + // NOTE: This should be OVR_OS_BSD +#ifdef OVR_OS_MAC + int flags = 0; +#else + int flags = MSG_NOSIGNAL; +#endif + + return (int)sendto(TheSocket, (const char*)pData, bytes, flags, (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 = (int)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; +} +TCPSocket::TCPSocket(SocketHandle boundHandle, bool isListenSocket) +{ + TheSocket = boundHandle; + IsListenSocket = isListenSocket; + IsConnecting = false; + SetSocketOptions(TheSocket); + + // The actual socket is always non-blocking + _Ioctlsocket(TheSocket, 1); +} + +TCPSocket::~TCPSocket() +{ +} + +void TCPSocket::OnRecv(SocketEvent_TCP* eventHandler, UByte* pData, int bytesRead) +{ + eventHandler->TCP_OnRecv(this, pData, bytesRead); +} + +SocketHandle TCPSocket::Bind(BerkleyBindParameters* pBindParameters) +{ + SocketHandle s = BindShared(AF_INET6, SOCK_STREAM, pBindParameters); + if (s < 0) + return s; + + Close(); + + SetBlockingTimeout(pBindParameters->blockingTimeout); + TheSocket = s; + + 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) + { + int errsv = errno; + // EINPROGRESS should not be checked on windows but should + // be checked on POSIX platforms. + if (errsv == EWOULDBLOCK || errsv == EINPROGRESS) + { + IsConnecting = true; + return 0; + } + + OVR::LogText( "TCPSocket::Connect failed:Error code - %d\n", errsv ); + } + + return retval; +} + +int TCPSocket::Send(const void* pData, int bytes) +{ + if (bytes <= 0) + { + return 0; + } + else + { + return (int)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 (handle == INVALID_SOCKET) + { + return; + } + + 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 = (int)usec; + + return select(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 = (int)recv(handle, data, BUFF_SIZE, 0); + if (bytesRead > 0) + { + tcpSocket->OnRecv(eventHandler, (UByte*)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 > 0) + { + 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_Unix_Socket.h b/LibOVR/Src/Net/OVR_Unix_Socket.h new file mode 100644 index 0000000..90ee515 --- /dev/null +++ b/LibOVR/Src/Net/OVR_Unix_Socket.h @@ -0,0 +1,152 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_Unix_Socket.h +Content : Berkley sockets networking implementation +Created : July 1, 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_Unix_Socket_h +#define OVR_Unix_Socket_h + +#include "OVR_Socket.h" +#include "OVR_BitStream.h" + +#include +#include +#include +#include +#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 port, int sockType); + +public: + void Set(const sockaddr_storage* sa); + void Set(const sockaddr_in6* sa); + void Set(const char* hostAddress, UInt16 port, int sockType); // SOCK_DGRAM or SOCK_STREAM + + UInt16 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; + UByte* RecvBuf; + + virtual void OnRecv(SocketEvent_UDP* eventHandler, UByte* 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, UByte* 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/Net/OVR_Win32_Socket.cpp b/LibOVR/Src/Net/OVR_Win32_Socket.cpp new file mode 100644 index 0000000..edc6ade --- /dev/null +++ b/LibOVR/Src/Net/OVR_Win32_Socket.cpp @@ -0,0 +1,608 @@ +/************************************************************************************ + +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 diff --git a/LibOVR/Src/Net/OVR_Win32_Socket.h b/LibOVR/Src/Net/OVR_Win32_Socket.h new file mode 100644 index 0000000..ac66869 --- /dev/null +++ b/LibOVR/Src/Net/OVR_Win32_Socket.h @@ -0,0 +1,151 @@ +/************************************************************************************ + +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 diff --git a/LibOVR/Src/OVR_CAPI.cpp b/LibOVR/Src/OVR_CAPI.cpp index a7f921f..bfc0527 100644 --- a/LibOVR/Src/OVR_CAPI.cpp +++ b/LibOVR/Src/OVR_CAPI.cpp @@ -5,16 +5,16 @@ Content : Experimental simple C interface to the HMD - version 1. Created : November 30, 2013 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -30,14 +30,24 @@ limitations under the License. #include "Kernel/OVR_System.h" #include "OVR_Stereo.h" #include "OVR_Profile.h" +#include "../Include/OVR_Version.h" -#include "CAPI/CAPI_GlobalState.h" #include "CAPI/CAPI_HMDState.h" #include "CAPI/CAPI_FrameTimeManager.h" +#include "Service/Service_NetClient.h" +#ifdef OVR_SINGLE_PROCESS +#include "Service/Service_NetServer.h" +#endif + +#ifdef OVR_OS_WIN32 +#include "Displays/OVR_Win32_ShimFunctions.h" +#endif + using namespace OVR; using namespace OVR::Util::Render; +using namespace OVR::Tracking; //------------------------------------------------------------------------------------- // Math @@ -68,24 +78,54 @@ Vector2f FovPort::TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle) return tanEyeAngle * eyeToSourceNDC.Scale + eyeToSourceNDC.Offset; } +// ***** SensorDataType + +SensorDataType::SensorDataType(const ovrSensorData& s) +{ + Acceleration = s.Accelerometer; + RotationRate = s.Gyro; + MagneticField = s.Magnetometer; + Temperature = s.Temperature; + AbsoluteTimeSeconds = s.TimeInSeconds; +} + +SensorDataType::operator ovrSensorData () const +{ + ovrSensorData result; + result.Accelerometer = Acceleration; + result.Gyro = RotationRate; + result.Magnetometer = MagneticField; + result.Temperature = Temperature; + result.TimeInSeconds = (float) AbsoluteTimeSeconds; + return result; +} + // ***** SensorState -SensorState::SensorState(const ovrSensorState& s) +TrackingState::TrackingState(const ovrTrackingState& s) { - Predicted = s.Predicted; - Recorded = s.Recorded; - Temperature = s.Temperature; - StatusFlags = s.StatusFlags; + HeadPose = s.HeadPose; + CameraPose = s.CameraPose; + LeveledCameraPose = s.LeveledCameraPose; + RawSensorData = s.RawSensorData; + StatusFlags = s.StatusFlags; + LastVisionProcessingTime = s.LastVisionProcessingTime; + LastVisionFrameLatency = s.LastVisionFrameLatency; + LastCameraFrameCounter = s.LastCameraFrameCounter; } -SensorState::operator ovrSensorState() const +TrackingState::operator ovrTrackingState() const { - ovrSensorState result; - result.Predicted = Predicted; - result.Recorded = Recorded; - result.Temperature = Temperature; + ovrTrackingState result; + result.HeadPose = HeadPose; + result.CameraPose = CameraPose; + result.LeveledCameraPose = LeveledCameraPose; + result.RawSensorData = RawSensorData; result.StatusFlags = StatusFlags; + result.LastVisionProcessingTime = LastVisionProcessingTime; + result.LastVisionFrameLatency = LastVisionFrameLatency; + result.LastCameraFrameCounter = LastCameraFrameCounter; return result; } @@ -109,10 +149,10 @@ OVR_EXPORT ovrMatrix4f ovrMatrix4f_Projection(ovrFovPort fov, float znear, float OVR_EXPORT ovrMatrix4f ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale, - float orthoDistance, float eyeViewAdjustX) + float orthoDistance, float hmdToEyeViewOffsetX) { - float orthoHorizontalOffset = eyeViewAdjustX / orthoDistance; + 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 @@ -125,7 +165,7 @@ OVR_EXPORT ovrMatrix4f ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ov // [-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. + // 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 + @@ -187,14 +227,14 @@ OVR_EXPORT double ovr_GetTimeInSeconds() // Waits until the specified absolute time. OVR_EXPORT double ovr_WaitTillTime(double absTime) { - volatile int i; double initialTime = ovr_GetTimeInSeconds(); double newTime = initialTime; while(newTime < absTime) { - for (int j = 0; j < 50; j++) - i = 0; + for (int j = 0; j < 5; j++) + OVR_PROCESSOR_PAUSE(); + newTime = ovr_GetTimeInSeconds(); } @@ -202,44 +242,76 @@ OVR_EXPORT double ovr_WaitTillTime(double absTime) return newTime - initialTime; } + //------------------------------------------------------------------------------------- // 1. Init/shutdown. static ovrBool CAPI_SystemInitCalled = 0; +static ovrBool CAPI_ovrInitializeCalled = 0; + +static OVR::Service::NetClient* CAPI_pNetClient = 0; + +OVR_EXPORT ovrBool ovr_InitializeRenderingShim() +{ + OVR::System::DirectDisplayInitialize(); + return OVR::System::DirectDisplayEnabled(); +} OVR_EXPORT ovrBool ovr_Initialize() { - if (OVR::CAPI::GlobalState::pInstance) + if (CAPI_ovrInitializeCalled) return 1; // We must set up the system for the plugin to work if (!OVR::System::IsInitialized()) - { + { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); CAPI_SystemInitCalled = 1; } - // Constructor detects devices - GlobalState::pInstance = new GlobalState; + if (!OVR::System::DirectDisplayEnabled() && !OVR::Display::InCompatibilityMode(false)) + { + OVR_ASSERT(false); + return 0; + } + + CAPI_pNetClient = NetClient::GetInstance(); + +#ifdef OVR_SINGLE_PROCESS + + // If the server could not start running, + if (Service::NetServer::GetInstance()->IsInitialized()) + { + CAPI_pNetClient->Connect(true); + } + else + { + // 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"); + } +#else + CAPI_pNetClient->Connect(true); +#endif + + CAPI_ovrInitializeCalled = 1; + return 1; } OVR_EXPORT void ovr_Shutdown() -{ - if (!GlobalState::pInstance) - return; - - delete GlobalState::pInstance; - GlobalState::pInstance = 0; - +{ // We should clean up the system to be complete - if (CAPI_SystemInitCalled) + if (OVR::System::IsInitialized() && CAPI_SystemInitCalled) { OVR::System::Destroy(); - CAPI_SystemInitCalled = 0; - } - return; + } + + CAPI_SystemInitCalled = 0; + CAPI_ovrInitializeCalled = 0; } @@ -254,89 +326,178 @@ OVR_EXPORT void ovr_Shutdown() OVR_EXPORT int ovrHmd_Detect() { - if (!GlobalState::pInstance) + if (!CAPI_ovrInitializeCalled) return 0; - return GlobalState::pInstance->EnumerateDevices(); + + return CAPI_pNetClient->Hmd_Detect(); } -// ovrHmd_Create us explicitly separated from StartSensor and Configure to allow creation of +// ovrHmd_Create us explicitly separated from ConfigureTracking and ConfigureRendering to allow creation of // 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) { - if (!GlobalState::pInstance) - return 0; - Ptr device = *GlobalState::pInstance->CreateDevice(index); - if (!device) + if (!CAPI_ovrInitializeCalled) return 0; - HMDState* hmds = new HMDState(device); + double t0 = Timer::GetSeconds(); + HMDNetworkInfo netInfo; + + // There may be some delay before the HMD is fully detected. + // Since we are also trying to create the HMD immediately it may lose this race and + // get "NO HMD DETECTED." Wait a bit longer to avoid this. + while (!CAPI_pNetClient->Hmd_Create(index, &netInfo) || + netInfo.NetId == InvalidVirtualHmdId) + { + // If two seconds elapse and still no HMD detected, + if (Timer::GetSeconds() - t0 > 2.) + { + if (!NetClient::GetInstance()->IsConnected(false, false)) + { + NetClient::GetInstance()->SetLastError("Not connected to service"); + } + else + { + NetClient::GetInstance()->SetLastError("No HMD Detected"); + } + + return 0; + } + } + + // Create HMD State object + HMDState* hmds = HMDState::CreateHMDState(CAPI_pNetClient, netInfo); if (!hmds) + { + CAPI_pNetClient->Hmd_Release(netInfo.NetId); + + NetClient::GetInstance()->SetLastError("Unable to create HMD state"); return 0; + } + + // Reset frame timing so that FrameTimeManager values are properly initialized in AppRendered mode. + ovrHmd_ResetFrameTiming(hmds->pHmdDesc, 0); - return hmds; + return hmds->pHmdDesc; +} + + +OVR_EXPORT ovrBool ovrHmd_AttachToWindow( ovrHmd hmd, void* window, + const ovrRecti* destMirrorRect, + const ovrRecti* sourceRenderTargetRect ) +{ + OVR_UNUSED( destMirrorRect ); + OVR_UNUSED( sourceRenderTargetRect ); + + if (!CAPI_ovrInitializeCalled) + return false; + + 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 +#ifdef OVR_OS_WIN32 + Win32::DisplayShim::GetInstance().hWindow = (HWND)window; +#endif +#ifdef OVR_OS_MAC + OVR_UNUSED(window); +#endif + + return true; } OVR_EXPORT ovrHmd ovrHmd_CreateDebug(ovrHmdType type) { - if (!GlobalState::pInstance) - return 0; + if (!CAPI_ovrInitializeCalled) + return 0; + + HMDState* hmds = HMDState::CreateHMDState(type); - HMDState* hmds = new HMDState(type); - return hmds; + return hmds->pHmdDesc; } -OVR_EXPORT void ovrHmd_Destroy(ovrHmd hmd) +OVR_EXPORT void ovrHmd_Destroy(ovrHmd hmddesc) { - if (!hmd) + if (!hmddesc || !hmddesc->Handle) return; + // TBD: Any extra shutdown? - HMDState* hmds = (HMDState*)hmd; + 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"); } - delete (HMDState*)hmd; +#ifdef OVR_OS_WIN32 + if (hmds->pWindow) + { + // ? ok to call + //CAPI_pNetClient->Hmd_AttachToWindow(hmds->GetNetId(), 0); + hmds->pWindow = 0; + Win32::DisplayShim::GetInstance().hWindow = (HWND)0; + } +#endif + + delete (HMDState*)hmddesc->Handle; } -OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmd) +OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmddesc) { - using namespace OVR; - if (!hmd) + if (!CAPI_ovrInitializeCalled) + { + return "System initialize not called"; + } + + VirtualHmdId netId = InvalidVirtualHmdId; + + if (hmddesc && hmddesc->Handle) { - if (!GlobalState::pInstance) - return "LibOVR not initialized."; - return GlobalState::pInstance->GetLastError(); + HMDState* p = (HMDState*)hmddesc->Handle; + netId = p->GetNetId(); } - HMDState* p = (HMDState*)hmd; - return p->GetLastError(); + + return CAPI_pNetClient->Hmd_GetLastError(netId); } +#define OVR_VERSION_LIBOVR_PFX "libOVR:" + +// Returns version string representing libOVR version. Static, so +// string remains valid for app lifespan +OVR_EXPORT const char* ovr_GetVersionString() +{ + static const char* version = OVR_VERSION_LIBOVR_PFX OVR_VERSION_STRING; + return version + sizeof(OVR_VERSION_LIBOVR_PFX) - 1; +} + + //------------------------------------------------------------------------------------- // 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 hmd) +OVR_EXPORT unsigned int ovrHmd_GetEnabledCaps(ovrHmd hmddesc) { - HMDState* p = (HMDState*)hmd; + HMDState* p = (HMDState*)hmddesc->Handle; return p ? p->EnabledHmdCaps : 0; } // Modifies capability bits described by ovrHmdCapBits that can be modified, -// such as ovrHmd_LowPersistance. -OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int capsBits) +// such as ovrHmdCap_LowPersistance. +OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmddesc, unsigned int capsBits) { - HMDState* p = (HMDState*)hmd; + HMDState* p = (HMDState*)hmddesc->Handle; if (p) + { p->SetEnabledHmdCaps(capsBits); + } } @@ -355,55 +516,59 @@ OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int capsBits) // functions that have different rules (all frame access functions // must be on render thread) -OVR_EXPORT ovrBool ovrHmd_StartSensor(ovrHmd hmd, unsigned int supportedCaps, unsigned int requiredCaps) +OVR_EXPORT ovrBool ovrHmd_ConfigureTracking(ovrHmd hmddesc, unsigned int supportedCaps, + unsigned int requiredCaps) { - HMDState* p = (HMDState*)hmd; - // TBD: Decide if we null-check arguments. - return p->StartSensor(supportedCaps, requiredCaps); -} + if (hmddesc) + { + HMDState* p = (HMDState*)hmddesc->Handle; + return p->ConfigureTracking(supportedCaps, requiredCaps); + } -OVR_EXPORT void ovrHmd_StopSensor(ovrHmd hmd) -{ - HMDState* p = (HMDState*)hmd; - p->StopSensor(); + return 0; } -OVR_EXPORT void ovrHmd_ResetSensor(ovrHmd hmd) +OVR_EXPORT void ovrHmd_RecenterPose(ovrHmd hmddesc) { - HMDState* p = (HMDState*)hmd; - p->ResetSensor(); + if (hmddesc) + { + HMDState* p = (HMDState*)hmddesc->Handle; + p->TheSensorStateReader.RecenterPose(); + } } -OVR_EXPORT ovrSensorState ovrHmd_GetSensorState(ovrHmd hmd, double absTime) +OVR_EXPORT ovrTrackingState ovrHmd_GetTrackingState(ovrHmd hmddesc, double absTime) { - HMDState* p = (HMDState*)hmd; - return p->PredictedSensorState(absTime); -} + ovrTrackingState result; -// Returns information about a sensor. Only valid after SensorStart. -OVR_EXPORT ovrBool ovrHmd_GetSensorDesc(ovrHmd hmd, ovrSensorDesc* descOut) -{ - HMDState* p = (HMDState*)hmd; - return p->GetSensorDesc(descOut) ? 1 : 0; -} + if (hmddesc) + { + HMDState* p = (HMDState*)hmddesc->Handle; + result = p->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 -//------------------------------------------------------------------------------------- -// *** General Setup + return result; +} -OVR_EXPORT void ovrHmd_GetDesc(ovrHmd hmd, ovrHmdDesc* desc) -{ - HMDState* hmds = (HMDState*)hmd; - *desc = hmds->RenderState.GetDesc(); - desc->Handle = hmd; -} +//------------------------------------------------------------------------------------- +// *** General Setup // Per HMD -> calculateIdealPixelSize -OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov, +OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmddesc, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel) { + ovrHmdStruct * hmd = hmddesc->Handle; if (!hmd) return Sizei(0); HMDState* hmds = (HMDState*)hmd; @@ -415,12 +580,13 @@ OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovP OVR_EXPORT -ovrBool ovrHmd_ConfigureRendering( ovrHmd hmd, +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); @@ -429,17 +595,18 @@ ovrBool ovrHmd_ConfigureRendering( ovrHmd hmd, // TBD: MA - Deprecated, need alternative -void ovrHmd_SetVsync(ovrHmd hmd, ovrBool vsync) +void ovrHmd_SetVsync(ovrHmd hmddesc, ovrBool vsync) { + ovrHmdStruct * hmd = hmddesc->Handle; if (!hmd) return; return ((HMDState*)hmd)->TimeManager.SetVsync(vsync? true : false); } -OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrame(ovrHmd hmd, unsigned int frameIndex) +OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrame(ovrHmd hmddesc, unsigned int frameIndex) { - HMDState* hmds = (HMDState*)hmd; + HMDState* hmds = (HMDState*)hmddesc->Handle; if (!hmds) { ovrFrameTiming f; @@ -449,56 +616,66 @@ OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrame(ovrHmd hmd, unsigned int frameIndex) // Check: Proper configure and threading state for the call. hmds->checkRenderingConfigured("ovrHmd_BeginFrame"); - OVR_ASSERT_LOG(hmds->BeginFrameCalled == false, ("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(hmd, frameIndex); + return ovrHmd_BeginFrameTiming(hmddesc, frameIndex); } // Renders textures to frame buffer -OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd) +OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmddesc, + const ovrPosef renderPose[2], + const ovrTexture eyeTexture[2]) { - HMDState* hmds = (HMDState*)hmd; + HMDState* hmds = (HMDState*)hmddesc->Handle; if (!hmds) return; + // Instrument when the EndFrame() call started + hmds->LagStats.InstrumentEndFrameStart(ovr_GetTimeInSeconds()); + + hmds->SubmitEyeTextures(renderPose, eyeTexture); + // 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); - // TBD: Move directly into renderer - bool dk2LatencyTest = (hmds->HMDInfo.HmdType == HmdType_DK2) && - (hmds->EnabledHmdCaps & ovrHmdCap_LatencyTest); - if (dk2LatencyTest) + ovrHmd_GetLatencyTest2DrawColor(hmddesc, NULL); // We don't actually need to draw color, so send NULL + + if (hmds->pRenderer) { - hmds->LatencyTest2DrawColor[0] = hmds->TimeManager.GetFrameLatencyTestDrawColor(); - hmds->LatencyTest2DrawColor[1] = hmds->LatencyTest2DrawColor[0]; - hmds->LatencyTest2DrawColor[2] = hmds->LatencyTest2DrawColor[0]; - } + hmds->pRenderer->SaveGraphicsState(); - if (hmds->pRenderer) - { - hmds->pRenderer->SaveGraphicsState(); - hmds->pRenderer->EndFrame(true, - hmds->LatencyTestActive ? hmds->LatencyTestDrawColor : NULL, - - // MA: Use this color since we are running DK2 test all the time. - dk2LatencyTest ? hmds->LatencyTest2DrawColor : 0 - //hmds->LatencyTest2Active ? hmds->LatencyTest2DrawColor : NULL - ); - hmds->pRenderer->RestoreGraphicsState(); + // See if we need to show the HSWDisplay. + if (hmds->pHSWDisplay) // Until we know that these are valid, assume any of them can't be. + { + ovrHSWDisplayState hswDisplayState; + hmds->pHSWDisplay->TickState(&hswDisplayState, true); // This may internally call HASWarning::Display. + + if (hswDisplayState.Displayed) + { + hmds->pHSWDisplay->Render(ovrEye_Left, &eyeTexture[ovrEye_Left]); + hmds->pHSWDisplay->Render(ovrEye_Right, &eyeTexture[ovrEye_Right]); + } + } + + hmds->pRenderer->EndFrame(true); + hmds->pRenderer->RestoreGraphicsState(); } + // Call after present - ovrHmd_EndFrameTiming(hmd); + ovrHmd_EndFrameTiming(hmddesc); - if (dk2LatencyTest) - { - hmds->TimeManager.UpdateFrameLatencyTrackingAfterEndFrame( - hmds->LatencyTest2DrawColor[0], hmds->LatencyUtil2.GetLocklessState()); - } + // Instrument latency tester + hmds->LagStats.InstrumentLatencyTimings(hmds->TimeManager); + + // Instrument when the EndFrame() call ended + hmds->LagStats.InstrumentEndFrameEnd(ovr_GetTimeInSeconds()); // Out of BeginFrame hmds->BeginFrameThreadId = 0; @@ -506,28 +683,27 @@ OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd) } -OVR_EXPORT ovrPosef ovrHmd_BeginEyeRender(ovrHmd hmd, ovrEyeType eye) -{ - HMDState* hmds = (HMDState*)hmd; - if (!hmds) return ovrPosef(); - return hmds->BeginEyeRender(eye); -} - -OVR_EXPORT void ovrHmd_EndEyeRender(ovrHmd hmd, ovrEyeType eye, - ovrPosef renderPose, ovrTexture* eyeTexture) +// Not exposed as part of public API +OVR_EXPORT void ovrHmd_RegisterPostDistortionCallback(ovrHmd hmddesc, PostDistortionCallback callback) { - HMDState* hmds = (HMDState*)hmd; + HMDState* hmds = (HMDState*)hmddesc->Handle; if (!hmds) return; - hmds->EndEyeRender(eye, renderPose, eyeTexture); + + if (hmds->pRenderer) + { + hmds->pRenderer->RegisterPostDistortionCallback(callback); + } } + //------------------------------------------------------------------------------------- // ***** Frame Timing logic -OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIndex) +OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) { + ovrHmdStruct * hmd = hmddesc->Handle; ovrFrameTiming f; memset(&f, 0, sizeof(f)); @@ -536,12 +712,12 @@ OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIn { FrameTimeManager::Timing frameTiming = hmds->TimeManager.GetFrameTiming(frameIndex); - f.ThisFrameSeconds = frameTiming.ThisFrameTime; + 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]; + 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 : @@ -554,8 +730,9 @@ OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIn return f; } -OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frameIndex) +OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) { + ovrHmdStruct * hmd = hmddesc->Handle; ovrFrameTiming f; memset(&f, 0, sizeof(f)); @@ -563,16 +740,16 @@ OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frame if (!hmds) return f; // Check: Proper state for the call. - OVR_ASSERT_LOG(hmds->BeginFrameTimingCalled == false, - ("ovrHmd_BeginFrameTiming called multiple times.")); + 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(); - f.ThisFrameSeconds = thisFrameTime; - f.NextFrameSeconds = frameTiming.NextFrameTime; + f.ThisFrameSeconds = thisFrameTime; + f.NextFrameSeconds = frameTiming.NextFrameTime; f.TimewarpPointSeconds = frameTiming.TimewarpPointTime; f.ScanoutMidpointSeconds= frameTiming.MidpointTime; f.EyeScanoutSeconds[0] = frameTiming.EyeRenderTimes[0]; @@ -580,7 +757,7 @@ OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frame // Compute DeltaSeconds. f.DeltaSeconds = (hmds->LastFrameTimeSeconds == 0.0f) ? 0.0f : - (float) (thisFrameTime - hmds->LastFrameTimeSeconds); + (float) (thisFrameTime - hmds->LastFrameTimeSeconds); hmds->LastFrameTimeSeconds = thisFrameTime; if (f.DeltaSeconds > 1.0f) f.DeltaSeconds = 1.0f; @@ -589,24 +766,33 @@ OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frame } -OVR_EXPORT void ovrHmd_EndFrameTiming(ovrHmd hmd) +OVR_EXPORT void ovrHmd_EndFrameTiming(ovrHmd hmddesc) { - HMDState* hmds = (HMDState*)hmd; + HMDState* hmds = (HMDState*)hmddesc->Handle; if (!hmds) return; // Debug state checks: Must be in BeginFrameTiming, on the same thread. hmds->checkBeginFrameTimingScope("ovrHmd_EndTiming"); - // MA TBD: Correct chek or not? + // 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); + } } -OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex) +OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) { - HMDState* hmds = (HMDState*)hmd; + HMDState* hmds = (HMDState*)hmddesc->Handle; if (!hmds) return; hmds->TimeManager.ResetFrameTiming(frameIndex, @@ -616,29 +802,69 @@ OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex) hmds->LastGetFrameTimeSeconds = 0.0; } +OVR_EXPORT void ovrHmd_GetEyePoses(ovrHmd hmd, unsigned int frameIndex, ovrVector3f hmdToEyeViewOffset[2], + ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState) +{ + HMDState* hmds = (HMDState*)hmd->Handle; + if (!hmds) return; + + hmds->LatencyTestActive = hmds->ProcessLatencyTest(hmds->LatencyTestDrawColor); + + ovrTrackingState hmdTrackingState = hmds->TimeManager.GetEyePredictionTracking(hmd, ovrEye_Count, frameIndex); + ovrPosef hmdPose = hmdTrackingState.HeadPose.ThePose; + + // caller passed in a valid pointer, so copy to output + 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); +} -OVR_EXPORT ovrPosef ovrHmd_GetEyePose(ovrHmd hmd, ovrEyeType eye) +ovrPosef ovrHmd_GetHmdPosePerEye(ovrHmd hmd, ovrEyeType eye) { - HMDState* hmds = (HMDState*)hmd; + 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) + { + hmds->LatencyTestActive = hmds->ProcessLatencyTest(hmds->LatencyTestDrawColor); + } + hmds->checkBeginFrameTimingScope("ovrHmd_GetEyePose"); return hmds->TimeManager.GetEyePredictionPose(hmd, eye); } +OVR_EXPORT void ovrHmd_AddDistortionTimeMeasurement(ovrHmd hmddesc, double distortionTimeSeconds) +{ + if (!hmddesc) + return; + HMDState* hmds = (HMDState*)hmddesc->Handle; -OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, - ovrPosef renderPose, ovrMatrix4f twmOut[2]) + hmds->checkBeginFrameTimingScope("ovrHmd_GetTimewarpEyeMatrices"); + hmds->TimeManager.AddDistortionTimeMeasurement(distortionTimeSeconds); +} + + + +OVR_EXPORT void ovrHmd_GetEyeTimewarpMatricesDebug(ovrHmd hmddesc, ovrEyeType eye, + ovrPosef renderPose, ovrMatrix4f twmOut[2],double debugTimingOffsetInSeconds) { - HMDState* hmds = (HMDState*)hmd; - if (!hmd) + if (!hmddesc) return; + HMDState* hmds = (HMDState*)hmddesc->Handle; // Debug checks: BeginFrame was called, on the same thread. hmds->checkBeginFrameTimingScope("ovrHmd_GetTimewarpEyeMatrices"); - hmds->TimeManager.GetTimewarpMatrices(hmd, eye, renderPose, twmOut); + hmds->TimeManager.GetTimewarpMatrices(hmddesc, eye, renderPose, twmOut, debugTimingOffsetInSeconds); /* // MA: Took this out because new latency test approach just sames @@ -652,20 +878,27 @@ OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, } +OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmddesc, ovrEyeType eye, + ovrPosef renderPose, ovrMatrix4f twmOut[2]) +{ + return(ovrHmd_GetEyeTimewarpMatricesDebug(hmddesc, eye, renderPose, twmOut, 0.0)); +} + + -OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, +OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmddesc, ovrEyeType eyeType, ovrFovPort fov) { + HMDState* hmds = (HMDState*)hmddesc->Handle; ovrEyeRenderDesc erd; - HMDState* hmds = (HMDState*)hmd; if (!hmds) { memset(&erd, 0, sizeof(erd)); return erd; } - return hmds->RenderState.calcRenderDesc(eyeType, fov); + return hmds->RenderState.CalcRenderDesc(eyeType, fov); } @@ -674,67 +907,34 @@ OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, -// Generate distortion mesh per eye. -// scaleAndOffsetOut - this will be needed for shader -OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, + +OVR_EXPORT ovrBool ovrHmd_CreateDistortionMeshDebug( ovrHmd hmddesc, ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, - ovrDistortionMesh *meshData ) + ovrDistortionMesh *meshData, + float debugEyeReliefOverrideInMetres) { - 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_OS_WIN32) - // TBD: We should probably be sharing some C API structures with C++ to avoid this mess... - OVR_COMPILER_ASSERT(sizeof(DistortionMeshVertexData) == sizeof(ovrDistortionVertex)); - OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, ScreenPosNDC) == OVR_OFFSET_OF(ovrDistortionVertex, Pos)); - OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, TimewarpLerp) == OVR_OFFSET_OF(ovrDistortionVertex, TimeWarpFactor)); - OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, Shade) == OVR_OFFSET_OF(ovrDistortionVertex, VignetteFactor)); - OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, TanEyeAnglesR) == OVR_OFFSET_OF(ovrDistortionVertex, TexR)); - OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, TanEyeAnglesG) == OVR_OFFSET_OF(ovrDistortionVertex, TexG)); - OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, TanEyeAnglesB) == OVR_OFFSET_OF(ovrDistortionVertex, TexB)); -#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 = hmds->RenderState.RenderInfo; - StereoEye stereoEye = (eyeType == ovrEye_Left) ? StereoEye_Left : StereoEye_Right; + // 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)); - const DistortionRenderDesc& distortion = hmds->RenderState.Distortion[eyeType]; - - // 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**)&meshData->pIndexData, - &vertexCount, &triangleCount, - (stereoEye == StereoEye_Right), - hmdri, distortion, eyeToSourceNDC); - - if (meshData->pVertexData) - { - // Convert to index - meshData->IndexCount = triangleCount * 3; - meshData->VertexCount = vertexCount; - return 1; - } - - return 0; +} +OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmddesc, + ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, + ovrDistortionMesh *meshData) +{ + 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) @@ -771,155 +971,319 @@ OVR_EXPORT void ovrHmd_GetRenderScaleAndOffset( ovrFovPort fov, //------------------------------------------------------------------------------------- // ***** Latency Test interface -OVR_EXPORT ovrBool ovrHmd_GetLatencyTestDrawColor(ovrHmd hmd, unsigned char rgbColorOut[3]) +OVR_EXPORT ovrBool ovrHmd_GetLatencyTestDrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]) { - HMDState* p = (HMDState*)hmd; + HMDState* p = (HMDState*)hmddesc->Handle; rgbColorOut[0] = p->LatencyTestDrawColor[0]; rgbColorOut[1] = p->LatencyTestDrawColor[1]; rgbColorOut[2] = p->LatencyTestDrawColor[2]; return p->LatencyTestActive; } -OVR_EXPORT const char* ovrHmd_GetLatencyTestResult(ovrHmd hmd) +OVR_EXPORT ovrBool ovrHmd_ProcessLatencyTest(ovrHmd hmddesc, unsigned char rgbColorOut[3]) +{ + OVR_UNUSED(hmddesc); + return NetClient::GetInstance()->LatencyUtil_ProcessInputs(Timer::GetSeconds(), rgbColorOut); +} + +OVR_EXPORT const char* ovrHmd_GetLatencyTestResult(ovrHmd hmddesc) { - HMDState* p = (HMDState*)hmd; - return p->LatencyUtil.GetResultsString(); + OVR_UNUSED(hmddesc); + return NetClient::GetInstance()->LatencyUtil_GetResultsString(); } -OVR_EXPORT double ovrHmd_GetMeasuredLatencyTest2(ovrHmd hmd) +OVR_EXPORT ovrBool ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]) { - HMDState* p = (HMDState*)hmd; + HMDState* hmds = (HMDState*)hmddesc->Handle; + if (!hmds) return false; + + // TBD: Move directly into renderer + bool dk2LatencyTest = (hmds->EnabledHmdCaps & ovrHmdCap_DynamicPrediction) != 0; + if (dk2LatencyTest) + { + hmds->TimeManager.GetFrameLatencyTestDrawColor(hmds->LatencyTest2DrawColor); + if(rgbColorOut != NULL) + { + rgbColorOut[0] = hmds->LatencyTest2DrawColor[0]; + rgbColorOut[1] = hmds->LatencyTest2DrawColor[1]; + rgbColorOut[2] = hmds->LatencyTest2DrawColor[2]; + } + + if(hmds->pRenderer != NULL) + hmds->pRenderer->SetLatencyTest2Color(hmds->LatencyTest2DrawColor); + } + else + { + if(hmds->pRenderer != NULL) + hmds->pRenderer->SetLatencyTest2Color(NULL); + } + + return dk2LatencyTest; +} + + +OVR_EXPORT double ovrHmd_GetMeasuredLatencyTest2(ovrHmd hmddesc) +{ + HMDState* p = (HMDState*)hmddesc->Handle; // MA Test - float latencies[3]; - p->TimeManager.GetLatencyTimings(latencies); - return latencies[2]; - // return p->LatencyUtil2.GetMeasuredLatency(); + float latencyRender, latencyTimewarp, latencyPostPresent; + + p->TimeManager.GetLatencyTimings(latencyRender, latencyTimewarp, latencyPostPresent); + return latencyPostPresent; } -// ----------------------------------------------------------------------------------- -// ***** Property Access +//------------------------------------------------------------------------------------- +// ***** Health and Safety Warning Display interface +// -OVR_EXPORT float ovrHmd_GetFloat(ovrHmd hmd, const char* propertyName, float defaultVal) +OVR_EXPORT void ovrHmd_GetHSWDisplayState(ovrHmd hmd, ovrHSWDisplayState *hswDisplayState) { - HMDState* hmds = (HMDState*)hmd; - if (hmds) - { - return hmds->getFloatValue(propertyName, defaultVal); - } + OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; + + if (pHMDState) + { + OVR::CAPI::HSWDisplay* pHSWDisplay = pHMDState->pHSWDisplay; - return defaultVal; + if(pHSWDisplay) + pHSWDisplay->TickState(hswDisplayState); // This may internally call HSWDisplay::Display. + } } -OVR_EXPORT ovrBool ovrHmd_SetFloat(ovrHmd hmd, const char* propertyName, float value) +OVR_EXPORT ovrBool ovrHmd_DismissHSWDisplay(ovrHmd hmd) { - HMDState* hmds = (HMDState*)hmd; - if (hmds) + OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; + + if (pHMDState) { - return hmds->setFloatValue(propertyName, value); + OVR::CAPI::HSWDisplay* pHSWDisplay = pHMDState->pHSWDisplay; + + if(pHSWDisplay) + return (pHSWDisplay->Dismiss() ? 1 : 0); } + return false; } +// ----------------------------------------------------------------------------------- +// ***** Property Access +OVR_EXPORT ovrBool ovrHmd_GetBool(ovrHmd hmddesc, + const char* propertyName, + ovrBool defaultVal) +{ + OVR_ASSERT(propertyName); + if (hmddesc) + { + HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); + if (hmds) + { + return hmds->getBoolValue(propertyName, (defaultVal != 0)); + } + } -OVR_EXPORT unsigned int ovrHmd_GetFloatArray(ovrHmd hmd, const char* propertyName, - float values[], unsigned int arraySize) + return NetClient::GetInstance()->GetBoolValue(InvalidVirtualHmdId, propertyName, (defaultVal != 0)) ? 1 : 0; +} + +OVR_EXPORT ovrBool ovrHmd_SetBool(ovrHmd hmddesc, + const char* propertyName, + ovrBool value) { - HMDState* hmds = (HMDState*)hmd; - if (hmds) - { - return hmds->getFloatArray(propertyName, values, arraySize); + OVR_ASSERT(propertyName); + if (hmddesc) + { + HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); + if (hmds) + { + return hmds->setBoolValue(propertyName, value != 0) ? 1 : 0; + } } - return 0; + return NetClient::GetInstance()->SetBoolValue(InvalidVirtualHmdId, propertyName, (value != 0)) ? 1 : 0; } +OVR_EXPORT int ovrHmd_GetInt(ovrHmd hmddesc, + const char* propertyName, + int defaultVal) +{ + OVR_ASSERT(propertyName); + if (hmddesc) + { + HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); + if (hmds) + { + return hmds->getIntValue(propertyName, defaultVal); + } + } + + return NetClient::GetInstance()->GetIntValue(InvalidVirtualHmdId, propertyName, defaultVal); +} -// 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) +OVR_EXPORT ovrBool ovrHmd_SetInt(ovrHmd hmddesc, + const char* propertyName, + int value) { - HMDState* hmds = (HMDState*)hmd; - if (hmds) - { - return hmds->setFloatArray(propertyName, values, arraySize); + OVR_ASSERT(propertyName); + if (hmddesc) + { + HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); + if (hmds) + { + return hmds->setIntValue(propertyName, value) ? 1 : 0; + } } - return 0; + return NetClient::GetInstance()->SetIntValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; } -OVR_EXPORT const char* ovrHmd_GetString(ovrHmd hmd, const char* propertyName, - const char* defaultVal) +OVR_EXPORT float ovrHmd_GetFloat(ovrHmd hmddesc, + const char* propertyName, + float defaultVal) { - HMDState* hmds = (HMDState*)hmd; - if (hmds) + OVR_ASSERT(propertyName); + if (hmddesc) { - return hmds->getString(propertyName, defaultVal); + HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); + if (hmds) + { + return hmds->getFloatValue(propertyName, defaultVal); + } } - return defaultVal; + return (float)NetClient::GetInstance()->GetNumberValue(InvalidVirtualHmdId, propertyName, defaultVal); } - -/* Not needed yet. -// Get array of strings, i.e. const char* [] property. -// Returns the number of elements filled in, 0 if property doesn't exist. -// Maximum of arraySize elements will be written. -// String memory is guaranteed to exist until next call to GetString or GetStringArray, or HMD is destroyed. -OVR_EXPORT -unsigned int ovrHmd_GetStringArray(ovrHmd hmd, const char* propertyName, - const char* values[], unsigned int arraySize) +OVR_EXPORT ovrBool ovrHmd_SetFloat(ovrHmd hmddesc, + const char* propertyName, + float value) { - HMDState* hmds = (HMDState*)hmd; - if (hmds && hmds->pHMD && arraySize) - { - Profile* p = hmds->pHMD->GetProfile(); + OVR_ASSERT(propertyName); + if (hmddesc) + { + HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); + if (hmds) + { + return hmds->setFloatValue(propertyName, value) ? 1 : 0; + } + } - hmds->LastGetStringValue[0] = 0; - if (p && p->GetValue(propertyName, hmds->LastGetStringValue, sizeof(hmds->LastGetStringValue))) + return NetClient::GetInstance()->SetNumberValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; +} + +OVR_EXPORT unsigned int ovrHmd_GetFloatArray(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) { - values[0] = hmds->LastGetStringValue; - return 1; + return hmds->getFloatArray(propertyName, values, arraySize); } } + // FIXME: Currently it takes a few lines of code to do this, so just not supported for now. return 0; } -*/ -// Returns array size of a property, 0 if property doesn't exist. -// Can be used to check existence of a property. -OVR_EXPORT unsigned int ovrHmd_GetArraySize(ovrHmd hmd, const char* propertyName) +// 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) { - HMDState* hmds = (HMDState*)hmd; - if (hmds && hmds->pHMD) + OVR_ASSERT(propertyName); + OVR_ASSERT(hmddesc); + if (hmddesc) { - // For now, just access the profile. - Profile* p = hmds->pHMD->GetProfile(); - - if (p) - return p->GetNumValues(propertyName); + HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); + if (hmds) + { + return hmds->setFloatArray(propertyName, values, arraySize) ? 1 : 0; + } } + + // FIXME: Currently it takes a few lines of code to do this, so just not supported for now. return 0; } +OVR_EXPORT const char* ovrHmd_GetString(ovrHmd hmddesc, + const char* propertyName, + const char* defaultVal) +{ + OVR_ASSERT(propertyName); + if (hmddesc) + { + HMDState* hmds = (HMDState*)hmddesc->Handle; + if (hmds) + { + return hmds->getString(propertyName, defaultVal); + } + } -#ifdef __cplusplus -} // extern "C" -#endif + return NetClient::GetInstance()->GetStringValue(InvalidVirtualHmdId, propertyName, defaultVal); +} + +OVR_EXPORT ovrBool ovrHmd_SetString(ovrHmd hmddesc, + const char* propertyName, + const char* value) +{ + OVR_ASSERT(propertyName); + if (hmddesc) + { + HMDState* hmds = (HMDState*)hmddesc->Handle; + if (hmds) + { + return hmds->setString(propertyName, value) ? 1 : 0; + } + } + return NetClient::GetInstance()->SetStringValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; +} -//------------------------------------------------------------------------------------- -// ****** Special access for VRConfig +// ----------------------------------------------------------------------------------- +// ***** Logging -// Return the sensor fusion object for the purposes of magnetometer calibration. The -// function is private and is only exposed through VRConfig header declarations -OVR::SensorFusion* ovrHmd_GetSensorFusion(ovrHmd hmd) +OVR_EXPORT ovrBool ovrHmd_StartPerfLog(ovrHmd hmd, const char* fileName, const char* userData1) { - HMDState* p = (HMDState*)hmd; - return &p->SFusion; + OVR_ASSERT(fileName && fileName[0]); + + OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; + + 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::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; + if (pHMDState) + { + return pHMDState->LagStatsCSV.Stop() ? 1 : 0; + } + return false; +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/LibOVR/Src/OVR_CAPI.h b/LibOVR/Src/OVR_CAPI.h index ec4708c..ca41d3f 100644 --- a/LibOVR/Src/OVR_CAPI.h +++ b/LibOVR/Src/OVR_CAPI.h @@ -1,179 +1,247 @@ /************************************************************************************ Filename : OVR_CAPI.h -Content : C Interface to Oculus sensors and rendering. +Content : C Interface to Oculus tracking and rendering. Created : November 23, 2013 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 +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 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) - #if defined(WIN32) - #define OVR_EXPORT __declspec(dllexport) + #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 -// 2D integer +/// 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; -// 3D +/// A quaternion rotation. typedef struct ovrQuatf_ { - float x, y, z, w; + 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. + +/// Position and orientation together. typedef struct ovrPosef_ { ovrQuatf Orientation; - ovrVector3f Position; + ovrVector3f Position; } ovrPosef; -// Full pose (rigid body) configuration with first and second derivatives. +/// A full pose (rigid body) configuration with first and second derivatives. typedef struct ovrPoseStatef_ { - ovrPosef Pose; - ovrVector3f AngularVelocity; - ovrVector3f LinearVelocity; - ovrVector3f AngularAcceleration; - ovrVector3f LinearAcceleration; - double TimeInSeconds; // Absolute time of this state sample. + 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) }. +/// 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. +/// Enumerates all HMD types that we support. typedef enum { - ovrHmd_None = 0, + ovrHmd_None = 0, ovrHmd_DK1 = 3, ovrHmd_DKHD = 4, - ovrHmd_CrystalCoveProto = 5, ovrHmd_DK2 = 6, ovrHmd_Other // Some HMD other then the one in the enumeration. } ovrHmdType; -// HMD capability bits reported by device. -// +/// HMD capability bits reported by device. typedef enum { // Read-only flags. - ovrHmdCap_Present = 0x0001, // This HMD exists (as opposed to being unplugged). - ovrHmdCap_Available = 0x0002, // HMD and is sensor is available for use - // (if not owned by another app). + 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 = 0x0004, // Read only, means display driver is in compatibility mode. - - ovrHmdCap_DisplayOff = 0x0040, // Turns off Oculus HMD screen and output. - ovrHmdCap_NoMirrorToWindow = 0x2000, // Disables mirrowing of HMD output to the window; - // may improve rendering performance slightly. - */ + ovrHmdCap_ExtendDesktop = 0x0008, /// (read only) Means the display driver is in compatibility mode. // Modifiable flags (through ovrHmd_SetEnabledCaps). - ovrHmdCap_LowPersistence = 0x0080, // Supports low persistence mode. - ovrHmdCap_LatencyTest = 0x0100, // Supports pixel reading for continuous latency testing. - ovrHmdCap_DynamicPrediction = 0x0200, // Adjust prediction dynamically based on DK2 Latency. - // Support rendering without VSync for debugging - ovrHmdCap_NoVSync = 0x1000, - ovrHmdCap_NoRestore = 0x4000, + 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 = 0x1380 + ovrHmdCap_Writable_Mask = 0x32F0, + + /// These flags are currently passed into the service. May change without notice. + ovrHmdCap_Service_Mask = 0x22F0 } ovrHmdCaps; -// Sensor capability bits reported by device. -// Used with ovrHmd_StartSensor. +/// Tracking capability bits reported by the device. +/// Used with ovrHmd_ConfigureTracking. typedef enum { - ovrSensorCap_Orientation = 0x0010, // Supports orientation tracking (IMU). - ovrSensorCap_YawCorrection = 0x0020, // Supports yaw correction through magnetometer or other means. - ovrSensorCap_Position = 0x0040, // Supports positional tracking. - -} ovrSensorCaps; - -// Distortion capability bits reported by device. -// Used with ovrHmd_ConfigureRendering and ovrHmd_CreateDistortionMesh. + 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. - ovrDistortionCap_Vignette = 0x08 // Supports vignetting around the edges of the view. +{ + 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. +/// 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, @@ -181,163 +249,180 @@ typedef enum ovrEye_Count = 2 } ovrEyeType; - -// Handle to HMD; returned by ovrHmd_Create. -typedef struct ovrHmdStruct* ovrHmd; - -// This is a complete descriptor of the HMD. +/// This is a complete descriptor of the HMD. typedef struct ovrHmdDesc_ { - ovrHmd Handle; // Handle of this HMD. + /// 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; + /// Name string describing the product: "Oculus Rift DK1", etc. + const char* ProductName; const char* Manufacturer; - - // Capability bits described by ovrHmdCaps. + + /// 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 ovrSensorCaps. - unsigned int SensorCaps; - // Capability bits described by ovrDistortionCaps. + /// Capability bits described by ovrTrackingCaps. + unsigned int TrackingCaps; + /// Capability bits described by ovrDistortionCaps. unsigned int DistortionCaps; - // Resolution of the entire HMD screen (for both eyes) in pixels. - ovrSizei Resolution; - // Where monitor window should be on screen or (0,0). - ovrVector2i WindowsPos; - - // These define the recommended and maximum optical FOVs for the HMD. + /// 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. + /// Preferred eye rendering order for best performance. + /// Can help reduce latency on sideways-scanned screens. ovrEyeType EyeRenderOrder[ovrEye_Count]; - - // Display that HMD should present on. - // TBD: It may be good to remove this information relying on WidowPos instead. - // Ultimately, we may need to come up with a more convenient alternative, - // such as a API-specific functions that return adapter, ot something that will - // work with our monitor driver. - // Windows: "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC. + /// 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; + /// MacOS: + int DisplayId; -// Describes the type of positional tracking being done. -/* -typedef enum -{ - ovrPose_None, - ovrPose_HeadModel, - ovrPose_Positional -} ovrPoseType; -*/ +} ovrHmdDesc; +/// Simple type ovrHmd is used in ovrHmd_* calls. +typedef const ovrHmdDesc * ovrHmd; -// Bit flags describing the current status of sensor tracking. +/// 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_PositionConnected = 0x0020, // Position tracking HW is connected. - ovrStatus_HmdConnected = 0x0080 // HMD Display is available & connected. + 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; - -// State of the sensor at a given absolute time. -typedef struct ovrSensorState_ +/// 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 pose configuration at requested absolute time. - // One can determine the time difference between predicted and actual - // readings by comparing ovrPoseState.TimeInSeconds. - ovrPoseStatef Predicted; - // Actual recorded pose configuration based on the sensor sample at a - // moment closest to the requested time. - ovrPoseStatef Recorded; - - // Sensor temperature reading, in degrees Celsius, as sample time. - float Temperature; - // Sensor status described by ovrStatusBits. + /// 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; -} ovrSensorState; -// For now. -// TBD: Decide if this becomes a part of HMDDesc -typedef struct ovrSensorDesc_ -{ - // HID Vendor and ProductId of the device. - short VendorId; - short ProductId; - // Sensor (and display) serial number. - char SerialNumber[24]; -} ovrSensorDesc; + //// 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 data reported by ovrHmd_BeginFrameTiming(). +/// Frame timing data reported by ovrHmd_BeginFrameTiming() or ovrHmd_BeginFrame(). typedef struct ovrFrameTiming_ { - // The amount of time that has passed since the previous frame returned - // BeginFrameSeconds value, usable for movement scaling. - // This will be clamped to no more than 0.1 seconds to prevent - // excessive movement after pauses for loading or initialization. - float DeltaSeconds; - - // It is generally expected that the following hold: - // ThisFrameSeconds < TimewarpPointSeconds < NextFrameSeconds < - // EyeScanoutSeconds[EyeOrder[0]] <= ScanoutMidpointSeconds <= EyeScanoutSeconds[EyeOrder[1]] - - // Absolute time value of 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 + GPU Flush will finish, and the next frame starts. - double NextFrameSeconds; - - // Time when when half of the screen will be scanned out. Can be passes as a prediction - // value to ovrHmd_GetSensorState() go get general orientation. - double ScanoutMidpointSeconds; - // Timing points when each eye will be scanned out to display. Used for rendering each eye. - double EyeScanoutSeconds[2]; - + /// 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 though: -// (a) calling ovrHmd_GetRenderScaleAndOffset with game-rendered api, -// or (b) passing different values in ovrTexture in case of SDK-rendered distortion. +/// 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; - ovrFovPort Fov; - ovrRecti DistortedViewport; // Distortion viewport - ovrVector2f PixelsPerTanAngleAtCenter; // How many display pixels will fit in tan(angle) = 1. - ovrVector3f ViewAdjust; // Translation to be applied to view matrix. +{ + 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 APIs. -// -// The benefit of having these wrappers vs. 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. - +/// 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, @@ -349,32 +434,35 @@ typedef enum ovrRenderAPI_Count } ovrRenderAPIType; -// Platform-independent part of rendering API-configuration data. -// It is a part of ovrRenderAPIConfig, passed to ovrHmd_Configure. -typedef struct ovrRenderAPIConfigHeader_ +/// 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 RTSize; + ovrSizei BackBufferSize; // Previously named RTSize. int Multisample; } ovrRenderAPIConfigHeader; -typedef struct ovrRenderAPIConfig_ +/// Contains platform-specific information for rendering. +typedef struct OVR_ALIGNAS(8) ovrRenderAPIConfig_ { ovrRenderAPIConfigHeader Header; uintptr_t PlatformData[8]; } ovrRenderAPIConfig; -// Platform-independent part of eye texture descriptor. -// It is a part of ovrTexture, passed to ovrHmd_EndFrame. -// - If RenderViewport is all zeros, will be used. -typedef struct ovrTextureHeader_ +/// 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; + ovrRenderAPIType API; ovrSizei TextureSize; ovrRecti RenderViewport; // Pixel viewport in texture that holds eye image. + uint32_t _PAD0_; } ovrTextureHeader; -typedef struct ovrTexture_ +/// Contains platform-specific information about a texture. +typedef struct OVR_ALIGNAS(8) ovrTexture_ { ovrTextureHeader Header; uintptr_t PlatformData[8]; @@ -387,124 +475,142 @@ typedef struct ovrTexture_ // Basic steps to use the API: // // Setup: -// 1. ovrInitialize(); -// 2. ovrHMD hmd = ovrHmd_Create(0); ovrHmd_GetDesc(hmd, &hmdDesc); -// 3. Use hmdDesc and ovrHmd_GetFovTextureSize() to determine graphics configuration. -// 4. Call ovrHmd_StartSensor() to configure and initialize tracking. -// 5. Call ovrHmd_ConfigureRendering() to setup graphics for SDK rendering, -// which is the preferred approach. -// Please refer to "Game-Side Rendering" below if you prefer to do that instead. -// 5. Allocate textures as needed. +// * 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: -// 6. Call ovrHmd_BeginFrame() to get frame timing and orientation information. -// 7. Render each eye in between ovrHmd_BeginEyeRender and ovrHmd_EndEyeRender calls, -// providing the result texture to the API. -// 8. Call ovrHmd_EndFrame() to render distorted textures to the back buffer -// and present them on the Hmd. +// * 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: -// 9. ovrHmd_Destroy(hmd) -// 10. ovr_Shutdown() +// * ovrHmd_Destroy(hmd) +// * ovr_Shutdown() // -#ifdef __cplusplus +#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 are allowed before ovr_Initialize succeeds or after ovr_Shutdown. +// 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. +/// 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 and optionally fills in data about it. -// Index can [0 .. ovrHmd_Detect()-1]; index mappings can cange after each ovrHmd_Detect call. -// If not null, returned handle must be freed with ovrHmd_Destroy. +/// 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. +/// 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 error (for create, etc). +/// 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); - -//------------------------------------------------------------------------------------- - -// Returns capability bits that are enabled at this time; described by ovrHmdCaps. -// Note that this value is different font ovrHmdDesc::HmdCaps, which describes what -// capabilities are available. +/// 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 ovrHmd_LowPersistance. +/// Modifies capability bits described by ovrHmdCaps that can be modified, +/// such as ovrHmdCap_LowPersistance. OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int hmdCaps); - //------------------------------------------------------------------------------------- -// ***** Sensor Interface - -// All sensor interface functions are thread-safe, allowing sensor state to be sampled -// from different threads. -// Starts sensor sampling, enabling specified capabilities, described by ovrSensorCaps. -// - supportedSensorCaps 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 ovrSensorState.StatusFlags for real-time status. -// - requiredSensorCaps specify sensor capabilities required at the time of the call. -// If they are not available, the function will fail. Pass 0 if only specifying -// supportedSensorCaps. -OVR_EXPORT ovrBool ovrHmd_StartSensor(ovrHmd hmd, unsigned int supportedSensorCaps, - unsigned int requiredSensorCaps); -// Stops sensor sampling, shutting down internal resources. -OVR_EXPORT void ovrHmd_StopSensor(ovrHmd hmd); -// Resets sensor orientation. -OVR_EXPORT void ovrHmd_ResetSensor(ovrHmd hmd); - -// Returns sensor state reading based on the specified absolute system time. -// Pass 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_GetEyePredictedSensorState relies on this internally. -// This may also be used for more refined timing of FrontBuffer rendering logic, etc. -OVR_EXPORT ovrSensorState ovrHmd_GetSensorState(ovrHmd hmd, double absTime); - -// Returns information about a sensor. -// Only valid after StartSensor. -OVR_EXPORT ovrBool ovrHmd_GetSensorDesc(ovrHmd hmd, ovrSensorDesc* descOut); - +// ***** 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 -// Fills in description about HMD; this is the same as filled in by ovrHmd_Create. -OVR_EXPORT void ovrHmd_GetDesc(ovrHmd hmd, ovrHmdDesc* desc); - -// Calculates texture size recommended for rendering one eye within HMD, given FOV cone. -// Higher FOV will generally require larger textures to maintain quality. -// - pixelsPerDisplayPixel specifies that number of render target pixels per display -// pixel at center of distortion; 1.0 is the default value. Lower values -// can improve performance. +/// 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 APIs, inclusing Configure and frame functions are *NOT -// Thread Safe*. It is ok to use ConfigureRendering on one thread and handle +// 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. // @@ -512,279 +618,333 @@ OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovP // the render thread, which is the same thread that calls ovrHmd_BeginFrame // or ovrHmd_BeginFrameTiming. // - ovrHmd_EndFrame -// - ovrHmd_BeginEyeRender -// - ovrHmd_EndEyeRender -// - ovrHmd_GetFramePointTime -// - ovrHmd_GetEyePose // - ovrHmd_GetEyeTimewarpMatrices - //------------------------------------------------------------------------------------- -// ***** SDK-Rendering Functions +// ***** SDK Distortion Rendering Functions // These functions support rendering of distortion by the SDK through direct -// access to the underlying rendering HW, such as D3D or GL. -// This is the recommended approach, as it allows for better support or future -// Oculus hardware and a range of low-level optimizations. - - -// Configures rendering; fills in computed render parameters. -// This function can be called multiple times to change rendering settings. -// The users pass in two eye view descriptors that are used to -// generate complete rendering information for each eye in eyeRenderDescOut[2]. -// -// - apiConfig provides D3D/OpenGL specific parameters. Pass null -// to shutdown rendering and release all resources. -// - distortionCaps describe distortion settings that will be applied. -// +// 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, + const ovrRenderAPIConfig* apiConfig, unsigned int distortionCaps, const ovrFovPort eyeFovIn[2], ovrEyeRenderDesc eyeRenderDescOut[2] ); -// Begins a frame, returning timing and orientation information useful for simulation. -// This should be called in the beginning of game rendering loop (on render thread). -// This function relies on ovrHmd_BeginFrameTiming for some of its functionality. -// Pass 0 for frame index if not using GetFrameTiming. +/// 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 frame, rendering textures to frame buffer. This may perform distortion and scaling -// internally, assuming is it not delegated to another thread. -// Must be called on the same thread as BeginFrame. Calls ovrHmd_BeginEndTiming internally. -// *** This Function will to Present/SwapBuffers and potentially wait for GPU Sync ***. -OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd); - - -// Marks beginning of eye rendering. Must be called on the same thread as BeginFrame. -// This function uses ovrHmd_GetEyePose to predict sensor state that should be -// used rendering the specified eye. -// This combines current absolute time with prediction that is appropriate for this HMD. -// It is ok to call ovrHmd_BeginEyeRender() on both eyes before calling ovrHmd_EndEyeRender. -// If rendering one eye at a time, it is best to render eye specified by -// HmdDesc.EyeRenderOrder[0] first. -OVR_EXPORT ovrPosef ovrHmd_BeginEyeRender(ovrHmd hmd, ovrEyeType eye); - -// Marks the end of eye rendering and submits the eye texture for display after it is ready. -// Rendering viewport within the texture can change per frame if necessary. -// Specified texture may be presented immediately or wait until ovrHmd_EndFrame based -// on the implementation. The API performs distortion and scaling internally. -// 'renderPose' will typically be the value returned from ovrHmd_BeginEyeRender, but can -// be different if a different pose was used for rendering. -OVR_EXPORT void ovrHmd_EndEyeRender(ovrHmd hmd, ovrEyeType eye, - ovrPosef renderPose, ovrTexture* eyeTexture); - +/// 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); //------------------------------------------------------------------------------------- -// ***** Game-Side Rendering Functions +// ***** Client Distortion Rendering Functions -// These functions provide distortion data and render timing support necessary to allow -// game rendering of distortion. Game-side rendering involves the following steps: +// 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 desired texture size and Fov. +// 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 distortion mesh. // -// 3. Use ovrHmd_BeginFrameTiming, ovrHmd_GetEyePose and ovrHmd_BeginFrameTiming -// in the rendering loop to obtain timing and predicted view orientation for -// each eye. -// - If relying on timewarp, use ovr_WaitTillTime after rendering+flush, followed -// by ovrHmd_GetEyeTimewarpMatrices to obtain timewarp matrices used -// in distortion pixel shader to reduce latency. +// 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 distortion viewport, view adjust and other rendering for the specified -// eye. This can be used instead of ovrHmd_ConfigureRendering to help setup rendering on -// the game side. +/// 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 for distortion; this is intended to be converted into -// the engine-specific format. -// Some fields may be unused based on ovrDistortionCaps selected. TexG and TexB, for example, -// are not used if chromatic correction is not requested. +/// 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 Pos; - 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 TexR; - ovrVector2f TexG; - ovrVector2f TexB; + 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. +/// 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; - unsigned short* pIndexData; - unsigned int VertexCount; - unsigned int IndexCount; + 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; user should rely on -// appropriate shaders based on their settings. -// Distortion mesh data will be allocated and stored 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. +/// 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 ); + ovrDistortionMesh *meshData); +OVR_EXPORT ovrBool ovrHmd_CreateDistortionMeshDebug( ovrHmd hmddesc, + ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, + ovrDistortionMesh *meshData, + float debugEyeReliefOverrideInMetres); + -// Frees distortion mesh allocated by ovrHmd_GenerateDistortionMesh. meshData elements -// are set to null and zeroes after the call. +/// 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. +/// 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 to RenderThread for processing. +/// 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 Render 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. +/// 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 game-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. +/// 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. +/// 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); -// Predicts and returns Pose that should be used rendering the specified eye. -// Must be called between ovrHmd_BeginFrameTiming & ovrHmd_EndFrameTiming. -OVR_EXPORT ovrPosef ovrHmd_GetEyePose(ovrHmd hmd, ovrEyeType eye); - -// Computes timewarp matrices used by distortion mesh shader, these are used to adjust -// for orientation change since the last call to ovrHmd_GetEyePose for 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]); //------------------------------------------------------------------------------------- // ***** Stateless math setup functions -// Used to generate projection from ovrEyeDesc::Fov. +/// 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 +/// 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 eyeViewAdjustX); + float orthoDistance, float hmdToEyeViewOffsetX); -// Returns global, absolute high-resolution time in seconds. This is the same -// value as used in sensor messages. +/// 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. +/// 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. +/// 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. +/// 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 latency for HMDs that support internal latency testing via the -// pixel-read back method (-1 for invalid or N/A) -OVR_EXPORT double ovrHmd_GetMeasuredLatencyTest2(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 +// -// ----------------------------------------------------------------------------------- -// ***** Property Access - -// NOTICE: This is experimental part of API that is likely to go away or change. - -// These allow accessing different properties of the HMD and profile. -// Some of the properties may go away with profile/HMD versions, so software should -// use defaults and/or proper fallbacks. -// - -// For now, access profile entries; this will change. -#if !defined(OVR_KEY_USER) - - #define OVR_KEY_USER "User" - #define OVR_KEY_NAME "Name" - #define OVR_KEY_GENDER "Gender" - #define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" - #define OVR_KEY_EYE_HEIGHT "EyeHeight" - #define OVR_KEY_IPD "IPD" - #define OVR_KEY_NECK_TO_EYE_HORIZONTAL "NeckEyeHori" - #define OVR_KEY_NECK_TO_EYE_VERTICAL "NeckEyeVert" - - #define OVR_DEFAULT_GENDER "Male" - #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.12f - #define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.12f -#endif - - -// 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. +/// 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. +/// 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. +/// 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, +/// 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); -// Returns array size of a property, 0 if property doesn't exist. -// Can be used to check existence of a property. -OVR_EXPORT unsigned int ovrHmd_GetArraySize(ovrHmd hmd, const char* propertyName); +/// 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 +#ifdef __cplusplus } // extern "C" #endif -#endif // OVR_CAPI_h +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + + +#endif // OVR_CAPI_h diff --git a/LibOVR/Src/OVR_CAPI_D3D.h b/LibOVR/Src/OVR_CAPI_D3D.h index b21de1d..25a6b2e 100644 --- a/LibOVR/Src/OVR_CAPI_D3D.h +++ b/LibOVR/Src/OVR_CAPI_D3D.h @@ -5,16 +5,16 @@ Content : D3D specific structures used by the CAPI interface. Created : November 7, 2013 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -26,6 +26,9 @@ 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 @@ -38,37 +41,53 @@ limitations under the License. //----------------------------------------------------------------------------------- // ***** 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 ovrD3D11ConfigData +/// Used to configure slave D3D rendering (i.e. for devices created externally). +struct OVR_ALIGNAS(8) ovrD3D11ConfigData { - // General device settings. - ovrRenderAPIConfigHeader Header; - ID3D11Device* pDevice; - ID3D11DeviceContext* pDeviceContext; - ID3D11RenderTargetView* pBackBufferRT; - IDXGISwapChain* pSwapChain; + /// 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 ovrD3D11TextureData +/// Used to pass D3D11 eye texture data to ovrHmd_EndFrame. +struct OVR_ALIGNAS(8) ovrD3D11TextureData { - // General device settings. + /// 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; }; @@ -76,17 +95,21 @@ union ovrD3D11Texture #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 ovrD3D10ConfigData +/// Used to configure slave D3D rendering (i.e. for devices created externally). +struct OVR_ALIGNAS(8) ovrD3D10ConfigData { - // General device settings. + /// General device settings. ovrRenderAPIConfigHeader Header; ID3D10Device* pDevice; - void* Unused; + void* Unused1; // pDeviceContext in DX11 ID3D10RenderTargetView* pBackBufferRT; + void* Unused2; // pBackBufferUAV in DX11 IDXGISwapChain* pSwapChain; }; @@ -96,10 +119,10 @@ union ovrD3D10Config ovrD3D10ConfigData D3D10; }; -// Used to pass D3D10 eye texture data to ovrHmd_EndFrame. -struct ovrD3D10TextureData +/// Used to pass D3D10 eye texture data to ovrHmd_EndFrame. +struct OVR_ALIGNAS(8) ovrD3D10TextureData { - // General device settings. + /// General device settings. ovrTextureHeader Header; ID3D10Texture2D* pTexture; ID3D10ShaderResourceView* pSRView; @@ -113,11 +136,13 @@ union ovrD3D10Texture #elif defined(OVR_D3D_VERSION) && (OVR_D3D_VERSION == 9) +#include + //----------------------------------------------------------------------------------- // ***** D3D9 Specific // Used to configure D3D9 rendering -struct ovrD3D9ConfigData +struct OVR_ALIGNAS(8) ovrD3D9ConfigData { // General device settings. ovrRenderAPIConfigHeader Header; @@ -133,7 +158,7 @@ union ovrD3D9Config }; // Used to pass D3D9 eye texture data to ovrHmd_EndFrame. -struct ovrD3D9TextureData +struct OVR_ALIGNAS(8) ovrD3D9TextureData { // General device settings. ovrTextureHeader Header; diff --git a/LibOVR/Src/OVR_CAPI_GL.h b/LibOVR/Src/OVR_CAPI_GL.h index ceabb74..2aa846f 100644 --- a/LibOVR/Src/OVR_CAPI_GL.h +++ b/LibOVR/Src/OVR_CAPI_GL.h @@ -5,7 +5,7 @@ Content : GL specific structures used by the CAPI interface. Created : November 7, 2013 Authors : Lee Cooper -Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. +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 @@ -15,59 +15,62 @@ otherwise accompanies this software in either electronic or hard copy form. #ifndef OVR_CAPI_GL_h #define OVR_CAPI_GL_h -#include "OVR_CAPI.h" - -//----------------------------------------------------------------------------------- -// ***** GL Specific +/// @file OVR_CAPI_GL.h +/// OpenGL rendering support. -#if defined(OVR_OS_WIN32) - #include - #include - #include - #include -#elif defined(OVR_OS_MAC) - #include - #include - #include +#include "OVR_CAPI.h" +#if defined(__APPLE__) + #include #else #include - #include - #include #endif -// Used to configure slave GL rendering (i.e. for devices created externally). -typedef struct ovrGLConfigData_s +/// Used to configure slave GL rendering (i.e. for devices created externally). +typedef struct OVR_ALIGNAS(8) ovrGLConfigData_s { - // General device settings. + /// General device settings. ovrRenderAPIConfigHeader Header; #if defined(OVR_OS_WIN32) - HWND Window; -#elif defined(OVR_OS_LINUX) - Display* Disp; - Window Win; + /// 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; - ovrGLConfigData OGL; + /// OpenGL-specific settings. + ovrGLConfigData OGL; }; -// Used to pass GL eye texture data to ovrHmd_EndFrame. -typedef struct ovrGLTextureData_s +/// Used to pass GL eye texture data to ovrHmd_EndFrame. +typedef struct OVR_ALIGNAS(8) ovrGLTextureData_s { - // General device settings. - ovrTextureHeader Header; + /// 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 { - ovrTexture Texture; - ovrGLTextureData OGL; + /// 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 new file mode 100644 index 0000000..13451e5 --- /dev/null +++ b/LibOVR/Src/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/Src/OVR_Common_HMDDevice.cpp b/LibOVR/Src/OVR_Common_HMDDevice.cpp deleted file mode 100644 index 6bedcbe..0000000 --- a/LibOVR/Src/OVR_Common_HMDDevice.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Common_HMDDevice.cpp -Content : -Created : -Authors : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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. - -*************************************************************************************/ - -// Should be #included from the relevant OVR_YourPlatformHere_HMDDevice.cpp - -#include "Kernel/OVR_Alg.h" - -//------------------------------------------------------------------------------------- -// ***** HMDDeviceCreateDesc - -DeviceBase* HMDDeviceCreateDesc::NewDeviceInstance() -{ - return new HMDDevice(this); -} - -void HMDDeviceCreateDesc::SetScreenParameters(int x, int y, - int hres, int vres, - float hsize, float vsize, - float vCenterFromTopInMeters, float lensSeparationInMeters) -{ - Desktop.X = x; - Desktop.Y = y; - ResolutionInPixels = Sizei(hres, vres); - ScreenSizeInMeters = Sizef(hsize, vsize); - VCenterFromTopInMeters = vCenterFromTopInMeters; - LensSeparationInMeters = lensSeparationInMeters; - - Contents |= Contents_Screen; -} - - -void HMDDeviceCreateDesc::SetDistortion(const float* dks) -{ - for (int i = 0; i < 4; i++) - DistortionK[i] = dks[i]; - // TODO: add DistortionEqn - Contents |= Contents_Distortion; -} - -HmdTypeEnum HMDDeviceCreateDesc::GetHmdType() const -{ - // Determine the HMD model - // The closest thing we have to a dependable model indicator are the - // the screen characteristics. Additionally we can check the sensor - // (on attached devices) to further refine our guess - HmdTypeEnum hmdType = HmdType_Unknown; - - if ( ResolutionInPixels.w == 1280 ) - { - if ( ScreenSizeInMeters.w > 0.1497f && ScreenSizeInMeters.w < 0.1498f ) - hmdType = HmdType_DK1; - else - hmdType = HmdType_DKProto; - } - else if ( ResolutionInPixels.w == 1920 ) - { - // DKHD protoypes, all 1920x1080 - if ( ScreenSizeInMeters.w > 0.1209f && ScreenSizeInMeters.w < 0.1210f ) - { - // Screen size 0.12096 x 0.06804 - hmdType = HmdType_DKHDProto; - } - else if ( ScreenSizeInMeters.w > 0.1257f && ScreenSizeInMeters.w < 0.1258f ) - { - // Screen size 0.125 x 0.071 - // Could be a HmdType_DKHDProto566Mi, HmdType_CrystalCoveProto, or DK2 - // - most likely the latter. - hmdType = HmdType_DK2; - - // If available, check the sensor to determine exactly which variant this is - if (pDevice) - { - Ptr sensor = *((HMDDevice*)pDevice)->GetSensor(); - - SensorInfo sinfo; - if (sensor && sensor->GetDeviceInfo(&sinfo)) - { - if (sinfo.ProductId == 1) - { - hmdType = HmdType_DKHDProto566Mi; - } - else - { // Crystal Cove uses 0.# firmware, DK2 uses 1.# - int firm_major = Alg::DecodeBCD((sinfo.Version >> 8) & 0x00ff); - int firm_minor = Alg::DecodeBCD(sinfo.Version & 0xff); - OVR_UNUSED(firm_minor); - if (firm_major == 0) - hmdType = HmdType_CrystalCoveProto; - else - hmdType = HmdType_DK2; - } - } - } - } - else if (ScreenSizeInMeters.w > 0.1295f && ScreenSizeInMeters.w < 0.1297f) - { - // Screen size 0.1296 x 0.0729 - hmdType = HmdType_DKHD2Proto; - } - } - - OVR_ASSERT( hmdType != HmdType_Unknown ); - return hmdType; -} - -bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const -{ - if ((info->InfoClassType != Device_HMD) && - (info->InfoClassType != Device_None)) - return false; - - HmdTypeEnum hmdType = GetHmdType(); - char const* deviceName = "Oculus HMD"; - switch (hmdType) - { - case HmdType_DKProto: deviceName = "Oculus Rift Prototype"; break; - case HmdType_DK1: deviceName = "Oculus Rift DK1"; break; - case HmdType_DKHDProto: deviceName = "Oculus Rift DKHD"; break; - case HmdType_DKHD2Proto: deviceName = "Oculus Rift DKHD2"; break; - case HmdType_DKHDProto566Mi: deviceName = "Oculus Rift DKHD 566 Mi"; break; - case HmdType_CrystalCoveProto: deviceName = "Oculus Rift Crystal Cove"; break; - case HmdType_DK2: deviceName = "Oculus Rift DK2"; break; - default: deviceName = "Oculus HMD"; break; - } - - info->ProductName = deviceName; - info->Manufacturer = "Oculus VR"; - info->Type = Device_HMD; - info->Version = 0; - - // Display detection. - if (info->InfoClassType == Device_HMD) - { - HMDInfo* hmdInfo = static_cast(info); - - hmdInfo->HmdType = hmdType; - hmdInfo->DesktopX = Desktop.X; - hmdInfo->DesktopY = Desktop.Y; - hmdInfo->ResolutionInPixels = ResolutionInPixels; - hmdInfo->ScreenSizeInMeters = ScreenSizeInMeters; // Includes ScreenGapSizeInMeters - hmdInfo->ScreenGapSizeInMeters = 0.0f; - hmdInfo->CenterFromTopInMeters = VCenterFromTopInMeters; - hmdInfo->LensSeparationInMeters = LensSeparationInMeters; - // TODO: any other information we get from the hardware itself should be added to this list - - switch ( hmdInfo->HmdType ) - { - case HmdType_DKProto: - // WARNING - estimated. - hmdInfo->Shutter.Type = HmdShutter_RollingTopToBottom; - hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 60.0f ); - hmdInfo->Shutter.VsyncToFirstScanline = 0.000052f; - hmdInfo->Shutter.FirstScanlineToLastScanline = 0.016580f; - hmdInfo->Shutter.PixelSettleTime = 0.015f; // estimated. - hmdInfo->Shutter.PixelPersistence = hmdInfo->Shutter.VsyncToNextVsync; // Full persistence - break; - case HmdType_DK1: - // Data from specs. - hmdInfo->Shutter.Type = HmdShutter_RollingTopToBottom; - hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 60.0f ); - hmdInfo->Shutter.VsyncToFirstScanline = 0.00018226f; - hmdInfo->Shutter.FirstScanlineToLastScanline = 0.01620089f; - hmdInfo->Shutter.PixelSettleTime = 0.017f; // estimated. - hmdInfo->Shutter.PixelPersistence = hmdInfo->Shutter.VsyncToNextVsync; // Full persistence - break; - case HmdType_DKHDProto: - // Data from specs. - hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft; - hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 60.0f ); - hmdInfo->Shutter.VsyncToFirstScanline = 0.0000859f; - hmdInfo->Shutter.FirstScanlineToLastScanline = 0.0164948f; - hmdInfo->Shutter.PixelSettleTime = 0.012f; // estimated. - hmdInfo->Shutter.PixelPersistence = hmdInfo->Shutter.VsyncToNextVsync; // Full persistence - break; - case HmdType_DKHD2Proto: - // Data from specs. - hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft; - hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 60.0f ); - hmdInfo->Shutter.VsyncToFirstScanline = 0.000052f; - hmdInfo->Shutter.FirstScanlineToLastScanline = 0.016580f; - hmdInfo->Shutter.PixelSettleTime = 0.015f; // estimated. - hmdInfo->Shutter.PixelPersistence = hmdInfo->Shutter.VsyncToNextVsync; // Full persistence - break; - case HmdType_DKHDProto566Mi: -#if 0 - // Low-persistence global shutter - hmdInfo->Shutter.Type = HmdShutter_Global; - hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 76.0f ); - hmdInfo->Shutter.VsyncToFirstScanline = 0.0000273f + 0.0131033f; // Global shutter - first visible scan line is actually the last! - hmdInfo->Shutter.FirstScanlineToLastScanline = 0.000f; // Global shutter - all visible at once. - hmdInfo->Shutter.PixelSettleTime = 0.0f; // <100us - hmdInfo->Shutter.PixelPersistence = 0.18f * hmdInfo->Shutter.VsyncToNextVsync; // Confgurable - currently set to 18% of total frame. -#else - // Low-persistence rolling shutter - hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft; - hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 76.0f ); - hmdInfo->Shutter.VsyncToFirstScanline = 0.0000273f; - hmdInfo->Shutter.FirstScanlineToLastScanline = 0.0131033f; - hmdInfo->Shutter.PixelSettleTime = 0.0f; // <100us - hmdInfo->Shutter.PixelPersistence = 0.18f * hmdInfo->Shutter.VsyncToNextVsync; // Confgurable - currently set to 18% of total frame. -#endif - break; - case HmdType_CrystalCoveProto: - // Low-persistence rolling shutter - hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft; - hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 76.0f ); - hmdInfo->Shutter.VsyncToFirstScanline = 0.0000273f; - hmdInfo->Shutter.FirstScanlineToLastScanline = 0.0131033f; - hmdInfo->Shutter.PixelSettleTime = 0.0f; // <100us - hmdInfo->Shutter.PixelPersistence = 0.18f * hmdInfo->Shutter.VsyncToNextVsync; // Confgurable - currently set to 18% of total frame. - break; - case HmdType_DK2: - // Low-persistence rolling shutter - hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft; - hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 76.0f ); - hmdInfo->Shutter.VsyncToFirstScanline = 0.0000273f; - hmdInfo->Shutter.FirstScanlineToLastScanline = 0.0131033f; - hmdInfo->Shutter.PixelSettleTime = 0.0f; // <100us - hmdInfo->Shutter.PixelPersistence = 0.18f * hmdInfo->Shutter.VsyncToNextVsync; // Confgurable - currently set to 18% of total frame. - break; - default: OVR_ASSERT ( false ); break; - } - - - OVR_strcpy(hmdInfo->DisplayDeviceName, sizeof(hmdInfo->DisplayDeviceName), - DisplayDeviceName.ToCStr()); -#if defined(OVR_OS_WIN32) - // Nothing special for Win32. -#elif defined(OVR_OS_MAC) - hmdInfo->DisplayId = DisplayId; -#elif defined(OVR_OS_LINUX) - hmdInfo->DisplayId = DisplayId; -#elif defined(OVR_OS_ANDROID) - hmdInfo->DisplayId = DisplayId; -#else -#error Unknown platform -#endif - - } - - return true; -} - - - - - -//------------------------------------------------------------------------------------- -// ***** HMDDevice - -HMDDevice::HMDDevice(HMDDeviceCreateDesc* createDesc) - : OVR::DeviceImpl(createDesc, 0) -{ -} -HMDDevice::~HMDDevice() -{ -} - -bool HMDDevice::Initialize(DeviceBase* parent) -{ - pParent = parent; - return true; -} -void HMDDevice::Shutdown() -{ - ProfileName.Clear(); - pCachedProfile.Clear(); - pParent.Clear(); -} - -Profile* HMDDevice::GetProfile() -{ - // Loads and returns a cached profile based on this device and current user - if (pCachedProfile == NULL) - { - ProfileManager* mgr = GetManager()->GetProfileManager(); - const char* profile_name = GetProfileName(); - if (profile_name && profile_name[0]) - pCachedProfile = *mgr->GetProfile(this, profile_name); - - if (pCachedProfile == NULL) - pCachedProfile = *mgr->GetDefaultProfile(this); - - } - return pCachedProfile.GetPtr(); -} - -const char* HMDDevice::GetProfileName() -{ - if (ProfileName.IsEmpty()) - { // If the profile name has not been initialized then - // retrieve the stored default user for this specific device - ProfileManager* mgr = GetManager()->GetProfileManager(); - const char* name = mgr->GetDefaultUser(this); - ProfileName = name; - } - - return ProfileName.ToCStr(); -} - -bool HMDDevice::SetProfileName(const char* name) -{ - if (ProfileName == name) - return true; // already set - - // Flush the old profile - pCachedProfile.Clear(); - if (!name) - { - ProfileName.Clear(); - return false; - } - - // Set the name and attempt to cache the profile - ProfileName = name; - if (GetProfile()) - { - return true; - } - else - { - ProfileName.Clear(); - return false; - } -} - -OVR::SensorDevice* HMDDevice::GetSensor() -{ - // Just return first sensor found since we have no way to match it yet. - - // Create DK2 sensor if it exists otherwise create first DK1 sensor. - SensorDevice* sensor = NULL; - - DeviceEnumerator enumerator = GetManager()->EnumerateDevices(); - - while(enumerator.GetType() != Device_None) - { - SensorInfo info; - enumerator.GetDeviceInfo(&info); - - if (info.ProductId == Device_Tracker2_ProductId) - { - sensor = enumerator.CreateDevice(); - break; - } - - enumerator.Next(); - } - - if (sensor == NULL) - { - sensor = GetManager()->EnumerateDevices().CreateDevice(); - } - - if (sensor) - { - sensor->SetCoordinateFrame(SensorDevice::Coord_HMD); - } - - return sensor; -} diff --git a/LibOVR/Src/OVR_Device.h b/LibOVR/Src/OVR_Device.h deleted file mode 100644 index 52a41f9..0000000 --- a/LibOVR/Src/OVR_Device.h +++ /dev/null @@ -1,1135 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_Device.h -Content : Definition of HMD-related Device interfaces -Created : September 21, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_Device_h -#define OVR_Device_h - -#include "OVR_DeviceConstants.h" -#include "OVR_DeviceHandle.h" -#include "OVR_DeviceMessages.h" -#include "OVR_HIDDeviceBase.h" - -#include "Kernel/OVR_Atomic.h" -#include "Kernel/OVR_RefCount.h" -#include "Kernel/OVR_String.h" - - -namespace OVR { - -// Declared externally -class Profile; -class ProfileManager; // << Should be renamed for consistency - -// Forward declarations -class SensorDevice; -class DeviceCommon; -class DeviceManager; - -// MessageHandler is a base class from which users derive to receive messages, -// its OnMessage handler will be called for messages once it is installed on -// a device. Same message handler can be installed on multiple devices. -class MessageHandler -{ - friend class MessageHandlerImpl; -public: - MessageHandler(); - virtual ~MessageHandler(); - - // Returns 'true' if handler is currently installed on any devices. - bool IsHandlerInstalled() const; - - // Should be called from derived class destructor to avoid handler - // being called after it exits. - void RemoveHandlerFromDevices(); - - // Returns a pointer to the internal lock object that is locked by a - // background thread while OnMessage() is called. - // This lock guaranteed to survive until ~MessageHandler. - Lock* GetHandlerLock() const; - - - virtual void OnMessage(const Message&) { } - - // Determines if handler supports a specific message type. Can - // be used to filter out entire message groups. The result - // returned by this function shouldn't change after handler creation. - virtual bool SupportsMessageType(MessageType) const { return true; } - -private: - UPInt Internal[8]; -}; - - -//------------------------------------------------------------------------------------- -// ***** DeviceBase - -// DeviceBase is the base class for all OVR Devices. It provides the following basic -// functionality: -// - Reports device type, manager, and associated parent (if any). -// - Supports installable message handlers, which are notified of device events. -// - Device objects are created through DeviceHandle::CreateDevice or more commonly -// through DeviceEnumerator<>::CreateDevice. -// - Created devices are reference counted, starting with RefCount of 1. -// - Device is resources are cleaned up when it is Released, although its handles -// may survive longer if referenced. - -class DeviceBase : public NewOverrideBase -{ - friend class DeviceHandle; - friend class DeviceManagerImpl; -public: - - // Enumerating DeviceBase enumerates all devices. - enum { EnumDeviceType = Device_All }; - - virtual ~DeviceBase() { } - virtual void AddRef(); - virtual void Release(); - - virtual DeviceBase* GetParent() const; - virtual DeviceManager* GetManager() const; - - virtual void AddMessageHandler(MessageHandler* handler); - - virtual DeviceType GetType() const; - virtual bool GetDeviceInfo(DeviceInfo* info) const; - - // Returns true if device is connected and usable - virtual bool IsConnected(); - - // returns the MessageHandler's lock - Lock* GetHandlerLock() const; -protected: - // Internal - virtual DeviceCommon* getDeviceCommon() const = 0; -}; - - -//------------------------------------------------------------------------------------- -// ***** DeviceInfo - -// DeviceInfo describes a device and its capabilities, obtained by calling -// GetDeviceInfo. This base class only contains device-independent functionality; -// users will normally use a derived HMDInfo or SensorInfo classes for more -// extensive device info. - -class DeviceInfo -{ -public: - DeviceInfo() : InfoClassType(Device_None), Type(Device_None), Version(0) - {} - - // Type of device for which DeviceInfo is intended. - // This will be set to Device_HMD for HMDInfo structure, note that this may be - // different form the actual device type since (Device_None) is valid. - const DeviceType InfoClassType; - // Type of device this describes. This must be the same as InfoClassType when - // InfoClassType != Device_None. - DeviceType Type; - // Name string describing the product: "Oculus Rift DK1", etc. - String ProductName; - String Manufacturer; - unsigned Version; - -protected: - DeviceInfo(DeviceType type) : InfoClassType(type), Type(type), Version(0) - {} - void operator = (const DeviceInfo&) { OVR_ASSERT(0); } // Assignment not allowed. -}; - - -//------------------------------------------------------------------------------------- -// DeviceEnumerationArgs provides device enumeration argumenrs for DeviceManager::EnumerateDevicesEx. -class DeviceEnumerationArgs -{ -public: - DeviceEnumerationArgs(DeviceType enumType, bool availableOnly) - : EnumType(enumType), AvailableOnly(availableOnly) - { } - - // Helper; returns true if args match our enumeration criteria. - bool MatchRule(DeviceType type, bool available) const - { - return ((EnumType == type) || (EnumType == Device_All)) && - (available || !AvailableOnly); - } - -protected: - DeviceType EnumType; - bool AvailableOnly; -}; - - -// DeviceEnumerator<> is used to enumerate and create devices of specified class, -// it is returned by calling MeviceManager::EnumerateDevices. Initially, the enumerator will -// refer to the first device of specified type. Additional devices can be accessed by -// calling Next(). - -template -class DeviceEnumerator : public DeviceHandle -{ - friend class DeviceManager; - friend class DeviceManagerImpl; -public: - DeviceEnumerator() - : DeviceHandle(), EnumArgs(Device_None, true) { } - - // Next advances enumeration to the next device that first criteria. - // Returns false if no more devices exist that match enumeration criteria. - bool Next() { return enumerateNext(EnumArgs); } - - // Creates an instance of the device referenced by enumerator; returns null - // if enumerator does not refer to a valid device or device is unavailable. - // If device was already created, the same object with incremented ref-count is returned. - T* CreateDevice() { return static_cast(DeviceHandle::CreateDevice()); } - -protected: - DeviceEnumerator(const DeviceHandle &dev, const DeviceEnumerationArgs& args) - : DeviceHandle(dev), EnumArgs(args) - { } - - DeviceEnumerationArgs EnumArgs; -}; - -//------------------------------------------------------------------------------------- -// ***** DeviceManager - -// DeviceManager maintains and provides access to devices supported by OVR, such as -// HMDs and sensors. A single instance of DeviceManager is normally created at -// program startup, allowing devices to be enumerated and created. DeviceManager is -// reference counted and is AddRefed by its created child devices, causing it to -// always be the last object that is released. -// -// Install MessageHandler on DeviceManager to detect when devices are inserted or removed. -// -// The following code will create the manager and its first available HMDDevice, -// and then release it when not needed: -// -// DeviceManager* manager = DeviceManager::Create(); -// HMDDevice* hmd = manager->EnumerateDevices().CreateDevice(); -// -// if (hmd) hmd->Release(); -// if (manager) manager->Release(); - - -class DeviceManager : public DeviceBase -{ -public: - - DeviceManager() - { } - - // DeviceBase implementation. - virtual DeviceType GetType() const { return Device_Manager; } - virtual DeviceManager* GetManager() const { return const_cast(this); } - - // Every DeviceManager has an associated profile manager, which us used to store - // user settings that may affect device behavior. - virtual ProfileManager* GetProfileManager() const = 0; - - - // EnumerateDevices enumerates all of the available devices of the specified class, - // returning an enumerator that references the first device. An empty enumerator is - // returned if no devices are available. The following APIs are exposed through - // DeviceEnumerator: - // DeviceEnumerator::GetType() - Check device type. Returns Device_None - // if no device was found/pointed to. - // DeviceEnumerator::GetDeviceInfo() - Get more information on device. - // DeviceEnumerator::CreateDevice() - Create an instance of device. - // DeviceEnumerator::Next() - Move onto next device. - template - DeviceEnumerator EnumerateDevices(bool availableOnly = true) - { - // TBD: A cleaner (but less efficient) alternative is though enumeratorFromHandle. - DeviceEnumerator<> e = EnumerateDevicesEx(DeviceEnumerationArgs((DeviceType)D::EnumDeviceType, availableOnly)); - return *reinterpret_cast*>(&e); - } - - // EnumerateDevicesEx provides internal implementation for device enumeration, enumerating - // devices based on dynamically specified DeviceType in DeviceEnumerationArgs. - // End users should call DeumerateDevices<>() instead. - virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args) = 0; - - // Creates a new DeviceManager. Only one instance of DeviceManager should be created at a time. - static DeviceManager* Create(); - - // Static constant for this device type, used in template cast type checks. - enum { EnumDeviceType = Device_Manager }; - - - - // Adds a device (DeviceCreateDesc*) into Devices. Returns NULL, - // if unsuccessful or device is already in the list. - virtual Ptr AddDevice_NeedsLock(const DeviceCreateDesc& createDesc) = 0; - -protected: - DeviceEnumerator<> enumeratorFromHandle(const DeviceHandle& h, const DeviceEnumerationArgs& args) - { return DeviceEnumerator<>(h, args); } - - DeviceManager* getThis() { return this; } -}; - - - -//------------------------------------------------------------------------------------- -// ***** HMDInfo - -// This structure describes various aspects of the HMD allowing us to configure rendering. -// -// Currently included data: -// - Physical screen dimensions, resolution, and eye distances. -// (some of these will be configurable with a tool in the future). -// These arguments allow us to properly setup projection across HMDs. -// - DisplayDeviceName for identifying HMD screen; system-specific interpretation. -// -// TBD: -// - Power on/ off? -// - Sensor rates and capabilities -// - Distortion radius/variables -// - Screen update frequency -// - Distortion needed flag -// - Update modes: -// Set update mode: Stereo (both sides together), mono (same in both eyes), -// Alternating, Alternating scan-lines. - -class HMDInfo : public DeviceInfo -{ -public: - // Characteristics of the HMD screen and enclosure - HmdTypeEnum HmdType; - Size ResolutionInPixels; - Size ScreenSizeInMeters; - float ScreenGapSizeInMeters; - float CenterFromTopInMeters; - float LensSeparationInMeters; - - // Timing & shutter data. All values in seconds. - struct ShutterInfo - { - HmdShutterTypeEnum Type; - float VsyncToNextVsync; // 1/framerate - float VsyncToFirstScanline; // for global shutter, vsync->shutter open. - float FirstScanlineToLastScanline; // for global shutter, will be zero. - float PixelSettleTime; // estimated. - float PixelPersistence; // Full persistence = 1/framerate. - } Shutter; - - // Desktop coordinate position of the screen (can be negative; may not be present on all platforms) - int DesktopX; - int DesktopY; - - // Windows: - // "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC. - char DisplayDeviceName[32]; - - // MacOS: - int DisplayId; - - - // Constructor initializes all values to 0s. - // To create a "virtualized" HMDInfo, use CreateDebugHMDInfo instead. - HMDInfo() - : DeviceInfo(Device_HMD), - HmdType(HmdType_None), - ResolutionInPixels(0), - ScreenSizeInMeters(0.0f), - ScreenGapSizeInMeters(0.0f), - CenterFromTopInMeters(0), - LensSeparationInMeters(0), - DisplayId(0) - { - DesktopX = 0; - DesktopY = 0; - DisplayDeviceName[0] = 0; - Shutter.Type = HmdShutter_LAST; - Shutter.VsyncToNextVsync = 0.0f; - Shutter.VsyncToFirstScanline = 0.0f; - Shutter.FirstScanlineToLastScanline = 0.0f; - Shutter.PixelSettleTime = 0.0f; - Shutter.PixelPersistence = 0.0f; - } - - // Operator = copies local fields only (base class must be correct already) - void operator = (const HMDInfo& src) - { - HmdType = src.HmdType; - ResolutionInPixels = src.ResolutionInPixels; - ScreenSizeInMeters = src.ScreenSizeInMeters; - ScreenGapSizeInMeters = src.ScreenGapSizeInMeters; - CenterFromTopInMeters = src.CenterFromTopInMeters; - LensSeparationInMeters = src.LensSeparationInMeters; - DesktopX = src.DesktopX; - DesktopY = src.DesktopY; - Shutter = src.Shutter; - memcpy(DisplayDeviceName, src.DisplayDeviceName, sizeof(DisplayDeviceName)); - - DisplayId = src.DisplayId; - } - - bool IsSameDisplay(const HMDInfo& o) const - { - return DisplayId == o.DisplayId && - String::CompareNoCase(DisplayDeviceName, - o.DisplayDeviceName) == 0; - } - -}; - - -// HMDDevice represents an Oculus HMD device unit. An instance of this class -// is typically created from the DeviceManager. -// After HMD device is created, we its sensor data can be obtained by -// first creating a Sensor object and then. - -// TBD: -// - Configure Sensor -// - APIs to set On-Screen message, other states? - -class HMDDevice : public DeviceBase -{ -public: - HMDDevice() - { } - - // Static constant for this device type, used in template cast type checks. - enum { EnumDeviceType = Device_HMD }; - - virtual DeviceType GetType() const { return Device_HMD; } - - // Creates a sensor associated with this HMD. - virtual SensorDevice* GetSensor() = 0; - - - // Requests the currently used profile. This profile affects the - // settings reported by HMDInfo. - virtual Profile* GetProfile() = 0; - // Obtains the currently used profile name. This is initialized to the default - // profile name, if any; it can then be changed per-device by SetProfileName. - virtual const char* GetProfileName() = 0; - // Sets the profile user name, changing the data returned by GetProfileInfo. - virtual bool SetProfileName(const char* name) = 0; - - - // Disconnects from real HMD device. This HMDDevice remains as 'fake' HMD. - // SensorDevice ptr is used to restore the 'fake' HMD (can be NULL). - HMDDevice* Disconnect(SensorDevice*); - - // Returns 'true' if HMD device is a 'fake' HMD (was created this way or - // 'Disconnect' method was called). - bool IsDisconnected() const; -}; - - -//------------------------------------------------------------------------------------- -// ***** SensorRange & SensorInfo - -// SensorRange specifies maximum value ranges that SensorDevice hardware is configured -// to detect. Although this range doesn't affect the scale of MessageBodyFrame values, -// physical motions whose positive or negative magnitude is outside the specified range -// may get clamped or misreported. Setting lower values may result in higher precision -// tracking. -struct SensorRange -{ - SensorRange(float maxAcceleration = 0.0f, float maxRotationRate = 0.0f, - float maxMagneticField = 0.0f) - : MaxAcceleration(maxAcceleration), MaxRotationRate(maxRotationRate), - MaxMagneticField(maxMagneticField) - { } - - // Maximum detected acceleration in m/s^2. Up to 8*G equivalent support guaranteed, - // where G is ~9.81 m/s^2. - // Oculus DK1 HW has thresholds near: 2, 4 (default), 8, 16 G. - float MaxAcceleration; - // Maximum detected angular velocity in rad/s. Up to 8*Pi support guaranteed. - // Oculus DK1 HW thresholds near: 1, 2, 4, 8 Pi (default). - float MaxRotationRate; - // Maximum detectable Magnetic field strength in Gauss. Up to 2.5 Gauss support guaranteed. - // Oculus DK1 HW thresholds near: 0.88, 1.3, 1.9, 2.5 gauss. - float MaxMagneticField; -}; - -// SensorInfo describes capabilities of the sensor device. -class SensorInfo : public DeviceInfo -{ -public: - SensorInfo() : DeviceInfo(Device_Sensor), VendorId(0), ProductId(0) - { - } - - // HID Vendor and ProductId of the device. - UInt16 VendorId; - UInt16 ProductId; - // MaxRanges report maximum sensor range values supported by HW. - SensorRange MaxRanges; - // Sensor (and display) serial number. - String SerialNumber; - -private: - void operator = (const SensorInfo&) { OVR_ASSERT(0); } // Assignment not allowed. -}; - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Serial Number feature report. (DK1) -struct SerialReport -{ - static const int SERIAL_NUMBER_SIZE = 12; // Serial Number size = 12 bytes. (Refer 'Tracker Firmware Specification Section 4.9, Pg 18) - - SerialReport() - : CommandId(0) - { - memset(SerialNumberValue, 0, sizeof(SerialNumberValue)); - } - - SerialReport(UInt16 commandId, - UByte SNo[SERIAL_NUMBER_SIZE]) - : CommandId(commandId) - { - for (int i=0; i < SERIAL_NUMBER_SIZE; i++) - { - SerialNumberValue[i] = SNo[i]; - } - } - - UInt16 CommandId; - UByte SerialNumberValue[SERIAL_NUMBER_SIZE]; // See 'Tracker Firmware Specification' document for - // a description of Serial Report. -}; - - -//////////////////////////////////////////////////////////////////////////////////////////////// -//Added Serial Report Implementation. - -struct SerialImpl -{ - enum { PacketSize = 15 }; - UByte Buffer[PacketSize]; - - SerialReport Settings; - - SerialImpl() - { - memset(Buffer, 0, sizeof(Buffer)); - Buffer[0] = 10; - } - - SerialImpl(const SerialReport& settings) - :Settings(settings) - { - Pack(); - } - - void Pack() - { - Buffer[0] = 10; - Alg::EncodeUInt16(Buffer+1, Settings.CommandId); - for (int i = 0; i < Settings.SERIAL_NUMBER_SIZE; ++i) - Buffer[3 + i] = Settings.SerialNumberValue[i]; - } - - void Unpack() - { - Settings.CommandId = Alg::DecodeUInt16(Buffer+1); - for (int i = 0; i < Settings.SERIAL_NUMBER_SIZE; ++i) - Settings.SerialNumberValue[i] = Buffer[3 + i]; - } - -}; - - -// Tracking settings (DK2). -struct TrackingReport -{ - TrackingReport() - : CommandId(0), Pattern(0), - Enable(0), Autoincrement(0), UseCarrier(0), - SyncInput(0), VsyncLock(0), CustomPattern(0), - ExposureLength(0), FrameInterval(0), - VsyncOffset(0), DutyCycle(0) - {} - - TrackingReport( UInt16 commandId, - UByte pattern, - bool enable, - bool autoincrement, - bool useCarrier, - bool syncInput, - bool vsyncLock, - bool customPattern, - UInt16 exposureLength, - UInt16 frameInterval, - UInt16 vsyncOffset, - UByte dutyCycle) - : CommandId(commandId), Pattern(pattern), - Enable(enable), Autoincrement(autoincrement), UseCarrier(useCarrier), - SyncInput(syncInput), VsyncLock(vsyncLock), CustomPattern(customPattern), - ExposureLength(exposureLength), FrameInterval(frameInterval), - VsyncOffset(vsyncOffset), DutyCycle(dutyCycle) - { } - - UInt16 CommandId; - UByte Pattern; // Tracking LED pattern index. - bool Enable; // Enables the tracking LED exposure and updating. - bool Autoincrement; // Autoincrement pattern after each exposure. - bool UseCarrier; // Modulate tracking LEDs at 85kHz. - bool SyncInput; // Trigger LED exposure from wired sync signal. - bool VsyncLock; // Trigger LED exposure from panel Vsync. - bool CustomPattern; // Use custom LED sequence. - UInt16 ExposureLength; // Tracking LED illumination (and exposure) length in microseconds. - UInt16 FrameInterval; // LED exposure interval in microseconds when in - // 'internal timer' mode (when SyncInput = VsyncLock = false). - UInt16 VsyncOffset; // Exposure offset in microseconds from vsync when in - // 'vsync lock' mode (when VsyncLock = true). - UByte DutyCycle; // Duty cycle of 85kHz modulation when in 'use carrier' mode - // (when UseCarrier = true). 128 = 50% duty cycle. -}; - -// Display settings (DK2). -struct DisplayReport -{ - enum ShutterTypeEnum - { - // These are not yet defined. - ShutterType_Default = 0, - }; - - enum CurrentLimitEnum - { - // These are not yet defined. - CurrentLimit_Default = 0, - }; - - DisplayReport() - : CommandId(0), Brightness(0), - ShutterType(ShutterType_Default), CurrentLimit(CurrentLimit_Default), UseRolling(0), - ReverseRolling(0), HighBrightness(0), SelfRefresh(0), - ReadPixel(0), DirectPentile(0), - Persistence(0), LightingOffset(0), - PixelSettle(0), TotalRows(0) - {} - - DisplayReport( UInt16 commandId, - UByte brightness, - ShutterTypeEnum shutterType, - CurrentLimitEnum currentLimit, - bool useRolling, - bool reverseRolling, - bool highBrightness, - bool selfRefresh, - bool readPixel, - bool directPentile, - UInt16 persistence, - UInt16 lightingOffset, - UInt16 pixelSettle, - UInt16 totalRows) - : CommandId(commandId), Brightness(brightness), - ShutterType(shutterType), CurrentLimit(currentLimit), UseRolling(useRolling), - ReverseRolling(reverseRolling), HighBrightness(highBrightness), SelfRefresh(selfRefresh), - ReadPixel(readPixel), DirectPentile(directPentile), - Persistence(persistence), LightingOffset(lightingOffset), - PixelSettle(pixelSettle), TotalRows(totalRows) - { } - - UInt16 CommandId; - UByte Brightness; // See 'DK2 Firmware Specification' document for a description of - ShutterTypeEnum ShutterType; // display settings. - CurrentLimitEnum CurrentLimit; - bool UseRolling; - bool ReverseRolling; - bool HighBrightness; - bool SelfRefresh; - bool ReadPixel; - bool DirectPentile; - UInt16 Persistence; - UInt16 LightingOffset; - UInt16 PixelSettle; - UInt16 TotalRows; -}; - -// MagCalibration matrix (DK2). -struct MagCalibrationReport -{ - MagCalibrationReport() - : CommandId(0), Version(0), Calibration() - {} - - MagCalibrationReport( UInt16 commandId, - UByte version, - const Matrix4f& calibration) - : CommandId(commandId), Version(version), Calibration(calibration) - { } - - UInt16 CommandId; - UByte Version; // Version of the calibration procedure used to generate the calibration matrix. - Matrix4f Calibration; // Calibration matrix. Note only the first three rows are used by the feature report. -}; - -// PositionCalibration values (DK2). -// - Sensor interface versions before 5 do not support Normal and Rotation. -struct PositionCalibrationReport -{ - enum PositionTypeEnum - { - PositionType_LED = 0, - PositionType_IMU = 1 - }; - - PositionCalibrationReport() - : CommandId(0), Version(0), - Position(0), Normal(0), Angle(0), - PositionIndex(0), NumPositions(0), PositionType(PositionType_LED) - {} - - PositionCalibrationReport(UInt16 commandId, - UByte version, - const Vector3d& position, - const Vector3d& normal, - double rotation, - UInt16 positionIndex, - UInt16 numPositions, - PositionTypeEnum positionType) - : CommandId(commandId), Version(version), - Position(position), Normal(normal), Angle(rotation), - PositionIndex(positionIndex), NumPositions(numPositions), PositionType(positionType) - { - } - - UInt16 CommandId; - UByte Version; // The version of the calibration procedure used to generate the stored positions. - Vector3d Position; // Position of the LED or inertial tracker in meters. This is relative to the - // center of the emitter plane of the display at nominal focus. - Vector3d Normal; // Normal of the LED or inertial tracker. This is a signed integer in - // meters. The normal is relative to the position. - double Angle; // The rotation about the normal. This is in radians. - UInt16 PositionIndex; // The current position being read or written to. Autoincrements on reads, gets set - // to the written value on writes. - UInt16 NumPositions; // The read-only number of items with positions stored. The last position is that of - // the inertial tracker, all others are LED positions. - PositionTypeEnum PositionType; // The type of the item which has its position reported in the current report -}; - -// CustomPattern values (DK2). -struct CustomPatternReport -{ - CustomPatternReport() - : CommandId(0), SequenceLength(0), Sequence(0), - LEDIndex(0), NumLEDs(0) - {} - - CustomPatternReport(UInt16 commandId, - UByte sequenceLength, - UInt32 sequence, - UInt16 ledIndex, - UInt16 numLEDs) - : CommandId(commandId), SequenceLength(sequenceLength), Sequence(sequence), - LEDIndex(ledIndex), NumLEDs(numLEDs) - { } - - UInt16 CommandId; - UByte SequenceLength; // See 'DK2 Firmware Specification' document for a description of - UInt32 Sequence; // LED custom patterns. - UInt16 LEDIndex; - UInt16 NumLEDs; -}; - -// KeepAliveMux settings (DK2). -struct KeepAliveMuxReport -{ - KeepAliveMuxReport() - : CommandId(0), INReport(0), Interval(0) - {} - - KeepAliveMuxReport( UInt16 commandId, - UByte inReport, - UInt16 interval) - : CommandId(commandId), INReport(inReport), Interval(interval) - { } - - UInt16 CommandId; - UByte INReport; // Requested IN report type (1 = DK1, 11 = DK2). - UInt16 Interval; // Keep alive period in milliseconds. -}; - -// Manufacturing test result (DK2). -struct ManufacturingReport -{ - ManufacturingReport() - : CommandId(0), NumStages(0), Stage(0), - StageVersion(0), StageLocation(0), StageTime(0), Result(0) - {} - - ManufacturingReport( UInt16 commandId, - UByte numStages, - UByte stage, - UByte version, - UInt16 stageLocation, - UInt32 stageTime, - UInt32 result) - : CommandId(commandId), NumStages(numStages), Stage(stage), - StageVersion(version), StageLocation(stageLocation), StageTime(stageTime), Result(result) - { } - - UInt16 CommandId; - UByte NumStages; // See 'DK2 Firmware Specification' document for a description of - UByte Stage; // manufacturing test results. - UByte StageVersion; - UInt16 StageLocation; - UInt32 StageTime; - UInt32 Result; -}; - -// UUID (DK2). -struct UUIDReport -{ - static const int UUID_SIZE = 20; - - UUIDReport() - : CommandId(0) - { - memset(UUIDValue, 0, sizeof(UUIDValue)); - } - - UUIDReport( UInt16 commandId, - UByte uuid[UUID_SIZE]) - : CommandId(commandId) - { - for (int i=0; i*) { return false; } - - virtual bool SetCustomPatternReport(const CustomPatternReport&) { return false; } - virtual bool GetCustomPatternReport(CustomPatternReport*) { return false; } - - virtual bool SetKeepAliveMuxReport(const KeepAliveMuxReport&) { return false; } - virtual bool GetKeepAliveMuxReport(KeepAliveMuxReport*) { return false; } - - virtual bool SetManufacturingReport(const ManufacturingReport&) { return false; } - virtual bool GetManufacturingReport(ManufacturingReport*) { return false; } - - virtual bool SetUUIDReport(const UUIDReport&) { return false; } - virtual bool GetUUIDReport(UUIDReport*) { return false; } - - virtual bool SetTemperatureReport(const TemperatureReport&) { return false; } - virtual bool GetAllTemperatureReports(Array >*) { return false; } - - virtual bool GetGyroOffsetReport(GyroOffsetReport*) { return false; } - - virtual bool SetLensDistortionReport(const LensDistortionReport&) { return false; } - virtual bool GetLensDistortionReport(LensDistortionReport*) { return false; } -}; - -//------------------------------------------------------------------------------------- -// ***** LatencyTestConfiguration -// LatencyTestConfiguration specifies configuration information for the Oculus Latency Tester device. -struct LatencyTestConfiguration -{ - LatencyTestConfiguration(const Color& threshold, bool sendSamples = false) - : Threshold(threshold), SendSamples(sendSamples) - { - } - - // The color threshold for triggering a detected display change. - Color Threshold; - // Flag specifying whether we wish to receive a stream of color values from the sensor. - bool SendSamples; -}; - -//------------------------------------------------------------------------------------- -// ***** LatencyTestDisplay -// LatencyTestDisplay sets the mode and contents of the Latency Tester LED display. -// See the 'Latency Tester Specification' document for more details. -struct LatencyTestDisplay -{ - LatencyTestDisplay(UByte mode, UInt32 value) - : Mode(mode), Value(value) - { - } - - UByte Mode; // The display mode that we wish to select. - UInt32 Value; // The value to display. -}; - -//------------------------------------------------------------------------------------- -// ***** LatencyTestDevice - -// LatencyTestDevice provides an interface to the Oculus Latency Tester which is used to test 'motion to photon' latency. -class LatencyTestDevice : public HIDDeviceBase, public DeviceBase -{ -public: - LatencyTestDevice() - { } - - // Static constant for this device type, used in template cast type checks. - enum { EnumDeviceType = Device_LatencyTester }; - - virtual DeviceType GetType() const { return Device_LatencyTester; } - - // Specifies configuration information including the threshold for triggering a detected color change, - // and a flag to enable a stream of sensor values (typically used for debugging). - virtual bool SetConfiguration(const LatencyTestConfiguration& configuration, bool waitFlag = false) = 0; - - // Get configuration information from device. - virtual bool GetConfiguration(LatencyTestConfiguration* configuration) = 0; - - // Used to calibrate the latency tester at the start of a test. Display the specified color on the screen - // beneath the latency tester and then call this method. Calibration information is lost - // when power is removed from the device. - virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false) = 0; - - // Triggers the start of a measurement. This starts the millisecond timer on the device and - // causes it to respond with the 'MessageLatencyTestStarted' message. - virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false) = 0; - - // Used to set the value displayed on the LED display panel. - virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false) = 0; - - virtual DeviceBase* GetDevice() { return this; } -}; - -} // namespace OVR - - - - -#endif diff --git a/LibOVR/Src/OVR_DeviceConstants.h b/LibOVR/Src/OVR_DeviceConstants.h deleted file mode 100644 index 6b40b7d..0000000 --- a/LibOVR/Src/OVR_DeviceConstants.h +++ /dev/null @@ -1,142 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_DeviceConstants.h -Content : Device constants -Created : February 5, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceConstants_h -#define OVR_DeviceConstants_h - -namespace OVR { - - -//------------------------------------------------------------------------------------- -// Different device types supported by OVR; this type is reported by DeviceBase::GetType. -// -enum DeviceType -{ - Device_None = 0, - Device_Manager = 1, - Device_HMD = 2, - Device_Sensor = 3, - Device_LatencyTester = 4, - Device_BootLoader = 5, - Device_Camera = 6, - Device_Display = 7, - Device_All = 0xFF // Set for enumeration only, to enumerate all device types. -}; - - - -//------------------------------------------------------------------------------------- -// Different lens distortion types supported by devices. -// -enum DistortionEqnType -{ - Distortion_No_Override = -1, - // These two are leagcy and deprecated. - Distortion_Poly4 = 0, // scale = (K0 + K1*r^2 + K2*r^4 + K3*r^6) - Distortion_RecipPoly4 = 1, // scale = 1/(K0 + K1*r^2 + K2*r^4 + K3*r^6) - - // CatmullRom10 is the preferred distortion format. - Distortion_CatmullRom10 = 2, // scale = Catmull-Rom spline through points (1.0, K[1]...K[9]) - - Distortion_LAST // For ease of enumeration. -}; - - -//------------------------------------------------------------------------------------- -// HMD types. -// -enum HmdTypeEnum -{ - HmdType_None, - - HmdType_DKProto, // First duct-tape model, never sold. - HmdType_DK1, // DevKit1 - on sale to developers. - HmdType_DKHDProto, // DKHD - shown at various shows, never sold. - HmdType_DKHD2Proto, // DKHD2, 5.85-inch panel, never sold. - 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, - - // Reminder - this header file is public - codenames only! - - HmdType_Unknown, // Used for unnamed HW lab experiments. - - HmdType_LAST -}; - - -//------------------------------------------------------------------------------------- -// HMD shutter types. -// -enum HmdShutterTypeEnum -{ - HmdShutter_Global, - HmdShutter_RollingTopToBottom, - HmdShutter_RollingLeftToRight, - HmdShutter_RollingRightToLeft, - // TODO: - // color-sequential e.g. LCOS? - // alternate eyes? - // alternate columns? - // outside-in? - - HmdShutter_LAST -}; - - - -//------------------------------------------------------------------------------------- -// For headsets that use eye cups -// -enum EyeCupType -{ - // Public lenses - EyeCup_DK1A = 0, - EyeCup_DK1B = 1, - EyeCup_DK1C = 2, - - EyeCup_DK2A = 3, - - // Internal R&D codenames. - // Reminder - this header file is public - codenames only! - EyeCup_DKHD2A, - EyeCup_OrangeA, - EyeCup_RedA, - EyeCup_PinkA, - EyeCup_BlueA, - EyeCup_Delilah1A, - EyeCup_Delilah2A, - EyeCup_JamesA, - EyeCup_SunMandalaA, - - EyeCup_LAST -}; - - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/OVR_DeviceHandle.cpp b/LibOVR/Src/OVR_DeviceHandle.cpp deleted file mode 100644 index cf6f05f..0000000 --- a/LibOVR/Src/OVR_DeviceHandle.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/************************************************************************************ - -Filename : OVR_DeviceHandle.cpp -Content : Implementation of device handle class -Created : February 5, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceHandle.h" - -#include "OVR_DeviceImpl.h" - -namespace OVR { - -//------------------------------------------------------------------------------------- -// ***** DeviceHandle - -DeviceHandle::DeviceHandle(DeviceCreateDesc* impl) : pImpl(impl) -{ - if (pImpl) - pImpl->AddRef(); -} - -DeviceHandle::DeviceHandle(const DeviceHandle& src) : pImpl(src.pImpl) -{ - if (pImpl) - pImpl->AddRef(); -} - -DeviceHandle::~DeviceHandle() -{ - if (pImpl) - pImpl->Release(); -} - -void DeviceHandle::operator = (const DeviceHandle& src) -{ - if (src.pImpl) - src.pImpl->AddRef(); - if (pImpl) - pImpl->Release(); - pImpl = src.pImpl; -} - -DeviceBase* DeviceHandle::GetDevice_AddRef() const -{ - if (pImpl && pImpl->pDevice) - { - pImpl->pDevice->AddRef(); - return pImpl->pDevice; - } - return NULL; -} - -// Returns true, if the handle contains the same device ptr -// as specified in the parameter. -bool DeviceHandle::IsDevice(DeviceBase* pdev) const -{ - return (pdev && pImpl && pImpl->pDevice) ? - pImpl->pDevice == pdev : false; -} - -DeviceType DeviceHandle::GetType() const -{ - return pImpl ? pImpl->Type : Device_None; -} - -bool DeviceHandle::GetDeviceInfo(DeviceInfo* info) const -{ - return pImpl ? pImpl->GetDeviceInfo(info) : false; -} -bool DeviceHandle::IsAvailable() const -{ - // This isn't "atomically safe", but the function only returns the - // recent state that may change. - return pImpl ? (pImpl->Enumerated && pImpl->pLock->pManager) : false; -} - -bool DeviceHandle::IsCreated() const -{ - return pImpl ? (pImpl->pDevice != 0) : false; -} - -DeviceBase* DeviceHandle::CreateDevice() -{ - if (!pImpl) - return 0; - - DeviceBase* device = 0; - Ptr manager= 0; - - // Since both manager and device pointers can only be destroyed during a lock, - // hold it while checking for availability. - // AddRef to manager so that it doesn't get released on us. - { - Lock::Locker deviceLockScope(pImpl->GetLock()); - - if (pImpl->pDevice) - { - pImpl->pDevice->AddRef(); - return pImpl->pDevice; - } - manager = pImpl->GetManagerImpl(); - } - - if (manager) - { - if (manager->GetThreadId() != OVR::GetCurrentThreadId()) - { - // Queue up a CreateDevice request. This fills in '&device' with AddRefed value, - // or keep it at null. - manager->GetThreadQueue()->PushCallAndWaitResult( - manager.GetPtr(), &DeviceManagerImpl::CreateDevice_MgrThread, - &device, pImpl, (DeviceBase*)0); - } - else - device = manager->CreateDevice_MgrThread(pImpl, (DeviceBase*)0); - } - return device; -} - -void DeviceHandle::Clear() -{ - if (pImpl) - { - pImpl->Release(); - pImpl = 0; - } -} - -bool DeviceHandle::enumerateNext(const DeviceEnumerationArgs& args) -{ - if (GetType() == Device_None) - return false; - - Ptr managerKeepAlive; - Lock::Locker lockScope(pImpl->GetLock()); - - DeviceCreateDesc* next = pImpl; - // If manager was destroyed, we get removed from the list. - if (!pImpl->pNext) - return false; - - managerKeepAlive = next->GetManagerImpl(); - OVR_ASSERT(managerKeepAlive); - - do { - next = next->pNext; - - if (managerKeepAlive->Devices.IsNull(next)) - { - pImpl->Release(); - pImpl = 0; - return false; - } - - } while(!args.MatchRule(next->Type, next->Enumerated)); - - next->AddRef(); - pImpl->Release(); - pImpl = next; - - return true; -} - -} // namespace OVR - diff --git a/LibOVR/Src/OVR_DeviceHandle.h b/LibOVR/Src/OVR_DeviceHandle.h deleted file mode 100644 index dd3e92b..0000000 --- a/LibOVR/Src/OVR_DeviceHandle.h +++ /dev/null @@ -1,108 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_DeviceHandle.h -Content : Handle to a device that was enumerated -Created : February 5, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceHandle_h -#define OVR_DeviceHandle_h - -#include "OVR_DeviceConstants.h" - -namespace OVR { - -class DeviceBase; -class DeviceInfo; - -// Internal -class DeviceCreateDesc; -class DeviceEnumerationArgs; - - -//------------------------------------------------------------------------------------- -// ***** DeviceHandle - -// DeviceHandle references a specific device that was enumerated; it can be assigned -// directly from DeviceEnumerator. -// -// Devices represented by DeviceHandle are not necessarily created or available. -// A device may become unavailable if, for example, it its unplugged. If the device -// is available, it can be created by calling CreateDevice. -// - -class DeviceHandle -{ - friend class DeviceManager; - friend class DeviceManagerImpl; - template friend class HIDDeviceImpl; - -public: - DeviceHandle() : pImpl(0) { } - DeviceHandle(const DeviceHandle& src); - ~DeviceHandle(); - - void operator = (const DeviceHandle& src); - - bool operator == (const DeviceHandle& other) const { return pImpl == other.pImpl; } - bool operator != (const DeviceHandle& other) const { return pImpl != other.pImpl; } - - // operator bool() returns true if Handle/Enumerator points to a valid device. - operator bool () const { return GetType() != Device_None; } - - // Returns existing device, or NULL if !IsCreated. The returned ptr is - // addref-ed. - DeviceBase* GetDevice_AddRef() const; - DeviceType GetType() const; - bool GetDeviceInfo(DeviceInfo* info) const; - bool IsAvailable() const; - bool IsCreated() const; - // Returns true, if the handle contains the same device ptr - // as specified in the parameter. - bool IsDevice(DeviceBase*) const; - - // Creates a device, or returns AddRefed pointer if one is already created. - // New devices start out with RefCount of 1. - DeviceBase* CreateDevice(); - - // Creates a device, or returns AddRefed pointer if one is already created. - // New devices start out with RefCount of 1. DeviceT is used to cast the - // DeviceBase* to a concreete type. - template - DeviceT* CreateDeviceTyped() const - { - return static_cast(DeviceHandle(*this).CreateDevice()); - } - - // Resets the device handle to uninitialized state. - void Clear(); - -protected: - explicit DeviceHandle(DeviceCreateDesc* impl); - bool enumerateNext(const DeviceEnumerationArgs& args); - DeviceCreateDesc* pImpl; -}; - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/OVR_DeviceImpl.cpp b/LibOVR/Src/OVR_DeviceImpl.cpp deleted file mode 100644 index 5b77708..0000000 --- a/LibOVR/Src/OVR_DeviceImpl.cpp +++ /dev/null @@ -1,794 +0,0 @@ -/************************************************************************************ - -Filename : OVR_DeviceImpl.h -Content : Partial back-end independent implementation of Device interfaces -Created : October 10, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceImpl.h" -#include "Kernel/OVR_Atomic.h" -#include "Kernel/OVR_Log.h" -#include "Kernel/OVR_System.h" - -#include "OVR_DeviceImpl.h" -#include "OVR_SensorImpl.h" -#include "OVR_Profile.h" - -namespace OVR { - - -//------------------------------------------------------------------------------------- -// ***** MessageHandler - -// Threading notes: -// The OnMessage() handler and SetMessageHandler are currently synchronized -// through a separately stored shared Lock object to avoid calling the handler -// from background thread while it's being removed. - -static SharedLock MessageHandlerSharedLock; - - -class MessageHandlerImpl -{ -public: - enum - { - MaxHandlerRefsCount = 4 - }; - - MessageHandlerImpl() - : pLock(MessageHandlerSharedLock.GetLockAddRef()), HandlerRefsCount(0) - { - } - ~MessageHandlerImpl() - { - MessageHandlerSharedLock.ReleaseLock(pLock); - pLock = 0; - } - - static MessageHandlerImpl* FromHandler(MessageHandler* handler) - { return (MessageHandlerImpl*)&handler->Internal; } - static const MessageHandlerImpl* FromHandler(const MessageHandler* handler) - { return (const MessageHandlerImpl*)&handler->Internal; } - - // This lock is held while calling a handler and when we are applied/ - // removed from a device. - Lock* pLock; - // List of devices we are applied to. - int HandlerRefsCount; - MessageHandlerRef* pHandlerRefs[MaxHandlerRefsCount]; -}; - - -MessageHandlerRef::MessageHandlerRef(DeviceBase* device) - : pLock(MessageHandlerSharedLock.GetLockAddRef()), pDevice(device), HandlersCount(0) -{ -} - -MessageHandlerRef::~MessageHandlerRef() -{ - { - Lock::Locker lockScope(pLock); - - while (HandlersCount > 0) - removeHandler(0); - } - MessageHandlerSharedLock.ReleaseLock(pLock); - pLock = 0; -} - -void MessageHandlerRef::Call(const Message& msg) -{ - Lock::Locker lockScope(pLock); - - for (int i = 0; i < HandlersCount; i++) - pHandlers[i]->OnMessage(msg); -} - -void MessageHandlerRef::AddHandler(MessageHandler* handler) -{ - OVR_ASSERT(!handler || - MessageHandlerImpl::FromHandler(handler)->pLock == pLock); - Lock::Locker lockScope(pLock); - AddHandler_NTS(handler); -} - -void MessageHandlerRef::AddHandler_NTS(MessageHandler* handler) -{ - OVR_ASSERT(handler != NULL); - - OVR_ASSERT(HandlersCount < MaxHandlersCount); - for (int i = 0; i < HandlersCount; i++) - if (pHandlers[i] == handler) - // handler already installed - do nothing - return; - pHandlers[HandlersCount] = handler; - HandlersCount++; - - MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(handler); - OVR_ASSERT(handlerImpl->HandlerRefsCount < MessageHandlerImpl::MaxHandlerRefsCount); - handlerImpl->pHandlerRefs[handlerImpl->HandlerRefsCount] = this; - handlerImpl->HandlerRefsCount++; - - // TBD: Call notifier on device? -} - -bool MessageHandlerRef::RemoveHandler(MessageHandler* handler) -{ - Lock::Locker lockScope(pLock); - - for (int i = 0; i < HandlersCount; i++) - { - if (pHandlers[i] == handler) - return removeHandler(i); - } - return false; -} - -bool MessageHandlerRef::removeHandler(int idx) -{ - OVR_ASSERT(idx < HandlersCount); - - MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(pHandlers[idx]); - for (int i = 0; i < handlerImpl->HandlerRefsCount; i++) - if (handlerImpl->pHandlerRefs[i] == this) - { - handlerImpl->pHandlerRefs[i] = handlerImpl->pHandlerRefs[handlerImpl->HandlerRefsCount - 1]; - handlerImpl->HandlerRefsCount--; - - pHandlers[idx] = pHandlers[HandlersCount - 1]; - HandlersCount--; - - return true; - } - - // couldn't find a link in the opposite direction, assert in Debug - OVR_ASSERT(0); - - pHandlers[idx] = pHandlers[HandlersCount - 1]; - HandlersCount--; - - return true; -} - -MessageHandler::MessageHandler() -{ - OVR_COMPILER_ASSERT(sizeof(Internal) > sizeof(MessageHandlerImpl)); - Construct(Internal); -} - -MessageHandler::~MessageHandler() -{ - MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(this); - { - Lock::Locker lockedScope(handlerImpl->pLock); - OVR_ASSERT_LOG(handlerImpl->HandlerRefsCount == 0, - ("~MessageHandler %p - Handler still active; call RemoveHandlerFromDevices", this)); - } - - Destruct(handlerImpl); -} - -bool MessageHandler::IsHandlerInstalled() const -{ - const MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(this); - Lock::Locker lockedScope(handlerImpl->pLock); - - return handlerImpl->HandlerRefsCount > 0; -} - -void MessageHandler::RemoveHandlerFromDevices() -{ - MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(this); - Lock::Locker lockedScope(handlerImpl->pLock); - - while (handlerImpl->HandlerRefsCount > 0) - { - MessageHandlerRef* use = handlerImpl->pHandlerRefs[0]; - use->RemoveHandler(this); - } -} - -Lock* MessageHandler::GetHandlerLock() const -{ - const MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(this); - return handlerImpl->pLock; -} - - -//------------------------------------------------------------------------------------- -// ***** DeviceBase - - -// Delegate relevant implementation to DeviceRectord to avoid re-implementation in -// every derived Device. -void DeviceBase::AddRef() -{ - getDeviceCommon()->DeviceAddRef(); -} -void DeviceBase::Release() -{ - getDeviceCommon()->DeviceRelease(); -} -DeviceBase* DeviceBase::GetParent() const -{ - return getDeviceCommon()->pParent.GetPtr(); -} -DeviceManager* DeviceBase::GetManager() const -{ - return getDeviceCommon()->pCreateDesc->GetManagerImpl(); -} - -void DeviceBase::AddMessageHandler(MessageHandler* handler) -{ - getDeviceCommon()->HandlerRef.AddHandler(handler); -} - -DeviceType DeviceBase::GetType() const -{ - return getDeviceCommon()->pCreateDesc->Type; -} - -bool DeviceBase::GetDeviceInfo(DeviceInfo* info) const -{ - return getDeviceCommon()->pCreateDesc->GetDeviceInfo(info); - //info->Name[0] = 0; - //return false; -} - -// Returns true if device is connected and usable -bool DeviceBase::IsConnected() -{ - return getDeviceCommon()->ConnectedFlag; -} - -// returns the MessageHandler's lock -Lock* DeviceBase::GetHandlerLock() const -{ - return getDeviceCommon()->HandlerRef.GetLock(); -} - -// Derive DeviceManagerCreateDesc to provide abstract function implementation. -class DeviceManagerCreateDesc : public DeviceCreateDesc -{ -public: - DeviceManagerCreateDesc(DeviceFactory* factory) - : DeviceCreateDesc(factory, Device_Manager) { } - - // We don't need there on Manager since it isn't assigned to DeviceHandle. - virtual DeviceCreateDesc* Clone() const { return 0; } - virtual MatchResult MatchDevice(const DeviceCreateDesc&, - DeviceCreateDesc**) const { return Match_None; } - virtual DeviceBase* NewDeviceInstance() { return 0; } - virtual bool GetDeviceInfo(DeviceInfo*) const { return false; } -}; - -//------------------------------------------------------------------------------------- -// ***** DeviceManagerImpl - -DeviceManagerImpl::DeviceManagerImpl() - : DeviceImpl(CreateManagerDesc(), 0) - //,DeviceCreateDescList(pCreateDesc ? pCreateDesc->pLock : 0) -{ - if (pCreateDesc) - { - pCreateDesc->pLock->pManager = this; - } -} - -DeviceManagerImpl::~DeviceManagerImpl() -{ - // Shutdown must've been called. - OVR_ASSERT(!pCreateDesc->pDevice); - - // Remove all factories - while(!Factories.IsEmpty()) - { - DeviceFactory* factory = Factories.GetFirst(); - factory->RemovedFromManager(); - factory->RemoveNode(); - } -} - -DeviceCreateDesc* DeviceManagerImpl::CreateManagerDesc() -{ - DeviceCreateDesc* managerDesc = new DeviceManagerCreateDesc(0); - if (managerDesc) - { - managerDesc->pLock = *new DeviceManagerLock; - } - return managerDesc; -} - -bool DeviceManagerImpl::Initialize(DeviceBase* parent) -{ - OVR_UNUSED(parent); - if (!pCreateDesc || !pCreateDesc->pLock) - return false; - - pProfileManager = *ProfileManager::Create(); - - return true; -} - -void DeviceManagerImpl::Shutdown() -{ - // Remove all device descriptors from list while the lock is held. - // Some descriptors may survive longer due to handles. - while(!Devices.IsEmpty()) - { - DeviceCreateDesc* devDesc = Devices.GetFirst(); - OVR_ASSERT(!devDesc->pDevice); // Manager shouldn't be dying while Device exists. - devDesc->Enumerated = false; - devDesc->RemoveNode(); - devDesc->pNext = devDesc->pPrev = 0; - - if (devDesc->HandleCount == 0) - { - delete devDesc; - } - } - Devices.Clear(); - - // These must've been cleared by caller. - OVR_ASSERT(pCreateDesc->pDevice == 0); - OVR_ASSERT(pCreateDesc->pLock->pManager == 0); - - pProfileManager.Clear(); -} - - -// Callbacks for DeviceCreation/Release -DeviceBase* DeviceManagerImpl::CreateDevice_MgrThread(DeviceCreateDesc* createDesc, DeviceBase* parent) -{ - // Calls to DeviceManagerImpl::CreateDevice are enqueued with wait while holding pManager, - // so 'this' must remain valid. - OVR_ASSERT(createDesc->pLock->pManager); - - Lock::Locker devicesLock(GetLock()); - - // If device already exists, just AddRef to it. - if (createDesc->pDevice) - { - createDesc->pDevice->AddRef(); - return createDesc->pDevice; - } - - if (!parent) - parent = this; - - DeviceBase* device = createDesc->NewDeviceInstance(); - - if (device) - { - if (device->getDeviceCommon()->Initialize(parent)) - { - createDesc->pDevice = device; - } - else - { - // Don't go through Release() to avoid PushCall behaviour, - // as it is not needed here. - delete device; - device = 0; - } - } - - return device; -} - -Void DeviceManagerImpl::ReleaseDevice_MgrThread(DeviceBase* device) -{ - // descKeepAlive will keep ManagerLock object alive as well, - // allowing us to exit gracefully. - Ptr descKeepAlive; - Lock::Locker devicesLock(GetLock()); - DeviceCommon* devCommon = device->getDeviceCommon(); - - while(1) - { - UInt32 refCount = devCommon->RefCount; - - if (refCount > 1) - { - if (devCommon->RefCount.CompareAndSet_NoSync(refCount, refCount-1)) - { - // We decreented from initial count higher then 1; - // nothing else to do. - return 0; - } - } - else if (devCommon->RefCount.CompareAndSet_NoSync(1, 0)) - { - // { 1 -> 0 } decrement succeded. Destroy this device. - break; - } - } - - // At this point, may be releasing the device manager itself. - // This does not matter, however, since shutdown logic is the same - // in both cases. DeviceManager::Shutdown with begin shutdown process for - // the internal manager thread, which will eventually destroy itself. - // TBD: Clean thread shutdown. - descKeepAlive = devCommon->pCreateDesc; - descKeepAlive->pDevice = 0; - devCommon->Shutdown(); - delete device; - return 0; -} - - - -Void DeviceManagerImpl::EnumerateAllFactoryDevices() -{ - // 1. Mark matching devices as NOT enumerated. - // 2. Call factory to enumerate all HW devices, adding any device that - // was not matched. - // 3. Remove non-matching devices. - - Lock::Locker deviceLock(GetLock()); - - DeviceCreateDesc* devDesc, *nextdevDesc; - - // 1. - for(devDesc = Devices.GetFirst(); - !Devices.IsNull(devDesc); devDesc = devDesc->pNext) - { - //if (devDesc->pFactory == factory) - devDesc->Enumerated = false; - } - - // 2. - DeviceFactory* factory = Factories.GetFirst(); - while(!Factories.IsNull(factory)) - { - EnumerateFactoryDevices(factory); - factory = factory->pNext; - } - - - // 3. - for(devDesc = Devices.GetFirst(); - !Devices.IsNull(devDesc); devDesc = nextdevDesc) - { - // In case 'devDesc' gets removed. - nextdevDesc = devDesc->pNext; - - // Note, device might be not enumerated since it is opened and - // in use! Do NOT notify 'device removed' in this case (!AB) - if (!devDesc->Enumerated) - { - // This deletes the devDesc for HandleCount == 0 due to Release in DeviceHandle. - CallOnDeviceRemoved(devDesc); - - /* - if (devDesc->HandleCount == 0) - { - // Device must be dead if it ever existed, since it AddRefs to us. - // ~DeviceCreateDesc removes its node from list. - OVR_ASSERT(!devDesc->pDevice); - delete devDesc; - } - */ - } - } - - return 0; -} - -Ptr DeviceManagerImpl::AddDevice_NeedsLock( - const DeviceCreateDesc& createDesc) -{ - // If found, mark as enumerated and we are done. - DeviceCreateDesc* descCandidate = 0; - - for(DeviceCreateDesc* devDesc = Devices.GetFirst(); - !Devices.IsNull(devDesc); devDesc = devDesc->pNext) - { - DeviceCreateDesc::MatchResult mr = devDesc->MatchDevice(createDesc, &descCandidate); - if (mr == DeviceCreateDesc::Match_Found) - { - devDesc->Enumerated = true; - if (!devDesc->pDevice) - CallOnDeviceAdded(devDesc); - return devDesc; - } - } - - // Update candidate (this may involve writing fields to HMDDevice createDesc). - if (descCandidate) - { - bool newDevice = false; - if (descCandidate->UpdateMatchedCandidate(createDesc, &newDevice)) - { - descCandidate->Enumerated = true; - if (!descCandidate->pDevice || newDevice) - CallOnDeviceAdded(descCandidate); - return descCandidate; - } - } - - // If not found, add new device. - // - This stores a new descriptor with - // {pDevice = 0, HandleCount = 1, Enumerated = true} - DeviceCreateDesc* desc = createDesc.Clone(); - desc->pLock = pCreateDesc->pLock; - Devices.PushBack(desc); - desc->Enumerated = true; - - CallOnDeviceAdded(desc); - - return desc; -} - -Ptr DeviceManagerImpl::FindDevice( - const String& path, - DeviceType deviceType) -{ - Lock::Locker deviceLock(GetLock()); - DeviceCreateDesc* devDesc; - - for (devDesc = Devices.GetFirst(); - !Devices.IsNull(devDesc); devDesc = devDesc->pNext) - { - if ((deviceType == Device_None || deviceType == devDesc->Type) && - devDesc->MatchDevice(path)) - return devDesc; - } - return NULL; -} - -Ptr DeviceManagerImpl::FindHIDDevice(const HIDDeviceDesc& hidDevDesc, bool created) -{ - Lock::Locker deviceLock(GetLock()); - DeviceCreateDesc* devDesc; - - for (devDesc = Devices.GetFirst(); - !Devices.IsNull(devDesc); devDesc = devDesc->pNext) - { - if (created) - { // Search for matching device that is created - if (devDesc->MatchHIDDevice(hidDevDesc) && devDesc->pDevice) - return devDesc; - } - else - { // Search for any matching device - if (devDesc->MatchHIDDevice(hidDevDesc)) - return devDesc; - } - } - return NULL; -} - -void DeviceManagerImpl::DetectHIDDevice(const HIDDeviceDesc& hidDevDesc) -{ - Lock::Locker deviceLock(GetLock()); - DeviceFactory* factory = Factories.GetFirst(); - while(!Factories.IsNull(factory)) - { - if (factory->DetectHIDDevice(this, hidDevDesc)) - break; - factory = factory->pNext; - } - -} - -// Enumerates devices for a particular factory. -Void DeviceManagerImpl::EnumerateFactoryDevices(DeviceFactory* factory) -{ - - class FactoryEnumerateVisitor : public DeviceFactory::EnumerateVisitor - { - DeviceManagerImpl* pManager; - DeviceFactory* pFactory; - public: - FactoryEnumerateVisitor(DeviceManagerImpl* manager, DeviceFactory* factory) - : pManager(manager), pFactory(factory) { } - - virtual void Visit(const DeviceCreateDesc& createDesc) - { - pManager->AddDevice_NeedsLock(createDesc); - } - }; - - FactoryEnumerateVisitor newDeviceVisitor(this, factory); - factory->EnumerateDevices(newDeviceVisitor); - - - return 0; -} - - -DeviceEnumerator<> DeviceManagerImpl::EnumerateDevicesEx(const DeviceEnumerationArgs& args) -{ - Lock::Locker deviceLock(GetLock()); - - if (Devices.IsEmpty()) - return DeviceEnumerator<>(); - - DeviceCreateDesc* firstDeviceDesc = Devices.GetFirst(); - DeviceEnumerator<> e = enumeratorFromHandle(DeviceHandle(firstDeviceDesc), args); - - if (!args.MatchRule(firstDeviceDesc->Type, firstDeviceDesc->Enumerated)) - { - e.Next(); - } - - return e; -} - -//------------------------------------------------------------------------------------- -// ***** DeviceCommon - -void DeviceCommon::DeviceAddRef() -{ - RefCount++; -} - -void DeviceCommon::DeviceRelease() -{ - while(1) - { - UInt32 refCount = RefCount; - OVR_ASSERT(refCount > 0); - - if (refCount == 1) - { - DeviceManagerImpl* manager = pCreateDesc->GetManagerImpl(); - ThreadCommandQueue* queue = manager->GetThreadQueue(); - - // Enqueue ReleaseDevice for {1 -> 0} transition with no wait. - // We pass our reference ownership into the queue to destroy. - // It's in theory possible for another thread to re-steal our device reference, - // but that is checked for atomically in DeviceManagerImpl::ReleaseDevice. - if (!queue->PushCall(manager, &DeviceManagerImpl::ReleaseDevice_MgrThread, - pCreateDesc->pDevice)) - { - // PushCall shouldn't fail because background thread runs while manager is - // alive and we are holding Manager alive through pParent chain. - OVR_ASSERT(false); - } - - // Warning! At his point everything, including manager, may be dead. - break; - } - else if (RefCount.CompareAndSet_NoSync(refCount, refCount-1)) - { - break; - } - } -} - - - -//------------------------------------------------------------------------------------- -// ***** DeviceCreateDesc - - -void DeviceCreateDesc::AddRef() -{ - // Technically, HandleCount { 0 -> 1 } transition can only happen during Lock, - // but we leave this to caller to worry about (happens during enumeration). - HandleCount++; -} - -void DeviceCreateDesc::Release() -{ - while(1) - { - UInt32 handleCount = HandleCount; - // HandleCount must obviously be >= 1, since we are releasing it. - OVR_ASSERT(handleCount > 0); - - // {1 -> 0} transition may cause us to be destroyed, so require a lock. - if (handleCount == 1) - { - Ptr lockKeepAlive; - Lock::Locker deviceLockScope(GetLock()); - - if (!HandleCount.CompareAndSet_NoSync(handleCount, 0)) - continue; - - OVR_ASSERT(pDevice == 0); - - // Destroy *this if the manager was destroyed already, or Enumerated - // is false (device no longer available). - if (!GetManagerImpl() || !Enumerated) - { - lockKeepAlive = pLock; - - // Remove from manager list (only matters for !Enumerated). - if (pNext) - { - RemoveNode(); - pNext = pPrev = 0; - } - - delete this; - } - - // Available DeviceCreateDesc may survive with { HandleCount == 0 }, - // in case it might be enumerated again later. - break; - } - else if (HandleCount.CompareAndSet_NoSync(handleCount, handleCount-1)) - { - break; - } - } -} - -HMDDevice* HMDDevice::Disconnect(SensorDevice* psensor) -{ - if (!psensor) - return NULL; - - OVR::DeviceManager* manager = GetManager(); - if (manager) - { - //DeviceManagerImpl* mgrImpl = static_cast(manager); - Ptr desc = getDeviceCommon()->pCreateDesc; - if (desc) - { - class Visitor : public DeviceFactory::EnumerateVisitor - { - Ptr Desc; - public: - Visitor(DeviceCreateDesc* desc) : Desc(desc) {} - virtual void Visit(const DeviceCreateDesc& createDesc) - { - Lock::Locker lock(Desc->GetLock()); - Desc->UpdateMatchedCandidate(createDesc); - } - } visitor(desc); - //SensorDeviceImpl* sImpl = static_cast(psensor); - - SensorDisplayInfoImpl displayInfo; - - if (psensor->GetFeatureReport(displayInfo.Buffer, SensorDisplayInfoImpl::PacketSize)) - { - displayInfo.Unpack(); - - // If we got display info, try to match / create HMDDevice as well - // so that sensor settings give preference. - if (displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) - { - SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo(displayInfo, visitor); - } - } - } - } - return this; -} - -bool HMDDevice::IsDisconnected() const -{ - OVR::HMDInfo info; - GetDeviceInfo(&info); - // if strlen(info.DisplayDeviceName) == 0 then - // this HMD is 'fake' (created using sensor). - return (strlen(info.DisplayDeviceName) == 0); -} - - -} // namespace OVR - diff --git a/LibOVR/Src/OVR_DeviceImpl.h b/LibOVR/Src/OVR_DeviceImpl.h deleted file mode 100644 index 8e737a5..0000000 --- a/LibOVR/Src/OVR_DeviceImpl.h +++ /dev/null @@ -1,428 +0,0 @@ -/************************************************************************************ - -Filename : OVR_DeviceImpl.h -Content : Partial back-end independent implementation of Device interfaces -Created : October 10, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceImpl_h -#define OVR_DeviceImpl_h - -#include "OVR_Device.h" -#include "Kernel/OVR_Atomic.h" -#include "Kernel/OVR_Log.h" -#include "Kernel/OVR_System.h" - -#include "Kernel/OVR_Threads.h" -#include "OVR_ThreadCommandQueue.h" -#include "OVR_HIDDevice.h" - -namespace OVR { - -class DeviceManagerImpl; -class DeviceFactory; - -enum -{ - Oculus_VendorId = 0x2833, - Device_Tracker_ProductId = 0x0001, - Device_Tracker2_ProductId = 0x0021, - Device_KTracker_ProductId = 0x0010, -}; - - -// Wrapper for MessageHandler that includes synchronization logic. -class MessageHandlerRef -{ - enum - { - MaxHandlersCount = 4 - }; -public: - MessageHandlerRef(DeviceBase* device); - ~MessageHandlerRef(); - - bool HasHandlers() const { return HandlersCount > 0; }; - void AddHandler(MessageHandler* handler); - // returns false if the handler is not found - bool RemoveHandler(MessageHandler* handler); - // Not-thread-safe version - void AddHandler_NTS(MessageHandler* handler); - - void Call(const Message& msg); - - Lock* GetLock() const { return pLock; } - DeviceBase* GetDevice() const { return pDevice; } - -private: - Lock* pLock; // Cached global handler lock. - DeviceBase* pDevice; - - int HandlersCount; - MessageHandler* pHandlers[MaxHandlersCount]; - - bool removeHandler(int idx); -}; - - -//------------------------------------------------------------------------------------- - -// DeviceManagerLock is a synchronization lock used by DeviceManager for Devices -// and is allocated separately for potentially longer lifetime. -// -// DeviceManagerLock is used for all of the following: -// - Adding/removing devices -// - Reporting manager lifetime (pManager != 0) for DeviceHandles -// - Protecting device creation/shutdown. - -class DeviceManagerLock : public RefCountBase -{ -public: - Lock CreateLock; - DeviceManagerImpl* pManager; - - DeviceManagerLock() : pManager(0) { } -}; - - -// DeviceCreateDesc provides all of the information needed to create any device, a derived -// instance of this class is created by DeviceFactory during enumeration. -// - DeviceCreateDesc may or may not be a part of DeviceManager::Devices list (check pNext != 0). -// - Referenced and kept alive by DeviceHandle. - -class DeviceCreateDesc : public ListNode, public NewOverrideBase -{ - void operator = (const DeviceCreateDesc&) { } // Assign not supported; suppress MSVC warning. -public: - DeviceCreateDesc(DeviceFactory* factory, DeviceType type) - : pFactory(factory), Type(type), pLock(0), HandleCount(0), pDevice(0), Enumerated(true) - { - pNext = pPrev = 0; - } - - virtual ~DeviceCreateDesc() - { - OVR_ASSERT(!pDevice); - if (pNext) - RemoveNode(); - } - - DeviceManagerImpl* GetManagerImpl() const { return pLock->pManager; } - Lock* GetLock() const { return &pLock->CreateLock; } - - // DeviceCreateDesc reference counting is tied to Devices list management, - // see comments for HandleCount. - void AddRef(); - void Release(); - - - // *** Device creation/matching Interface - - - // Cloning copies us to an allocated object when new device is enumerated. - virtual DeviceCreateDesc* Clone() const = 0; - // Creates a new device instance without Initializing it; the - // later is done my Initialize()/Shutdown() methods of the device itself. - virtual DeviceBase* NewDeviceInstance() = 0; - // Override to return device-specific info. - virtual bool GetDeviceInfo(DeviceInfo* info) const = 0; - - - enum MatchResult - { - Match_None, - Match_Found, - Match_Candidate - }; - - // Override to return Match_Found if descriptor matches our device. - // Match_Candidate can be returned, with pcandicate update, if this may be a match - // but more searching is necessary. If this is the case UpdateMatchedCandidate will be called. - virtual MatchResult MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc** pcandidate) const = 0; - - // Called for matched candidate after all potential matches are iterated. - // Used to update HMDevice creation arguments from Sensor. - // Optional return param 'newDeviceFlag' will be set to true if the - // 'desc' refers to a new device; false, otherwise. - // Return 'false' to create new object, 'true' if done with this argument. - virtual bool UpdateMatchedCandidate( - const DeviceCreateDesc& desc, bool* newDeviceFlag = NULL) - { OVR_UNUSED2(desc, newDeviceFlag); return false; } - - // Matches HID device to the descriptor. - virtual bool MatchHIDDevice(const HIDDeviceDesc&) const { return false; } - - // Matches device by path. - virtual bool MatchDevice(const String& /*path*/) { return false; } -//protected: - DeviceFactory* const pFactory; - const DeviceType Type; - - // List in which this descriptor lives. pList->CreateLock required if added/removed. - Ptr pLock; - - // Strong references to us: Incremented by Device, DeviceHandles & Enumerators. - // May be 0 if device not created and there are no handles. - // Following transitions require pList->CreateLock: - // {1 -> 0}: May delete & remove handle if no longer available. - // {0 -> 1}: Device creation is only possible if manager is still alive. - AtomicInt HandleCount; - // If not null, points to our created device instance. Modified during lock only. - DeviceBase* pDevice; - // True if device is marked as available during enumeration. - bool Enumerated; -}; - - - -// Common data present in the implementation of every DeviceBase. -// Injected by DeviceImpl. -class DeviceCommon -{ -public: - AtomicInt RefCount; - Ptr pCreateDesc; - Ptr pParent; - volatile bool ConnectedFlag; - MessageHandlerRef HandlerRef; - - DeviceCommon(DeviceCreateDesc* createDesc, DeviceBase* device, DeviceBase* parent) - : RefCount(1), pCreateDesc(createDesc), pParent(parent), - ConnectedFlag(true), HandlerRef(device) - { - } - virtual ~DeviceCommon() {} - - // Device reference counting delegates to Manager thread to actually kill devices. - void DeviceAddRef(); - void DeviceRelease(); - - Lock* GetLock() const { return pCreateDesc->GetLock(); } - - virtual bool Initialize(DeviceBase* parent) = 0; - virtual void Shutdown() = 0; -}; - - -//------------------------------------------------------------------------------------- -// DeviceImpl address DeviceRecord implementation to a device base class B. -// B must be derived form DeviceBase. - -template -class DeviceImpl : public B, public DeviceCommon -{ -public: - DeviceImpl(DeviceCreateDesc* createDesc, DeviceBase* parent) - : DeviceCommon(createDesc, getThis(), parent) - { - } - - // Convenience method to avoid manager access typecasts. - DeviceManagerImpl* GetManagerImpl() const { return pCreateDesc->pLock->pManager; } - - // Inline to avoid warnings. - DeviceImpl* getThis() { return this; } - - // Common implementation delegate to avoid virtual inheritance and dynamic casts. - virtual DeviceCommon* getDeviceCommon() const { return (DeviceCommon*)this; } - - /* - virtual void AddRef() { pCreateDesc->DeviceAddRef(); } - virtual void Release() { pCreateDesc->DeviceRelease(); } - virtual DeviceBase* GetParent() const { return pParent.GetPtr(); } - virtual DeviceManager* GetManager() const { return pCreateDesc->pLock->pManager;} - virtual void SetMessageHandler(MessageHandler* handler) { HanderRef.SetHandler(handler); } - virtual MessageHandler* GetMessageHandler() const { return HanderRef.GetHandler(); } - virtual DeviceType GetType() const { return pCreateDesc->Type; } - virtual DeviceType GetType() const { return pCreateDesc->Type; } - */ -}; - - -//------------------------------------------------------------------------------------- -// ***** DeviceFactory - -// DeviceFactory is maintained in DeviceManager for each separately-enumerable -// device type; factories allow separation of unrelated enumeration code. - -class DeviceFactory : public ListNode, public NewOverrideBase -{ -public: - - DeviceFactory() : pManager(0) - { - pNext = pPrev = 0; - } - virtual ~DeviceFactory() { } - - DeviceManagerImpl* GetManagerImpl() { return pManager; } - - // Notifiers called when we are added to/removed from a device. - virtual bool AddedToManager(DeviceManagerImpl* manager) - { - OVR_ASSERT(pManager == 0); - pManager = manager; - return true; - } - - virtual void RemovedFromManager() - { - pManager = 0; - } - - - // *** Device Enumeration/Creation Support - - // Passed to EnumerateDevices to be informed of every device detected. - class EnumerateVisitor - { - public: - virtual void Visit(const DeviceCreateDesc& createDesc) = 0; - }; - - // Enumerates factory devices by notifying EnumerateVisitor about every - // device that is present. - virtual void EnumerateDevices(EnumerateVisitor& visitor) = 0; - - // Matches vendorId/productId pair with the factory; returns 'true' - // if the factory can handle the device. - virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const - { - OVR_UNUSED2(vendorId, productId); - return false; - } - - // Detects the HID device and adds the DeviceCreateDesc into Devices list, if - // the device belongs to this factory. Returns 'false', if not. - virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc) - { - OVR_UNUSED2(pdevMgr, desc); - return false; - } - -protected: - DeviceManagerImpl* pManager; -}; - - -//------------------------------------------------------------------------------------- -// ***** DeviceManagerImpl - -// DeviceManagerImpl is a partial default DeviceManager implementation that -// maintains a list of devices and supports their enumeration. - -class DeviceManagerImpl : public DeviceImpl, public ThreadCommandQueue -{ -public: - DeviceManagerImpl(); - ~DeviceManagerImpl(); - - // Constructor helper function to create Descriptor and manager lock during initialization. - static DeviceCreateDesc* CreateManagerDesc(); - - // DeviceManagerImpl provides partial implementation of Initialize/Shutdown that must - // be called by the platform-specific derived class. - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - - // Every DeviceManager has an associated profile manager, which is used to store - // user settings that may affect device behavior. - virtual ProfileManager* GetProfileManager() const { return pProfileManager.GetPtr(); } - - // Override to return ThreadCommandQueue implementation used to post commands - // to the background device manager thread (that must be created by Initialize). - virtual ThreadCommandQueue* GetThreadQueue() = 0; - - // Returns the thread id of the DeviceManager. - virtual ThreadId GetThreadId() const = 0; - - virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args); - - - // - void AddFactory(DeviceFactory* factory) - { - // This lock is only needed if we call AddFactory after manager thread creation. - Lock::Locker scopeLock(GetLock()); - Factories.PushBack(factory); - factory->AddedToManager(this); - } - - void CallOnDeviceAdded(DeviceCreateDesc* desc) - { - HandlerRef.Call(MessageDeviceStatus(Message_DeviceAdded, this, DeviceHandle(desc))); - } - void CallOnDeviceRemoved(DeviceCreateDesc* desc) - { - HandlerRef.Call(MessageDeviceStatus(Message_DeviceRemoved, this, DeviceHandle(desc))); - } - - // Helper to access Common data for a device. - static DeviceCommon* GetDeviceCommon(DeviceBase* device) - { - return device->getDeviceCommon(); - } - - - // Background-thread callbacks for DeviceCreation/Release. These - DeviceBase* CreateDevice_MgrThread(DeviceCreateDesc* createDesc, DeviceBase* parent = 0); - Void ReleaseDevice_MgrThread(DeviceBase* device); - - - // Calls EnumerateDevices() on all factories - virtual Void EnumerateAllFactoryDevices(); - // Enumerates devices for a particular factory. - virtual Void EnumerateFactoryDevices(DeviceFactory* factory); - - virtual HIDDeviceManager* GetHIDDeviceManager() const - { - return HidDeviceManager; - } - - // Adds device (DeviceCreateDesc*) into Devices. Returns NULL, - // if unsuccessful or device is already in the list. - virtual Ptr AddDevice_NeedsLock(const DeviceCreateDesc& createDesc); - - // Finds a device descriptor by path and optional type. - Ptr FindDevice(const String& path, DeviceType = Device_None); - - // Finds HID device by HIDDeviceDesc. - Ptr FindHIDDevice(const HIDDeviceDesc&, bool created); - void DetectHIDDevice(const HIDDeviceDesc&); - - // Manager Lock-protected list of devices. - List Devices; - - // Factories used to detect and manage devices. - List Factories; - -protected: - Ptr HidDeviceManager; - Ptr pProfileManager; -}; - - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/OVR_DeviceMessages.h b/LibOVR/Src/OVR_DeviceMessages.h deleted file mode 100644 index c182404..0000000 --- a/LibOVR/Src/OVR_DeviceMessages.h +++ /dev/null @@ -1,273 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_DeviceMessages.h -Content : Definition of messages generated by devices -Created : February 5, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceMessages_h -#define OVR_DeviceMessages_h - -#include "OVR_DeviceConstants.h" -#include "OVR_DeviceHandle.h" - -#include "Kernel/OVR_Math.h" -#include "Kernel/OVR_Array.h" -#include "Kernel/OVR_Color.h" -#include "Kernel/OVR_String.h" - -namespace OVR { - -class DeviceBase; -class DeviceHandle; -class String; - - -#define OVR_MESSAGETYPE(devName, msgIndex) ((Device_##devName << 8) | msgIndex) - -// MessageType identifies the structure of the Message class; based on the message, -// casting can be used to obtain the exact value. -enum MessageType -{ - // Used for unassigned message types. - Message_None = 0, - - // Device Manager Messages - Message_DeviceAdded = OVR_MESSAGETYPE(Manager, 0), // A new device is detected by manager. - Message_DeviceRemoved = OVR_MESSAGETYPE(Manager, 1), // Existing device has been plugged/unplugged. - // Sensor Messages - Message_BodyFrame = OVR_MESSAGETYPE(Sensor, 0), // Emitted by sensor at regular intervals. - Message_ExposureFrame = OVR_MESSAGETYPE(Sensor, 1), - Message_PixelRead = OVR_MESSAGETYPE(Sensor, 2), - - // Latency Tester Messages - Message_LatencyTestSamples = OVR_MESSAGETYPE(LatencyTester, 0), - Message_LatencyTestColorDetected = OVR_MESSAGETYPE(LatencyTester, 1), - Message_LatencyTestStarted = OVR_MESSAGETYPE(LatencyTester, 2), - Message_LatencyTestButton = OVR_MESSAGETYPE(LatencyTester, 3), - - Message_CameraFrame = OVR_MESSAGETYPE(Camera, 0), - Message_CameraAdded = OVR_MESSAGETYPE(Camera, 1), -}; - -//------------------------------------------------------------------------------------- -// Base class for all messages. -class Message -{ -public: - Message(MessageType type = Message_None, - DeviceBase* pdev = 0) : Type(type), pDevice(pdev) - { } - - MessageType Type; // What kind of message this is. - DeviceBase* pDevice; // Device that emitted the message. -}; - - -// Sensor BodyFrame notification. -// Sensor uses Right-Handed coordinate system to return results, with the following -// axis definitions: -// - Y Up positive -// - X Right Positive -// - Z Back Positive -// Rotations a counter-clockwise (CCW) while looking in the negative direction -// of the axis. This means they are interpreted as follows: -// - Roll is rotation around Z, counter-clockwise (tilting left) in XY plane. -// - Yaw is rotation around Y, positive for turning left. -// - Pitch is rotation around X, positive for pitching up. - -//------------------------------------------------------------------------------------- -// ***** Sensor - -class MessageBodyFrame : public Message -{ -public: - MessageBodyFrame(DeviceBase* dev) - : Message(Message_BodyFrame, dev), Temperature(0.0f), TimeDelta(0.0f) - { - } - - Vector3f Acceleration; // Acceleration in m/s^2. - Vector3f RotationRate; // Angular velocity in rad/s. - Vector3f MagneticField; // Magnetic field strength in Gauss. - float Temperature; // Temperature reading on sensor surface, in degrees Celsius. - float TimeDelta; // Time passed since last Body Frame, in seconds. - - // The absolute time from the host computers perspective that the message should be - // interpreted as. This is based on incoming timestamp and processed by a filter - // that syncs the clocks while attempting to keep the distance between messages - // device clock matching. - // - // Integration should use TimeDelta, but prediction into the future should derive - // the delta time from PredictToSeconds - AbsoluteTimeSeconds. - // - // This value will generally be <= the return from a call to ovr_GetTimeInSeconds(), - // but could be greater by under 1 ms due to system time update interrupt delays. - // - double AbsoluteTimeSeconds; -}; - -// Sent when we receive a device status changes (e.g.: -// Message_DeviceAdded, Message_DeviceRemoved). -class MessageDeviceStatus : public Message -{ -public: - MessageDeviceStatus(MessageType type, DeviceBase* dev, const DeviceHandle &hdev) - : Message(type, dev), Handle(hdev) { } - - DeviceHandle Handle; -}; - -class MessageExposureFrame : public Message -{ -public: - MessageExposureFrame(DeviceBase* dev) - : Message(Message_ExposureFrame, dev), - CameraPattern(0), CameraFrameCount(0), CameraTimeSeconds(0) { } - - UByte CameraPattern; - UInt32 CameraFrameCount; - double CameraTimeSeconds; -}; - -class MessagePixelRead : public Message -{ -public: - MessagePixelRead(DeviceBase* dev) - : Message(Message_PixelRead, dev), - PixelReadValue(0), SensorTimeSeconds(0), FrameTimeSeconds(0) { } - - UByte PixelReadValue; - UInt32 RawSensorTime; - UInt32 RawFrameTime; - double SensorTimeSeconds; - double FrameTimeSeconds; -}; - -//------------------------------------------------------------------------------------- -// ***** Latency Tester - -// Sent when we receive Latency Tester samples. -class MessageLatencyTestSamples : public Message -{ -public: - MessageLatencyTestSamples(DeviceBase* dev) - : Message(Message_LatencyTestSamples, dev) - { - } - - Array Samples; -}; - -// Sent when a Latency Tester 'color detected' event occurs. -class MessageLatencyTestColorDetected : public Message -{ -public: - MessageLatencyTestColorDetected(DeviceBase* dev) - : Message(Message_LatencyTestColorDetected, dev) - { - } - - UInt16 Elapsed; - Color DetectedValue; - Color TargetValue; -}; - -// Sent when a Latency Tester 'change color' event occurs. -class MessageLatencyTestStarted : public Message -{ -public: - MessageLatencyTestStarted(DeviceBase* dev) - : Message(Message_LatencyTestStarted, dev) - { - } - - Color TargetValue; -}; - -// Sent when a Latency Tester 'button' event occurs. -class MessageLatencyTestButton : public Message -{ -public: - MessageLatencyTestButton(DeviceBase* dev) - : Message(Message_LatencyTestButton, dev) - { - } - -}; - -//------------------------------------------------------------------------------------- -// ***** Camera - -// Sent by camera, frame. -class MessageCameraFrame : public Message -{ -public: - MessageCameraFrame(DeviceBase* dev) - : Message(Message_CameraFrame, dev), CameraHandle(NULL), pFrameData(NULL) - { - LostFrames = 0; - } - - void SetInfo(UInt32 frameNumber, double timeSeconds, UInt32 width, UInt32 height, UInt32 format) - { - FrameNumber = frameNumber; - ArrivalTimeSeconds = timeSeconds; - Width = width; - Height = height; - Format = format; - } - - void SetData(const UByte* pdata, UInt32 sizeInBytes) - { - pFrameData = pdata; - FrameSizeInBytes = sizeInBytes; - } - - UInt32 FrameNumber; // an index of the frame - double ArrivalTimeSeconds; // frame time in seconds, as recorded by the host computer - const UByte* pFrameData; // a ptr to frame data. - UInt32 FrameSizeInBytes; // size of the data in the pFrameData. - UInt32 Width, Height; // width & height in pixels. - UInt32 Format; // format of pixel, see CameraDevice::PixelFormat enum - UInt32 LostFrames; // number of lost frames before this frame - String DeviceIdentifier; // identifies the device sensing the message - UInt32* CameraHandle; // Identifies the camera object associated with this frame -}; - -// Sent when a new camera is connected -class MessageCameraAdded : public Message -{ -public: - MessageCameraAdded(DeviceBase* dev) - : Message(Message_CameraAdded, dev) { } - - MessageCameraAdded(UInt32* cam) - : Message(Message_CameraAdded, NULL), CameraHandle(cam) { } - - UInt32* CameraHandle; // Identifies the camera object associated with this frame -}; - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/OVR_HIDDevice.h b/LibOVR/Src/OVR_HIDDevice.h deleted file mode 100644 index 24bfcfa..0000000 --- a/LibOVR/Src/OVR_HIDDevice.h +++ /dev/null @@ -1,154 +0,0 @@ -/************************************************************************************ - -Filename : OVR_HIDDevice.h -Content : Cross platform HID device interface. -Created : February 22, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HIDDevice_h -#define OVR_HIDDevice_h - -#include "OVR_HIDDeviceBase.h" - -#include "Kernel/OVR_RefCount.h" -#include "Kernel/OVR_String.h" -#include "Kernel/OVR_Timer.h" - -namespace OVR { - -class HIDDevice; -class DeviceManager; - -// HIDDeviceDesc contains interesting attributes of a HID device, including a Path -// that can be used to create it. -struct HIDDeviceDesc -{ - UInt16 VendorId; - UInt16 ProductId; - UInt16 VersionNumber; - UInt16 Usage; - UInt16 UsagePage; - String Path; // Platform specific. - String Manufacturer; - String Product; - String SerialNumber; -}; - -// HIDEnumerateVisitor exposes a Visit interface called for every detected device -// by HIDDeviceManager::Enumerate. -class HIDEnumerateVisitor -{ -public: - - // Should return true if we are interested in supporting - // this HID VendorId and ProductId pair. - virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) - { OVR_UNUSED2(vendorId, productId); return true; } - - // Override to get notified about available device. Will only be called for - // devices that matched MatchVendorProduct. - virtual void Visit(HIDDevice&, const HIDDeviceDesc&) { } -}; - - -//------------------------------------------------------------------------------------- -// ***** HIDDeviceManager - -// Internal manager for enumerating and opening HID devices. -// If an OVR::DeviceManager is created then an OVR::HIDDeviceManager will automatically be created and can be accessed from the -// DeviceManager by calling 'GetHIDDeviceManager()'. When using HIDDeviceManager in standalone mode, the client must call -// 'Create' below. -class HIDDeviceManager : public RefCountBase -{ -public: - - // Creates a new HIDDeviceManager. Only one instance of HIDDeviceManager should be created at a time. - static HIDDeviceManager* Create(Ptr& deviceManager); - - // Enumerate HID devices using a HIDEnumerateVisitor derived visitor class. - virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor) = 0; - - // Open a HID device with the specified path. - virtual HIDDevice* Open(const String& path) = 0; - -protected: - HIDDeviceManager() - { } -}; - -//------------------------------------------------------------------------------------- -// ***** HIDDevice - -// HID device object. This is designed to be operated in synchronous -// and asynchronous modes. With no handler set, input messages will be -// stored and can be retrieved by calling 'Read' or 'ReadBlocking'. -class HIDDevice : public RefCountBase, public HIDDeviceBase -{ -public: - - HIDDevice() - : Handler(NULL) - { - } - - virtual ~HIDDevice() {} - - virtual bool SetFeatureReport(UByte* data, UInt32 length) = 0; - virtual bool GetFeatureReport(UByte* data, UInt32 length) = 0; - -// Not yet implemented. -/* - virtual bool Write(UByte* data, UInt32 length) = 0; - - virtual bool Read(UByte* pData, UInt32 length, UInt32 timeoutMilliS) = 0; - virtual bool ReadBlocking(UByte* pData, UInt32 length) = 0; -*/ - - class HIDHandler - { - public: - virtual void OnInputReport(UByte* pData, UInt32 length) - { OVR_UNUSED2(pData, length); } - - virtual double OnTicks(double tickSeconds) - { OVR_UNUSED1(tickSeconds); return 1000.0 ; } - - enum HIDDeviceMessageType - { - HIDDeviceMessage_DeviceAdded = 0, - HIDDeviceMessage_DeviceRemoved = 1 - }; - - virtual void OnDeviceMessage(HIDDeviceMessageType messageType) - { OVR_UNUSED1(messageType); } - }; - - void SetHandler(HIDHandler* handler) - { Handler = handler; } - -protected: - HIDHandler* Handler; -}; - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/OVR_HIDDeviceBase.h b/LibOVR/Src/OVR_HIDDeviceBase.h deleted file mode 100644 index 7dfd6b4..0000000 --- a/LibOVR/Src/OVR_HIDDeviceBase.h +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_HIDDeviceBase.h -Content : Definition of HID device interface. -Created : March 11, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HIDDeviceBase_h -#define OVR_HIDDeviceBase_h - -#include "Kernel/OVR_Types.h" - -namespace OVR { - -//------------------------------------------------------------------------------------- -// ***** HIDDeviceBase - -// Base interface for HID devices. -class HIDDeviceBase -{ -public: - - virtual ~HIDDeviceBase() { } - - virtual bool SetFeatureReport(UByte* data, UInt32 length) = 0; - virtual bool GetFeatureReport(UByte* data, UInt32 length) = 0; -}; - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/OVR_HIDDeviceImpl.h b/LibOVR/Src/OVR_HIDDeviceImpl.h deleted file mode 100644 index 1399da6..0000000 --- a/LibOVR/Src/OVR_HIDDeviceImpl.h +++ /dev/null @@ -1,201 +0,0 @@ -/************************************************************************************ - -Filename : OVR_HIDDeviceImpl.h -Content : Implementation of HIDDevice. -Created : March 7, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HIDDeviceImpl_h -#define OVR_HIDDeviceImpl_h - -//#include "OVR_Device.h" -#include "OVR_DeviceImpl.h" - -namespace OVR { - -//------------------------------------------------------------------------------------- -class HIDDeviceCreateDesc : public DeviceCreateDesc -{ -public: - HIDDeviceCreateDesc(DeviceFactory* factory, DeviceType type, const HIDDeviceDesc& hidDesc) - : DeviceCreateDesc(factory, type), HIDDesc(hidDesc) { } - HIDDeviceCreateDesc(const HIDDeviceCreateDesc& other) - : DeviceCreateDesc(other.pFactory, other.Type), HIDDesc(other.HIDDesc) { } - - virtual bool MatchDevice(const String& path) - { - // should it be case insensitive? - return HIDDesc.Path.CompareNoCase(path) == 0; - } - - HIDDeviceDesc HIDDesc; -}; - -//------------------------------------------------------------------------------------- -template -class HIDDeviceImpl : public DeviceImpl, public HIDDevice::HIDHandler -{ -public: - HIDDeviceImpl(HIDDeviceCreateDesc* createDesc, DeviceBase* parent) - : DeviceImpl(createDesc, parent) - { - } - - // HIDDevice::Handler interface. - virtual void OnDeviceMessage(HIDDeviceMessageType messageType) - { - MessageType handlerMessageType; - switch (messageType) { - case HIDDeviceMessage_DeviceAdded: - handlerMessageType = Message_DeviceAdded; - DeviceImpl::ConnectedFlag = true; - break; - - case HIDDeviceMessage_DeviceRemoved: - handlerMessageType = Message_DeviceRemoved; - DeviceImpl::ConnectedFlag = false; - break; - - default: OVR_ASSERT(0); return; - } - - // Do device notification. - MessageDeviceStatus status(handlerMessageType, this, OVR::DeviceHandle(this->pCreateDesc)); - this->HandlerRef.Call(status); - - // Do device manager notification. - DeviceManagerImpl* manager = this->GetManagerImpl(); - switch (handlerMessageType) { - case Message_DeviceAdded: - manager->CallOnDeviceAdded(this->pCreateDesc); - break; - - case Message_DeviceRemoved: - manager->CallOnDeviceRemoved(this->pCreateDesc); - break; - - default:; - } - } - - virtual bool Initialize(DeviceBase* parent) - { - // Open HID device. - HIDDeviceDesc& hidDesc = *getHIDDesc(); - HIDDeviceManager* pManager = GetHIDDeviceManager(); - - - HIDDevice* device = pManager->Open(hidDesc.Path); - if (!device) - { - return false; - } - - InternalDevice = *device; - InternalDevice->SetHandler(this); - - // AddRef() to parent, forcing chain to stay alive. - DeviceImpl::pParent = parent; - - return true; - } - - virtual void Shutdown() - { - InternalDevice->SetHandler(NULL); - - DeviceImpl::pParent.Clear(); - } - - DeviceManager* GetDeviceManager() - { - return DeviceImpl::pCreateDesc->GetManagerImpl(); - } - - HIDDeviceManager* GetHIDDeviceManager() - { - return DeviceImpl::pCreateDesc->GetManagerImpl()->GetHIDDeviceManager(); - } - - bool SetFeatureReport(UByte* data, UInt32 length) - { - // Push call with wait. - bool result = false; - - ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue(); - if (!pQueue->PushCallAndWaitResult(this, &HIDDeviceImpl::setFeatureReport, &result, data, length)) - return false; - - return result; - } - - bool setFeatureReport(UByte* data, UInt32 length) - { - return InternalDevice->SetFeatureReport(data, length); - } - - bool GetFeatureReport(UByte* data, UInt32 length) - { - bool result = false; - - ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue(); - if (!pQueue->PushCallAndWaitResult(this, &HIDDeviceImpl::getFeatureReport, &result, data, length)) - return false; - - return result; - } - - bool getFeatureReport(UByte* data, UInt32 length) - { - return InternalDevice->GetFeatureReport(data, length); - } - - UByte GetDeviceInterfaceVersion() - { - UInt16 versionNumber = getHIDDesc()->VersionNumber; - - // Our interface and hardware versions are represented as two BCD digits each. - // Interface version is in the last two digits. - UByte interfaceVersion = (UByte) ((versionNumber & 0x000F) >> 0) * 1 + - ((versionNumber & 0x00F0) >> 4) * 10; - return interfaceVersion; - } - -protected: - HIDDevice* GetInternalDevice() const - { - return InternalDevice; - } - - HIDDeviceDesc* getHIDDesc() const - { return &getCreateDesc()->HIDDesc; } - - HIDDeviceCreateDesc* getCreateDesc() const - { return (HIDDeviceCreateDesc*) &(*DeviceImpl::pCreateDesc); } - -private: - Ptr InternalDevice; -}; - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/OVR_JSON.cpp b/LibOVR/Src/OVR_JSON.cpp index 262a0d9..7b40fb1 100644 --- a/LibOVR/Src/OVR_JSON.cpp +++ b/LibOVR/Src/OVR_JSON.cpp @@ -30,16 +30,16 @@ Notes : THE SOFTWARE. -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -60,6 +60,10 @@ limitations under the License. #include "Kernel/OVR_SysFile.h" #include "Kernel/OVR_Log.h" +#ifdef OVR_OS_LINUX +#include +#endif + namespace OVR { @@ -67,7 +71,7 @@ namespace OVR { // Create a new copy of a string static char* JSON_strdup(const char* str) { - UPInt len = OVR_strlen(str) + 1; + size_t len = OVR_strlen(str) + 1; char* copy = (char*)OVR_ALLOC(len); if (!copy) return 0; @@ -76,18 +80,29 @@ static char* JSON_strdup(const char* str) } +//----------------------------------------------------------------------------- +// 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; - //double d=item->valuedouble; + char *str; int valueint = (int)d; if (fabs(((double)valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) { - str=(char*)OVR_ALLOC(21); // 2^64+1 can be represented in 21 chars. - if (str) - OVR_sprintf(str, 21, "%d", valueint); + return PrintInt(valueint); } else { @@ -105,6 +120,7 @@ static char* PrintNumber(double 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 }; @@ -119,8 +135,8 @@ const char* AssignError(const char** perror, const char *errorMessage) //----------------------------------------------------------------------------- // ***** JSON Node class -JSON::JSON(JSONItemType itemType) - : Type(itemType), dValue(0.0) +JSON::JSON(JSONItemType itemType) : + Type(itemType), dValue(0.) { } @@ -141,26 +157,41 @@ JSON::~JSON() const char* JSON::parseNumber(const char *num) { const char* num_start = num; - double n=0, sign=1, scale=0; + double n=0, scale=0; int subscale = 0, signsubscale = 1; - - // Could use sscanf for this? - if (*num=='-') - sign=-1,num++; // Has sign? - if (*num=='0') + 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'); + { + n = (n*10.0) + (*num++ - '0'); } while (*num>='0' && *num<='9'); // Number? } - if (*num=='.' && num[1]>='0' && num[1]<='9') + if ((*num=='.' || *num==localeSeparator) && num[1]>='0' && num[1]<='9') { num++; do @@ -174,26 +205,35 @@ const char* JSON::parseNumber(const char *num) if (*num=='e' || *num=='E') // Exponent? { num++; - if (*num=='+') + if (*num == '+') + { num++; + } else if (*num=='-') { signsubscale=-1; num++; // With sign? } - while (*num>='0' && *num<='9') - subscale=(subscale*10)+(*num++ - '0'); // Number? + while (*num >= '0' && *num <= '9') + { + subscale = (subscale * 10) + (*num++ - '0'); // Number? + } } // Number = +/- number.fraction * 10^+/- exponent - n = sign*n*pow(10.0,(scale+subscale*signsubscale)); + n *= pow(10.0, (scale + subscale*signsubscale)); + + if (!positiveSign) + { + n = -n; + } // Assign parsed value. - Type = JSON_Number; + Type = JSON_Number; dValue = n; Value.AssignString(num_start, num - num_start); - + return num; } @@ -310,9 +350,13 @@ const char* JSON::parseString(const char* str, const char** perror) 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; @@ -467,15 +511,15 @@ const char* JSON::parseValue(const char* buff, const char** perror) { Type = JSON_Bool; Value = "false"; - dValue = 0; + dValue = 0.; return buff+5; } if (!strncmp(buff,"true",4)) { Type = JSON_Bool; Value = "true"; - dValue = 1; - return buff+4; + dValue = 1.; + return buff + 4; } if (*buff=='\"') { @@ -508,7 +552,7 @@ char* JSON::PrintValue(int depth, bool fmt) { case JSON_Null: out = JSON_strdup("null"); break; case JSON_Bool: - if (dValue == 0) + if ((int)dValue == 0) out = JSON_strdup("false"); else out = JSON_strdup("true"); @@ -571,9 +615,9 @@ const char* JSON::parseArray(const char* buff, const char** perror) // 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; - SPInt len = 5; + char ** entries; + char * out = 0, *ptr,*ret; + intptr_t len = 5; bool fail = false; @@ -720,11 +764,11 @@ const char* JSON::parseObject(const char* buff, const char** perror) // 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; - SPInt len = 7, i = 0, j; - bool fail = false; + 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(); @@ -732,7 +776,7 @@ char* JSON::PrintObject(int depth, bool fmt) // Explicitly handle empty object case if (numentries == 0) { - out=(char*)OVR_ALLOC(fmt?depth+3:3); + out=(char*)OVR_ALLOC(fmt?depth+4:4); if (!out) return 0; ptr=out; @@ -775,7 +819,7 @@ char* JSON::PrintObject(int depth, bool fmt) if (str && ret) { - len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?2+depth:0); + len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?3+depth:0); } else { @@ -812,31 +856,47 @@ char* JSON::PrintObject(int depth, bool fmt) *out = '{'; ptr = out+1; if (fmt) - *ptr++='\n'; + { +#ifdef OVR_OS_WIN32 + *ptr++ = '\r'; +#endif + *ptr++ = '\n'; + } *ptr = 0; for (i=0; ipNext) + for (const JSON* p = Children.GetFirst(); !Children.IsNull(p); p = p->pNext) + { count++; + } return count; } @@ -920,11 +984,11 @@ JSON* JSON::GetItemByName(const char* name) // Adds a new item to the end of the child list void JSON::AddItem(const char *string, JSON *item) { - if (!item) - return; - - item->Name = string; - Children.PushBack(item); + if (item) + { + item->Name = string; + Children.PushBack(item); + } } /* @@ -977,28 +1041,59 @@ void JSON::RemoveLast() } } -// Helper function to simplify creation of a typed object -JSON* JSON::createHelper(JSONItemType itemType, double dval, const char* strVal) +JSON* JSON::CreateBool(bool b) { - JSON *item = new JSON(itemType); + JSON *item = new JSON(JSON_Bool); if (item) { - item->dValue = dval; - if (strVal) - item->Value = strVal; + 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) { + if (!item || item->Type != JSON_Number) + { return defValue; } - else { + else + { return item->dValue; } } @@ -1006,10 +1101,12 @@ double JSON::GetNumberByName(const char *name, double defValue) int JSON::GetIntByName(const char *name, int defValue) { JSON* item = GetItemByName(name); - if (!item || item->Type != JSON_Number) { + if (!item || item->Type != JSON_Number) + { return defValue; } - else { + else + { return (int)item->dValue; } } @@ -1017,10 +1114,12 @@ int JSON::GetIntByName(const char *name, int defValue) bool JSON::GetBoolByName(const char *name, bool defValue) { JSON* item = GetItemByName(name); - if (!item || item->Type != JSON_Bool) { + if (!item || item->Type != JSON_Bool) + { return defValue; } - else { + else + { return (int)item->dValue != 0; } } @@ -1028,10 +1127,12 @@ bool JSON::GetBoolByName(const char *name, bool defValue) String JSON::GetStringByName(const char *name, const String &defValue) { JSON* item = GetItemByName(name); - if (!item || item->Type != JSON_String) { + if (!item || item->Type != JSON_String) + { return defValue; } - else { + else + { return item->Value; } } @@ -1040,17 +1141,19 @@ String JSON::GetStringByName(const char *name, const String &defValue) // Adds an element to an array object type void JSON::AddArrayElement(JSON *item) { - if (!item) - return; - - Children.PushBack(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) { @@ -1076,9 +1179,11 @@ void JSON::InsertArrayElement(int index, JSON *item) int JSON::GetArraySize() { if (Type == JSON_Array) + { return GetItemCount(); - else - return 0; + } + + return 0; } // Returns the number value an the give array index @@ -1089,10 +1194,8 @@ double JSON::GetArrayNumber(int index) JSON* number = GetItemByIndex(index); return number ? number->dValue : 0.0; } - else - { - return 0; - } + + return 0; } // Returns the string value at the given array index @@ -1103,10 +1206,8 @@ const char* JSON::GetArrayString(int index) JSON* number = GetItemByIndex(index); return number ? number->Value : 0; } - else - { - return 0; - } + + return 0; } JSON* JSON::Copy() @@ -1139,7 +1240,7 @@ JSON* JSON::Load(const char* path, const char** perror) } int len = f.GetLength(); - UByte* buff = (UByte*)OVR_ALLOC(len + 1); + uint8_t* buff = (uint8_t*)OVR_ALLOC(len + 1); int bytes = f.Read(buff, len); f.Close(); @@ -1168,10 +1269,10 @@ bool JSON::Save(const char* path) char* text = PrintValue(0, true); if (text) { - SPInt len = OVR_strlen(text); - OVR_ASSERT(len <= (SPInt)(int)len); + intptr_t len = OVR_strlen(text); + OVR_ASSERT(len <= (intptr_t)(int)len); - int bytes = f.Write((UByte*)text, (int)len); + int bytes = f.Write((uint8_t*)text, (int)len); f.Close(); OVR_FREE(text); return (bytes == len); @@ -1182,4 +1283,5 @@ bool JSON::Save(const char* path) } } -} + +} // namespace OVR diff --git a/LibOVR/Src/OVR_JSON.h b/LibOVR/Src/OVR_JSON.h index a2a603c..488cb1d 100644 --- a/LibOVR/Src/OVR_JSON.h +++ b/LibOVR/Src/OVR_JSON.h @@ -7,16 +7,16 @@ Created : April 9, 2013 Author : Brant Lewis Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -71,12 +71,13 @@ public: // *** 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) { return createHelper(JSON_Bool, b ? 1.0 : 0.0); } - static JSON* CreateNumber(double num) { return createHelper(JSON_Number, num); } - static JSON* CreateString(const char *s) { return createHelper(JSON_String, 0.0, s); } + 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. @@ -120,6 +121,7 @@ public: 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); @@ -132,6 +134,7 @@ public: 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. @@ -144,8 +147,6 @@ public: protected: JSON(JSONItemType itemType = JSON_Object); - static JSON* createHelper(JSONItemType itemType, double dval, const char* strVal = 0); - // JSON Parsing helper functions. const char* parseValue(const char *buff, const char** perror); const char* parseNumber(const char *num); diff --git a/LibOVR/Src/OVR_LatencyTestImpl.cpp b/LibOVR/Src/OVR_LatencyTestImpl.cpp deleted file mode 100644 index 015d9e4..0000000 --- a/LibOVR/Src/OVR_LatencyTestImpl.cpp +++ /dev/null @@ -1,773 +0,0 @@ -/************************************************************************************ - -Filename : OVR_LatencyTestImpl.cpp -Content : Oculus Latency Tester device implementation. -Created : March 7, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_LatencyTestImpl.h" -#include "Kernel/OVR_Alg.h" - -namespace OVR { - -using namespace Alg; - -//------------------------------------------------------------------------------------- -// ***** Oculus Latency Tester specific packet data structures - -enum { - LatencyTester_VendorId = Oculus_VendorId, - LatencyTester_ProductId = 0x0101, -}; - -static void UnpackSamples(const UByte* buffer, UByte* r, UByte* g, UByte* b) -{ - *r = buffer[0]; - *g = buffer[1]; - *b = buffer[2]; -} - -// Messages we handle. -enum LatencyTestMessageType -{ - LatencyTestMessage_None = 0, - LatencyTestMessage_Samples = 1, - LatencyTestMessage_ColorDetected = 2, - LatencyTestMessage_TestStarted = 3, - LatencyTestMessage_Button = 4, - LatencyTestMessage_Unknown = 0x100, - LatencyTestMessage_SizeError = 0x101, -}; - -struct LatencyTestSample -{ - UByte Value[3]; -}; - -struct LatencyTestSamples -{ - UByte SampleCount; - UInt16 Timestamp; - - LatencyTestSample Samples[20]; - - LatencyTestMessageType Decode(const UByte* buffer, int size) - { - if (size < 64) - { - return LatencyTestMessage_SizeError; - } - - SampleCount = buffer[1]; - Timestamp = DecodeUInt16(buffer + 2); - - for (UByte i = 0; i < SampleCount; i++) - { - UnpackSamples(buffer + 4 + (3 * i), &Samples[i].Value[0], &Samples[i].Value[1], &Samples[i].Value[2]); - } - - return LatencyTestMessage_Samples; - } -}; - -struct LatencyTestSamplesMessage -{ - LatencyTestMessageType Type; - LatencyTestSamples Samples; -}; - -bool DecodeLatencyTestSamplesMessage(LatencyTestSamplesMessage* message, UByte* buffer, int size) -{ - memset(message, 0, sizeof(LatencyTestSamplesMessage)); - - if (size < 64) - { - message->Type = LatencyTestMessage_SizeError; - return false; - } - - switch (buffer[0]) - { - case LatencyTestMessage_Samples: - message->Type = message->Samples.Decode(buffer, size); - break; - - default: - message->Type = LatencyTestMessage_Unknown; - break; - } - - return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None); -} - -struct LatencyTestColorDetected -{ - UInt16 CommandID; - UInt16 Timestamp; - UInt16 Elapsed; - UByte TriggerValue[3]; - UByte TargetValue[3]; - - LatencyTestMessageType Decode(const UByte* buffer, int size) - { - if (size < 13) - return LatencyTestMessage_SizeError; - - CommandID = DecodeUInt16(buffer + 1); - Timestamp = DecodeUInt16(buffer + 3); - Elapsed = DecodeUInt16(buffer + 5); - memcpy(TriggerValue, buffer + 7, 3); - memcpy(TargetValue, buffer + 10, 3); - - return LatencyTestMessage_ColorDetected; - } -}; - -struct LatencyTestColorDetectedMessage -{ - LatencyTestMessageType Type; - LatencyTestColorDetected ColorDetected; -}; - -bool DecodeLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message, UByte* buffer, int size) -{ - memset(message, 0, sizeof(LatencyTestColorDetectedMessage)); - - if (size < 13) - { - message->Type = LatencyTestMessage_SizeError; - return false; - } - - switch (buffer[0]) - { - case LatencyTestMessage_ColorDetected: - message->Type = message->ColorDetected.Decode(buffer, size); - break; - - default: - message->Type = LatencyTestMessage_Unknown; - break; - } - - return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None); -} - -struct LatencyTestStarted -{ - UInt16 CommandID; - UInt16 Timestamp; - UByte TargetValue[3]; - - LatencyTestMessageType Decode(const UByte* buffer, int size) - { - if (size < 8) - return LatencyTestMessage_SizeError; - - CommandID = DecodeUInt16(buffer + 1); - Timestamp = DecodeUInt16(buffer + 3); - memcpy(TargetValue, buffer + 5, 3); - - return LatencyTestMessage_TestStarted; - } -}; - -struct LatencyTestStartedMessage -{ - LatencyTestMessageType Type; - LatencyTestStarted TestStarted; -}; - -bool DecodeLatencyTestStartedMessage(LatencyTestStartedMessage* message, UByte* buffer, int size) -{ - memset(message, 0, sizeof(LatencyTestStartedMessage)); - - if (size < 8) - { - message->Type = LatencyTestMessage_SizeError; - return false; - } - - switch (buffer[0]) - { - case LatencyTestMessage_TestStarted: - message->Type = message->TestStarted.Decode(buffer, size); - break; - - default: - message->Type = LatencyTestMessage_Unknown; - break; - } - - return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None); -} - -struct LatencyTestButton -{ - UInt16 CommandID; - UInt16 Timestamp; - - LatencyTestMessageType Decode(const UByte* buffer, int size) - { - if (size < 5) - return LatencyTestMessage_SizeError; - - CommandID = DecodeUInt16(buffer + 1); - Timestamp = DecodeUInt16(buffer + 3); - - return LatencyTestMessage_Button; - } -}; - -struct LatencyTestButtonMessage -{ - LatencyTestMessageType Type; - LatencyTestButton Button; -}; - -bool DecodeLatencyTestButtonMessage(LatencyTestButtonMessage* message, UByte* buffer, int size) -{ - memset(message, 0, sizeof(LatencyTestButtonMessage)); - - if (size < 5) - { - message->Type = LatencyTestMessage_SizeError; - return false; - } - - switch (buffer[0]) - { - case LatencyTestMessage_Button: - message->Type = message->Button.Decode(buffer, size); - break; - - default: - message->Type = LatencyTestMessage_Unknown; - break; - } - - return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None); -} - -struct LatencyTestConfigurationImpl -{ - enum { PacketSize = 5 }; - UByte Buffer[PacketSize]; - - OVR::LatencyTestConfiguration Configuration; - - LatencyTestConfigurationImpl(const OVR::LatencyTestConfiguration& configuration) - : Configuration(configuration) - { - Pack(); - } - - void Pack() - { - Buffer[0] = 5; - Buffer[1] = UByte(Configuration.SendSamples); - Buffer[2] = Configuration.Threshold.R; - Buffer[3] = Configuration.Threshold.G; - Buffer[4] = Configuration.Threshold.B; - } - - void Unpack() - { - Configuration.SendSamples = Buffer[1] != 0 ? true : false; - Configuration.Threshold.R = Buffer[2]; - Configuration.Threshold.G = Buffer[3]; - Configuration.Threshold.B = Buffer[4]; - } -}; - -struct LatencyTestCalibrateImpl -{ - enum { PacketSize = 4 }; - UByte Buffer[PacketSize]; - - Color CalibrationColor; - - LatencyTestCalibrateImpl(const Color& calibrationColor) - : CalibrationColor(calibrationColor) - { - Pack(); - } - - void Pack() - { - Buffer[0] = 7; - Buffer[1] = CalibrationColor.R; - Buffer[2] = CalibrationColor.G; - Buffer[3] = CalibrationColor.B; - } - - void Unpack() - { - CalibrationColor.R = Buffer[1]; - CalibrationColor.G = Buffer[2]; - CalibrationColor.B = Buffer[3]; - } -}; - -struct LatencyTestStartTestImpl -{ - enum { PacketSize = 6 }; - UByte Buffer[PacketSize]; - - Color TargetColor; - - LatencyTestStartTestImpl(const Color& targetColor) - : TargetColor(targetColor) - { - Pack(); - } - - void Pack() - { - UInt16 commandID = 1; - - Buffer[0] = 8; - EncodeUInt16(Buffer+1, commandID); - Buffer[3] = TargetColor.R; - Buffer[4] = TargetColor.G; - Buffer[5] = TargetColor.B; - } - - void Unpack() - { -// UInt16 commandID = DecodeUInt16(Buffer+1); - TargetColor.R = Buffer[3]; - TargetColor.G = Buffer[4]; - TargetColor.B = Buffer[5]; - } -}; - -struct LatencyTestDisplayImpl -{ - enum { PacketSize = 6 }; - UByte Buffer[PacketSize]; - - OVR::LatencyTestDisplay Display; - - LatencyTestDisplayImpl(const OVR::LatencyTestDisplay& display) - : Display(display) - { - Pack(); - } - - void Pack() - { - Buffer[0] = 9; - Buffer[1] = Display.Mode; - EncodeUInt32(Buffer+2, Display.Value); - } - - void Unpack() - { - Display.Mode = Buffer[1]; - Display.Value = DecodeUInt32(Buffer+2); - } -}; - -//------------------------------------------------------------------------------------- -// ***** LatencyTestDeviceFactory - -LatencyTestDeviceFactory &LatencyTestDeviceFactory::GetInstance() -{ - static LatencyTestDeviceFactory instance; - return instance; -} - -void LatencyTestDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) -{ - - class LatencyTestEnumerator : public HIDEnumerateVisitor - { - // Assign not supported; suppress MSVC warning. - void operator = (const LatencyTestEnumerator&) { } - - DeviceFactory* pFactory; - EnumerateVisitor& ExternalVisitor; - public: - LatencyTestEnumerator(DeviceFactory* factory, EnumerateVisitor& externalVisitor) - : pFactory(factory), ExternalVisitor(externalVisitor) { } - - virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) - { - return pFactory->MatchVendorProduct(vendorId, productId); - } - - virtual void Visit(HIDDevice& device, const HIDDeviceDesc& desc) - { - OVR_UNUSED(device); - - LatencyTestDeviceCreateDesc createDesc(pFactory, desc); - ExternalVisitor.Visit(createDesc); - } - }; - - LatencyTestEnumerator latencyTestEnumerator(this, visitor); - GetManagerImpl()->GetHIDDeviceManager()->Enumerate(&latencyTestEnumerator); -} - -bool LatencyTestDeviceFactory::MatchVendorProduct(UInt16 vendorId, UInt16 productId) const -{ - return ((vendorId == LatencyTester_VendorId) && (productId == LatencyTester_ProductId)); -} - -bool LatencyTestDeviceFactory::DetectHIDDevice(DeviceManager* pdevMgr, - const HIDDeviceDesc& desc) -{ - if (MatchVendorProduct(desc.VendorId, desc.ProductId)) - { - LatencyTestDeviceCreateDesc createDesc(this, desc); - return pdevMgr->AddDevice_NeedsLock(createDesc).GetPtr() != NULL; - } - return false; -} - -//------------------------------------------------------------------------------------- -// ***** LatencyTestDeviceCreateDesc - -DeviceBase* LatencyTestDeviceCreateDesc::NewDeviceInstance() -{ - return new LatencyTestDeviceImpl(this); -} - -bool LatencyTestDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const -{ - if ((info->InfoClassType != Device_LatencyTester) && - (info->InfoClassType != Device_None)) - return false; - - info->Type = Device_LatencyTester; - info->ProductName = HIDDesc.Product; - info->Manufacturer = HIDDesc.Manufacturer; - info->Version = HIDDesc.VersionNumber; - - if (info->InfoClassType == Device_LatencyTester) - { - SensorInfo* sinfo = (SensorInfo*)info; - sinfo->VendorId = HIDDesc.VendorId; - sinfo->ProductId = HIDDesc.ProductId; - sinfo->SerialNumber = HIDDesc.SerialNumber; - } - return true; -} - -//------------------------------------------------------------------------------------- -// ***** LatencyTestDevice - -LatencyTestDeviceImpl::LatencyTestDeviceImpl(LatencyTestDeviceCreateDesc* createDesc) - : OVR::HIDDeviceImpl(createDesc, 0) -{ -} - -LatencyTestDeviceImpl::~LatencyTestDeviceImpl() -{ - // Check that Shutdown() was called. - OVR_ASSERT(!pCreateDesc->pDevice); -} - -// Internal creation APIs. -bool LatencyTestDeviceImpl::Initialize(DeviceBase* parent) -{ - if (HIDDeviceImpl::Initialize(parent)) - { - LogText("OVR::LatencyTestDevice initialized.\n"); - return true; - } - - return false; -} - -void LatencyTestDeviceImpl::Shutdown() -{ - HIDDeviceImpl::Shutdown(); - - LogText("OVR::LatencyTestDevice - Closed '%s'\n", getHIDDesc()->Path.ToCStr()); -} - -void LatencyTestDeviceImpl::OnInputReport(UByte* pData, UInt32 length) -{ - - bool processed = false; - if (!processed) - { - LatencyTestSamplesMessage message; - if (DecodeLatencyTestSamplesMessage(&message, pData, length)) - { - processed = true; - onLatencyTestSamplesMessage(&message); - } - } - - if (!processed) - { - LatencyTestColorDetectedMessage message; - if (DecodeLatencyTestColorDetectedMessage(&message, pData, length)) - { - processed = true; - onLatencyTestColorDetectedMessage(&message); - } - } - - if (!processed) - { - LatencyTestStartedMessage message; - if (DecodeLatencyTestStartedMessage(&message, pData, length)) - { - processed = true; - onLatencyTestStartedMessage(&message); - } - } - - if (!processed) - { - LatencyTestButtonMessage message; - if (DecodeLatencyTestButtonMessage(&message, pData, length)) - { - processed = true; - onLatencyTestButtonMessage(&message); - } - } -} - -bool LatencyTestDeviceImpl::SetConfiguration(const OVR::LatencyTestConfiguration& configuration, bool waitFlag) -{ - bool result = false; - ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue(); - - if (GetManagerImpl()->GetThreadId() != OVR::GetCurrentThreadId()) - { - if (!waitFlag) - { - return queue->PushCall(this, &LatencyTestDeviceImpl::setConfiguration, configuration); - } - - if (!queue->PushCallAndWaitResult( this, - &LatencyTestDeviceImpl::setConfiguration, - &result, - configuration)) - { - return false; - } - } - else - return setConfiguration(configuration); - - return result; -} - -bool LatencyTestDeviceImpl::setConfiguration(const OVR::LatencyTestConfiguration& configuration) -{ - LatencyTestConfigurationImpl ltc(configuration); - return GetInternalDevice()->SetFeatureReport(ltc.Buffer, LatencyTestConfigurationImpl::PacketSize); -} - -bool LatencyTestDeviceImpl::GetConfiguration(OVR::LatencyTestConfiguration* configuration) -{ - bool result = false; - - ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue(); - if (!pQueue->PushCallAndWaitResult(this, &LatencyTestDeviceImpl::getConfiguration, &result, configuration)) - return false; - - return result; -} - -bool LatencyTestDeviceImpl::getConfiguration(OVR::LatencyTestConfiguration* configuration) -{ - LatencyTestConfigurationImpl ltc(*configuration); - if (GetInternalDevice()->GetFeatureReport(ltc.Buffer, LatencyTestConfigurationImpl::PacketSize)) - { - ltc.Unpack(); - *configuration = ltc.Configuration; - return true; - } - - return false; -} - -bool LatencyTestDeviceImpl::SetCalibrate(const Color& calibrationColor, bool waitFlag) -{ - bool result = false; - ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue(); - - if (!waitFlag) - { - return queue->PushCall(this, &LatencyTestDeviceImpl::setCalibrate, calibrationColor); - } - - if (!queue->PushCallAndWaitResult( this, - &LatencyTestDeviceImpl::setCalibrate, - &result, - calibrationColor)) - { - return false; - } - - return result; -} - -bool LatencyTestDeviceImpl::setCalibrate(const Color& calibrationColor) -{ - LatencyTestCalibrateImpl ltc(calibrationColor); - return GetInternalDevice()->SetFeatureReport(ltc.Buffer, LatencyTestCalibrateImpl::PacketSize); -} - -bool LatencyTestDeviceImpl::SetStartTest(const Color& targetColor, bool waitFlag) -{ - bool result = false; - ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue(); - - if (!waitFlag) - { - return queue->PushCall(this, &LatencyTestDeviceImpl::setStartTest, targetColor); - } - - if (!queue->PushCallAndWaitResult( this, - &LatencyTestDeviceImpl::setStartTest, - &result, - targetColor)) - { - return false; - } - - return result; -} - -bool LatencyTestDeviceImpl::setStartTest(const Color& targetColor) -{ - LatencyTestStartTestImpl ltst(targetColor); - return GetInternalDevice()->SetFeatureReport(ltst.Buffer, LatencyTestStartTestImpl::PacketSize); -} - -bool LatencyTestDeviceImpl::SetDisplay(const OVR::LatencyTestDisplay& display, bool waitFlag) -{ - bool result = false; - ThreadCommandQueue * queue = GetManagerImpl()->GetThreadQueue(); - - if (!waitFlag) - { - return queue->PushCall(this, &LatencyTestDeviceImpl::setDisplay, display); - } - - if (!queue->PushCallAndWaitResult( this, - &LatencyTestDeviceImpl::setDisplay, - &result, - display)) - { - return false; - } - - return result; -} - -bool LatencyTestDeviceImpl::setDisplay(const OVR::LatencyTestDisplay& display) -{ - LatencyTestDisplayImpl ltd(display); - return GetInternalDevice()->SetFeatureReport(ltd.Buffer, LatencyTestDisplayImpl::PacketSize); -} - -void LatencyTestDeviceImpl::onLatencyTestSamplesMessage(LatencyTestSamplesMessage* message) -{ - - if (message->Type != LatencyTestMessage_Samples) - return; - - LatencyTestSamples& s = message->Samples; - - // Call OnMessage() within a lock to avoid conflicts with handlers. - Lock::Locker scopeLock(HandlerRef.GetLock()); - - if (HandlerRef.HasHandlers()) - { - MessageLatencyTestSamples samples(this); - for (UByte i = 0; i < s.SampleCount; i++) - { - samples.Samples.PushBack(Color(s.Samples[i].Value[0], s.Samples[i].Value[1], s.Samples[i].Value[2])); - } - - HandlerRef.Call(samples); - } -} - -void LatencyTestDeviceImpl::onLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message) -{ - if (message->Type != LatencyTestMessage_ColorDetected) - return; - - LatencyTestColorDetected& s = message->ColorDetected; - - // Call OnMessage() within a lock to avoid conflicts with handlers. - Lock::Locker scopeLock(HandlerRef.GetLock()); - - if (HandlerRef.HasHandlers()) - { - MessageLatencyTestColorDetected detected(this); - detected.Elapsed = s.Elapsed; - detected.DetectedValue = Color(s.TriggerValue[0], s.TriggerValue[1], s.TriggerValue[2]); - detected.TargetValue = Color(s.TargetValue[0], s.TargetValue[1], s.TargetValue[2]); - - HandlerRef.Call(detected); - } -} - -void LatencyTestDeviceImpl::onLatencyTestStartedMessage(LatencyTestStartedMessage* message) -{ - if (message->Type != LatencyTestMessage_TestStarted) - return; - - LatencyTestStarted& ts = message->TestStarted; - - // Call OnMessage() within a lock to avoid conflicts with handlers. - Lock::Locker scopeLock(HandlerRef.GetLock()); - - if (HandlerRef.HasHandlers()) - { - MessageLatencyTestStarted started(this); - started.TargetValue = Color(ts.TargetValue[0], ts.TargetValue[1], ts.TargetValue[2]); - - HandlerRef.Call(started); - } -} - -void LatencyTestDeviceImpl::onLatencyTestButtonMessage(LatencyTestButtonMessage* message) -{ - if (message->Type != LatencyTestMessage_Button) - return; - -// LatencyTestButton& s = message->Button; - - // Call OnMessage() within a lock to avoid conflicts with handlers. - Lock::Locker scopeLock(HandlerRef.GetLock()); - - if (HandlerRef.HasHandlers()) - { - MessageLatencyTestButton button(this); - - HandlerRef.Call(button); - } -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_LatencyTestImpl.h b/LibOVR/Src/OVR_LatencyTestImpl.h deleted file mode 100644 index 34faec2..0000000 --- a/LibOVR/Src/OVR_LatencyTestImpl.h +++ /dev/null @@ -1,144 +0,0 @@ -/************************************************************************************ - -Filename : OVR_LatencyTestImpl.h -Content : Latency Tester specific implementation. -Created : March 7, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_LatencyTestImpl_h -#define OVR_LatencyTestImpl_h - -#include "OVR_HIDDeviceImpl.h" - -namespace OVR { - -struct LatencyTestSamplesMessage; -struct LatencyTestButtonMessage; -struct LatencyTestStartedMessage; -struct LatencyTestColorDetectedMessage; - -//------------------------------------------------------------------------------------- -// LatencyTestDeviceFactory enumerates Oculus Latency Tester devices. -class LatencyTestDeviceFactory : public DeviceFactory -{ -public: - static LatencyTestDeviceFactory &GetInstance(); - - // Enumerates devices, creating and destroying relevant objects in manager. - virtual void EnumerateDevices(EnumerateVisitor& visitor); - - virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const; - virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc); - -protected: - DeviceManager* getManager() const { return (DeviceManager*) pManager; } -}; - - -// Describes a single a Oculus Latency Tester device and supports creating its instance. -class LatencyTestDeviceCreateDesc : public HIDDeviceCreateDesc -{ -public: - LatencyTestDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc) - : HIDDeviceCreateDesc(factory, Device_LatencyTester, hidDesc) { } - - virtual DeviceCreateDesc* Clone() const - { - return new LatencyTestDeviceCreateDesc(*this); - } - - virtual DeviceBase* NewDeviceInstance(); - - virtual MatchResult MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc**) const - { - if ((other.Type == Device_LatencyTester) && (pFactory == other.pFactory)) - { - const LatencyTestDeviceCreateDesc& s2 = (const LatencyTestDeviceCreateDesc&) other; - if (MatchHIDDevice(s2.HIDDesc)) - return Match_Found; - } - return Match_None; - } - - virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const - { - // should paths comparison be case insensitive? - return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) && - (HIDDesc.SerialNumber == hidDesc.SerialNumber)); - } - virtual bool GetDeviceInfo(DeviceInfo* info) const; -}; - - -//------------------------------------------------------------------------------------- -// ***** OVR::LatencyTestDeviceImpl - -// Oculus Latency Tester interface. - -class LatencyTestDeviceImpl : public HIDDeviceImpl -{ -public: - LatencyTestDeviceImpl(LatencyTestDeviceCreateDesc* createDesc); - ~LatencyTestDeviceImpl(); - - // DeviceCommon interface. - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - // DeviceManagerThread::Notifier interface. - virtual void OnInputReport(UByte* pData, UInt32 length); - - // LatencyTesterDevice interface - virtual bool SetConfiguration(const OVR::LatencyTestConfiguration& configuration, bool waitFlag = false); - virtual bool GetConfiguration(OVR::LatencyTestConfiguration* configuration); - - virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false); - - virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false); - virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false); - -protected: - bool openDevice(const char** errorFormatString); - void closeDevice(); - void closeDeviceOnIOError(); - - bool initializeRead(); - bool processReadResult(); - - bool setConfiguration(const OVR::LatencyTestConfiguration& configuration); - bool getConfiguration(OVR::LatencyTestConfiguration* configuration); - bool setCalibrate(const Color& calibrationColor); - bool setStartTest(const Color& targetColor); - bool setDisplay(const OVR::LatencyTestDisplay& display); - - // Called for decoded messages - void onLatencyTestSamplesMessage(LatencyTestSamplesMessage* message); - void onLatencyTestButtonMessage(LatencyTestButtonMessage* message); - void onLatencyTestStartedMessage(LatencyTestStartedMessage* message); - void onLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message); - -}; - -} // namespace OVR - -#endif // OVR_LatencyTestImpl_h diff --git a/LibOVR/Src/OVR_Linux_DeviceManager.cpp b/LibOVR/Src/OVR_Linux_DeviceManager.cpp deleted file mode 100644 index f1c4278..0000000 --- a/LibOVR/Src/OVR_Linux_DeviceManager.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Linux_DeviceManager.h -Content : Linux implementation of DeviceManager. -Created : -Authors : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceManager.h" - -// Sensor & HMD Factories -#include "OVR_LatencyTestImpl.h" -#include "OVR_SensorImpl.h" -#include "OVR_Linux_HIDDevice.h" -#include "OVR_Linux_HMDDevice.h" - -#include "Kernel/OVR_Timer.h" -#include "Kernel/OVR_Std.h" -#include "Kernel/OVR_Log.h" - -namespace OVR { namespace Linux { - - -//------------------------------------------------------------------------------------- -// **** Linux::DeviceManager - -DeviceManager::DeviceManager() -{ -} - -DeviceManager::~DeviceManager() -{ -} - -bool DeviceManager::Initialize(DeviceBase*) -{ - if (!DeviceManagerImpl::Initialize(0)) - return false; - - pThread = *new DeviceManagerThread(); - if (!pThread || !pThread->Start()) - return false; - - // Wait for the thread to be fully up and running. - pThread->StartupEvent.Wait(); - - // Do this now that we know the thread's run loop. - HidDeviceManager = *HIDDeviceManager::CreateInternal(this); - - pCreateDesc->pDevice = this; - LogText("OVR::DeviceManager - initialized.\n"); - return true; -} - -void DeviceManager::Shutdown() -{ - LogText("OVR::DeviceManager - shutting down.\n"); - - // Set Manager shutdown marker variable; this prevents - // any existing DeviceHandle objects from accessing device. - pCreateDesc->pLock->pManager = 0; - - // Push for thread shutdown *WITH NO WAIT*. - // This will have the following effect: - // - Exit command will get enqueued, which will be executed later on the thread itself. - // - Beyond this point, this DeviceManager object may be deleted by our caller. - // - Other commands, such as CreateDevice, may execute before ExitCommand, but they will - // fail gracefully due to pLock->pManager == 0. Future commands can't be enqued - // after pManager is null. - // - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last - // reference to the thread object. - pThread->PushExitCommand(false); - pThread.Clear(); - - DeviceManagerImpl::Shutdown(); -} - -ThreadCommandQueue* DeviceManager::GetThreadQueue() -{ - return pThread; -} - -ThreadId DeviceManager::GetThreadId() const -{ - return pThread->GetThreadId(); -} - -bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const -{ - if ((info->InfoClassType != Device_Manager) && - (info->InfoClassType != Device_None)) - return false; - - info->Type = Device_Manager; - info->Version = 0; - info->ProductName = "DeviceManager"; - info->Manufacturer = "Oculus VR, Inc."; - return true; -} - -DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args) -{ - // TBD: Can this be avoided in the future, once proper device notification is in place? - pThread->PushCall((DeviceManagerImpl*)this, - &DeviceManager::EnumerateAllFactoryDevices, true); - - return DeviceManagerImpl::EnumerateDevicesEx(args); -} - - -//------------------------------------------------------------------------------------- -// ***** DeviceManager Thread - -DeviceManagerThread::DeviceManagerThread() - : Thread(ThreadStackSize) -{ - int result = pipe(CommandFd); - OVR_ASSERT(!result); - OVR_UNUSED(result); - - AddSelectFd(NULL, CommandFd[0]); -} - -DeviceManagerThread::~DeviceManagerThread() -{ - if (CommandFd[0]) - { - RemoveSelectFd(NULL, CommandFd[0]); - close(CommandFd[0]); - close(CommandFd[1]); - } -} - -bool DeviceManagerThread::AddSelectFd(Notifier* notify, int fd) -{ - struct pollfd pfd; - pfd.fd = fd; - pfd.events = POLLIN|POLLHUP|POLLERR; - pfd.revents = 0; - - FdNotifiers.PushBack(notify); - PollFds.PushBack(pfd); - - OVR_ASSERT(FdNotifiers.GetSize() == PollFds.GetSize()); - return true; -} - -bool DeviceManagerThread::RemoveSelectFd(Notifier* notify, int fd) -{ - // [0] is reserved for thread commands with notify of null, but we still - // can use this function to remove it. - for (UPInt i = 0; i < FdNotifiers.GetSize(); i++) - { - if ((FdNotifiers[i] == notify) && (PollFds[i].fd == fd)) - { - FdNotifiers.RemoveAt(i); - PollFds.RemoveAt(i); - return true; - } - } - return false; -} - - - -int DeviceManagerThread::Run() -{ - ThreadCommand::PopBuffer command; - - SetThreadName("OVR::DeviceManagerThread"); - LogText("OVR::DeviceManagerThread - running (ThreadId=%p).\n", GetThreadId()); - - // Signal to the parent thread that initialization has finished. - StartupEvent.SetEvent(); - - while(!IsExiting()) - { - // PopCommand will reset event on empty queue. - if (PopCommand(&command)) - { - command.Execute(); - } - else - { - bool commands = 0; - do - { - int waitMs = -1; - - // If devices have time-dependent logic registered, get the longest wait - // allowed based on current ticks. - if (!TicksNotifiers.IsEmpty()) - { - double timeSeconds = Timer::GetSeconds(); - unsigned waitAllowed; - - for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++) - { - waitAllowed = (unsigned)(TicksNotifiers[j]->OnTicks(timeSeconds) * Timer::MsPerSecond); - if (waitAllowed < (unsigned)waitMs) - waitMs = waitAllowed; - } - } - - // wait until there is data available on one of the devices or the timeout expires - int n = poll(&PollFds[0], PollFds.GetSize(), waitMs); - - if (n > 0) - { - // Iterate backwards through the list so the ordering will not be - // affected if the called object gets removed during the callback - // Also, the HID data streams are located toward the back of the list - // and servicing them first will allow a disconnect to be handled - // and cleaned directly at the device first instead of the general HID monitor - for (int i=PollFds.GetSize()-1; i>=0; i--) - { - if (PollFds[i].revents & POLLERR) - { - OVR_DEBUG_LOG(("poll: error on [%d]: %d", i, PollFds[i].fd)); - } - else if (PollFds[i].revents & POLLIN) - { - if (FdNotifiers[i]) - FdNotifiers[i]->OnEvent(i, PollFds[i].fd); - else if (i == 0) // command - { - char dummy[128]; - read(PollFds[i].fd, dummy, 128); - commands = 1; - } - } - - if (PollFds[i].revents & POLLHUP) - PollFds[i].events = 0; - - if (PollFds[i].revents != 0) - { - n--; - if (n == 0) - break; - } - } - } - } while (PollFds.GetSize() > 0 && !commands); - } - } - - LogText("OVR::DeviceManagerThread - exiting (ThreadId=%p).\n", GetThreadId()); - return 0; -} - -bool DeviceManagerThread::AddTicksNotifier(Notifier* notify) -{ - TicksNotifiers.PushBack(notify); - return true; -} - -bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify) -{ - for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++) - { - if (TicksNotifiers[i] == notify) - { - TicksNotifiers.RemoveAt(i); - return true; - } - } - return false; -} - -} // namespace Linux - - -//------------------------------------------------------------------------------------- -// ***** Creation - - -// Creates a new DeviceManager and initializes OVR. -DeviceManager* DeviceManager::Create() -{ - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr manager = *new Linux::DeviceManager; - - if (manager) - { - if (manager->Initialize(0)) - { - manager->AddFactory(&LatencyTestDeviceFactory::GetInstance()); - manager->AddFactory(&SensorDeviceFactory::GetInstance()); - manager->AddFactory(&Linux::HMDDeviceFactory::GetInstance()); - - manager->AddRef(); - } - else - { - manager.Clear(); - } - - } - - return manager.GetPtr(); -} - - -} // namespace OVR - diff --git a/LibOVR/Src/OVR_Linux_DeviceManager.h b/LibOVR/Src/OVR_Linux_DeviceManager.h deleted file mode 100644 index 6532103..0000000 --- a/LibOVR/Src/OVR_Linux_DeviceManager.h +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Linux_DeviceManager.h -Content : Linux-specific DeviceManager header. -Created : -Authors : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceManager_h -#define OVR_Linux_DeviceManager_h - -#include "OVR_DeviceImpl.h" - -#include -#include - - -namespace OVR { namespace Linux { - -class DeviceManagerThread; - -//------------------------------------------------------------------------------------- -// ***** Linux DeviceManager - -class DeviceManager : public DeviceManagerImpl -{ -public: - DeviceManager(); - ~DeviceManager(); - - // Initialize/Shutdowncreate and shutdown manger thread. - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - virtual ThreadCommandQueue* GetThreadQueue(); - virtual ThreadId GetThreadId() const; - - virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args); - - virtual bool GetDeviceInfo(DeviceInfo* info) const; - - Ptr pThread; -}; - -//------------------------------------------------------------------------------------- -// ***** Device Manager Background Thread - -class DeviceManagerThread : public Thread, public ThreadCommandQueue -{ - friend class DeviceManager; - enum { ThreadStackSize = 64 * 1024 }; -public: - DeviceManagerThread(); - ~DeviceManagerThread(); - - virtual int Run(); - - // ThreadCommandQueue notifications for CommandEvent handling. - virtual void OnPushNonEmpty_Locked() { write(CommandFd[1], this, 1); } - virtual void OnPopEmpty_Locked() { } - - class Notifier - { - public: - // Called when I/O is received - virtual void OnEvent(int i, int fd) = 0; - - // Called when timing ticks are updated. - // Returns the largest number of seconds this function can - // wait till next call. - virtual double OnTicks(double tickSeconds) - { - OVR_UNUSED1(tickSeconds); - return 1000.0; - } - }; - - // Add I/O notifier - bool AddSelectFd(Notifier* notify, int fd); - bool RemoveSelectFd(Notifier* notify, int fd); - - // Add notifier that will be called at regular intervals. - bool AddTicksNotifier(Notifier* notify); - bool RemoveTicksNotifier(Notifier* notify); - -private: - - bool threadInitialized() { return CommandFd[0] != 0; } - - // pipe used to signal commands - int CommandFd[2]; - - Array PollFds; - Array FdNotifiers; - - Event StartupEvent; - - // Ticks notifiers - used for time-dependent events such as keep-alive. - Array TicksNotifiers; -}; - -}} // namespace Linux::OVR - -#endif // OVR_Linux_DeviceManager_h diff --git a/LibOVR/Src/OVR_Linux_HIDDevice.cpp b/LibOVR/Src/OVR_Linux_HIDDevice.cpp deleted file mode 100644 index 133e5c3..0000000 --- a/LibOVR/Src/OVR_Linux_HIDDevice.cpp +++ /dev/null @@ -1,819 +0,0 @@ -/************************************************************************************ -Filename : OVR_Linux_HIDDevice.cpp -Content : Linux HID device implementation. -Created : February 26, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HIDDevice.h" - -#include -#include -#include -#include -#include "OVR_HIDDeviceImpl.h" - -namespace OVR { namespace Linux { - -static const UInt32 MAX_QUEUED_INPUT_REPORTS = 5; - -//------------------------------------------------------------------------------------- -// **** Linux::DeviceManager -//----------------------------------------------------------------------------- -HIDDeviceManager::HIDDeviceManager(DeviceManager* manager) : DevManager(manager) -{ - UdevInstance = NULL; - HIDMonitor = NULL; - HIDMonHandle = -1; -} - -//----------------------------------------------------------------------------- -HIDDeviceManager::~HIDDeviceManager() -{ -} - -//----------------------------------------------------------------------------- -bool HIDDeviceManager::initializeManager() -{ - if (HIDMonitor) - { - return true; - } - - // Create a udev_monitor handle to watch for device changes (hot-plug detection) - HIDMonitor = udev_monitor_new_from_netlink(UdevInstance, "udev"); - if (HIDMonitor == NULL) - { - return false; - } - - udev_monitor_filter_add_match_subsystem_devtype(HIDMonitor, "hidraw", NULL); // filter for hidraw only - - int err = udev_monitor_enable_receiving(HIDMonitor); - if (err) - { - udev_monitor_unref(HIDMonitor); - HIDMonitor = NULL; - return false; - } - - // Get the file descriptor (fd) for the monitor. - HIDMonHandle = udev_monitor_get_fd(HIDMonitor); - if (HIDMonHandle < 0) - { - udev_monitor_unref(HIDMonitor); - HIDMonitor = NULL; - return false; - } - - // This file handle will be polled along-side with the device hid handles for changes - // Add the handle to the polling list - if (!DevManager->pThread->AddSelectFd(this, HIDMonHandle)) - { - close(HIDMonHandle); - HIDMonHandle = -1; - - udev_monitor_unref(HIDMonitor); - HIDMonitor = NULL; - return false; - } - - return true; -} - -//----------------------------------------------------------------------------- -bool HIDDeviceManager::Initialize() -{ - // Get a udev library handle. This handle must stay active during the - // duration the lifetime of device monitoring handles - UdevInstance = udev_new(); - if (!UdevInstance) - return false; - - return initializeManager(); -} - -//----------------------------------------------------------------------------- -void HIDDeviceManager::Shutdown() -{ - OVR_ASSERT_LOG((UdevInstance), ("Should have called 'Initialize' before 'Shutdown'.")); - - if (HIDMonitor) - { - DevManager->pThread->RemoveSelectFd(this, HIDMonHandle); - close(HIDMonHandle); - HIDMonHandle = -1; - - udev_monitor_unref(HIDMonitor); - HIDMonitor = NULL; - } - - udev_unref(UdevInstance); // release the library - - LogText("OVR::Linux::HIDDeviceManager - shutting down.\n"); -} - -//------------------------------------------------------------------------------- -bool HIDDeviceManager::AddNotificationDevice(HIDDevice* device) -{ - NotificationDevices.PushBack(device); - return true; -} - -//------------------------------------------------------------------------------- -bool HIDDeviceManager::RemoveNotificationDevice(HIDDevice* device) -{ - for (UPInt i = 0; i < NotificationDevices.GetSize(); i++) - { - if (NotificationDevices[i] == device) - { - NotificationDevices.RemoveAt(i); - return true; - } - } - return false; -} - -//----------------------------------------------------------------------------- -bool HIDDeviceManager::getIntProperty(udev_device* device, - const char* propertyName, - SInt32* pResult) -{ - const char* str = udev_device_get_sysattr_value(device, propertyName); - if (str) - { - *pResult = strtol(str, NULL, 16); - return true; - } - else - { - *pResult = 0; - return true; - } -} - -//----------------------------------------------------------------------------- -bool HIDDeviceManager::initVendorProductVersion(udev_device* device, HIDDeviceDesc* pDevDesc) -{ - SInt32 result; - if (getIntProperty(device, "idVendor", &result)) - pDevDesc->VendorId = result; - else - return false; - - if (getIntProperty(device, "idProduct", &result)) - pDevDesc->ProductId = result; - else - return false; - - if (getIntProperty(device, "bcdDevice", &result)) - pDevDesc->VersionNumber = result; - else - return false; - - return true; -} - -//----------------------------------------------------------------------------- -bool HIDDeviceManager::getStringProperty(udev_device* device, - const char* propertyName, - OVR::String* pResult) -{ - // Get the attribute in UTF8 - const char* str = udev_device_get_sysattr_value(device, propertyName); - if (str) - { // Copy the string into the return value - *pResult = String(str); - return true; - } - else - { - return false; - } -} - -//----------------------------------------------------------------------------- -bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) -{ - - if (!initializeManager()) - { - return false; - } - - // Get a list of hid devices - udev_enumerate* devices = udev_enumerate_new(UdevInstance); - udev_enumerate_add_match_subsystem(devices, "hidraw"); - udev_enumerate_scan_devices(devices); - - udev_list_entry* entry = udev_enumerate_get_list_entry(devices); - - // Search each device for the matching vid/pid - while (entry != NULL) - { - // Get the device file name - const char* sysfs_path = udev_list_entry_get_name(entry); - udev_device* hid; // The device's HID udev node. - hid = udev_device_new_from_syspath(UdevInstance, sysfs_path); - const char* dev_path = udev_device_get_devnode(hid); - - // Get the USB device - hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device"); - if (hid) - { - HIDDeviceDesc devDesc; - - // Check the VID/PID for a match - if (dev_path && - initVendorProductVersion(hid, &devDesc) && - enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId)) - { - devDesc.Path = dev_path; - getFullDesc(hid, &devDesc); - - // Look for the device to check if it is already opened. - Ptr existingDevice = DevManager->FindHIDDevice(devDesc, true); - // if device exists and it is opened then most likely the device open() - // will fail; therefore, we just set Enumerated to 'true' and continue. - if (existingDevice && existingDevice->pDevice) - { - existingDevice->Enumerated = true; - } - else - { // open the device temporarily for startup communication - int device_handle = open(dev_path, O_RDWR); - if (device_handle >= 0) - { - // Construct minimal device that the visitor callback can get feature reports from - Linux::HIDDevice device(this, device_handle); - enumVisitor->Visit(device, devDesc); - - close(device_handle); // close the file handle - } - } - } - - udev_device_unref(hid); - entry = udev_list_entry_get_next(entry); - } - } - - // Free the enumerator and udev objects - udev_enumerate_unref(devices); - - return true; -} - -//----------------------------------------------------------------------------- -OVR::HIDDevice* HIDDeviceManager::Open(const String& path) -{ - Ptr device = *new Linux::HIDDevice(this); - - if (device->HIDInitialize(path)) - { - device->AddRef(); - return device; - } - - return NULL; -} - -//----------------------------------------------------------------------------- -bool HIDDeviceManager::getFullDesc(udev_device* device, HIDDeviceDesc* desc) -{ - - if (!initVendorProductVersion(device, desc)) - { - return false; - } - - if (!getStringProperty(device, "serial", &(desc->SerialNumber))) - { - return false; - } - - getStringProperty(device, "manufacturer", &(desc->Manufacturer)); - getStringProperty(device, "product", &(desc->Product)); - - return true; -} - -//----------------------------------------------------------------------------- -bool HIDDeviceManager::GetDescriptorFromPath(const char* dev_path, HIDDeviceDesc* desc) -{ - if (!initializeManager()) - { - return false; - } - - // Search for the udev device from the given pathname so we can - // have a handle to query device properties - - udev_enumerate* devices = udev_enumerate_new(UdevInstance); - udev_enumerate_add_match_subsystem(devices, "hidraw"); - udev_enumerate_scan_devices(devices); - - udev_list_entry* entry = udev_enumerate_get_list_entry(devices); - - bool success = false; - // Search for the device with the matching path - while (entry != NULL) - { - // Get the device file name - const char* sysfs_path = udev_list_entry_get_name(entry); - udev_device* hid; // The device's HID udev node. - hid = udev_device_new_from_syspath(UdevInstance, sysfs_path); - const char* path = udev_device_get_devnode(hid); - - if (OVR_strcmp(dev_path, path) == 0) - { // Found the device so lets collect the device descriptor - - // Get the USB device - hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device"); - if (hid) - { - desc->Path = dev_path; - success = getFullDesc(hid, desc); - } - - } - - udev_device_unref(hid); - entry = udev_list_entry_get_next(entry); - } - - // Free the enumerator - udev_enumerate_unref(devices); - - return success; -} - -//----------------------------------------------------------------------------- -void HIDDeviceManager::OnEvent(int i, int fd) -{ - OVR_UNUSED(i); - OVR_UNUSED(fd); - - // There is a device status change - udev_device* hid = udev_monitor_receive_device(HIDMonitor); - if (hid) - { - const char* dev_path = udev_device_get_devnode(hid); - const char* action = udev_device_get_action(hid); - - HIDDeviceDesc device_info; - device_info.Path = dev_path; - - MessageType notify_type; - if (OVR_strcmp(action, "add") == 0) - { - notify_type = Message_DeviceAdded; - - // Retrieve the device info. This can only be done on a connected - // device and is invalid for a disconnected device - - // Get the USB device - hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device"); - if (!hid) - { - return; - } - - getFullDesc(hid, &device_info); - } - else if (OVR_strcmp(action, "remove") == 0) - { - notify_type = Message_DeviceRemoved; - } - else - { - return; - } - - bool error = false; - bool deviceFound = false; - for (UPInt i = 0; i < NotificationDevices.GetSize(); i++) - { - if (NotificationDevices[i] && - NotificationDevices[i]->OnDeviceNotification(notify_type, &device_info, &error)) - { - // The notification was for an existing device - deviceFound = true; - break; - } - } - - if (notify_type == Message_DeviceAdded && !deviceFound) - { - DevManager->DetectHIDDevice(device_info); - } - - udev_device_unref(hid); - } -} - -//============================================================================= -// Linux::HIDDevice -//============================================================================= -HIDDevice::HIDDevice(HIDDeviceManager* manager) - : InMinimalMode(false), HIDManager(manager) -{ - DeviceHandle = -1; -} - -//----------------------------------------------------------------------------- -// This is a minimal constructor used during enumeration for us to pass -// a HIDDevice to the visit function (so that it can query feature reports). -HIDDevice::HIDDevice(HIDDeviceManager* manager, int device_handle) -: InMinimalMode(true), HIDManager(manager), DeviceHandle(device_handle) -{ -} - -//----------------------------------------------------------------------------- -HIDDevice::~HIDDevice() -{ - if (!InMinimalMode) - { - HIDShutdown(); - } -} - -//----------------------------------------------------------------------------- -bool HIDDevice::HIDInitialize(const String& path) -{ - const char* hid_path = path.ToCStr(); - if (!openDevice(hid_path)) - { - LogText("OVR::Linux::HIDDevice - Failed to open HIDDevice: %s", hid_path); - return false; - } - - HIDManager->DevManager->pThread->AddTicksNotifier(this); - HIDManager->AddNotificationDevice(this); - - LogText("OVR::Linux::HIDDevice - Opened '%s'\n" - " Manufacturer:'%s' Product:'%s' Serial#:'%s'\n", - DevDesc.Path.ToCStr(), - DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(), - DevDesc.SerialNumber.ToCStr()); - - return true; -} - -//----------------------------------------------------------------------------- -bool HIDDevice::initInfo() -{ - // Device must have been successfully opened. - OVR_ASSERT(DeviceHandle >= 0); - - int desc_size = 0; - hidraw_report_descriptor rpt_desc; - memset(&rpt_desc, 0, sizeof(rpt_desc)); - - // get report descriptor size - int r = ioctl(DeviceHandle, HIDIOCGRDESCSIZE, &desc_size); - if (r < 0) - { - OVR_ASSERT_LOG(false, ("Failed to get report descriptor size.")); - return false; - } - - // Get the report descriptor - rpt_desc.size = desc_size; - r = ioctl(DeviceHandle, HIDIOCGRDESC, &rpt_desc); - if (r < 0) - { - OVR_ASSERT_LOG(false, ("Failed to get report descriptor.")); - return false; - } - - /* - // Get report lengths. - SInt32 bufferLength; - bool getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxInputReportSizeKey), &bufferLength); - OVR_ASSERT(getResult); - InputReportBufferLength = (UInt16) bufferLength; - - getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxOutputReportSizeKey), &bufferLength); - OVR_ASSERT(getResult); - OutputReportBufferLength = (UInt16) bufferLength; - - getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxFeatureReportSizeKey), &bufferLength); - OVR_ASSERT(getResult); - FeatureReportBufferLength = (UInt16) bufferLength; - - - if (ReadBufferSize < InputReportBufferLength) - { - OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer.")); - return false; - } - - // Get device desc. - if (!HIDManager->getFullDesc(Device, &DevDesc)) - { - OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device.")); - return false; - } - - return true; - */ - - // Get report lengths. -// TODO: hard-coded for now. Need to interpret these values from the report descriptor - InputReportBufferLength = 62; - OutputReportBufferLength = 0; - FeatureReportBufferLength = 69; - - if (ReadBufferSize < InputReportBufferLength) - { - OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer.")); - return false; - } - - return true; -} - -//----------------------------------------------------------------------------- -bool HIDDevice::openDevice(const char* device_path) -{ - // First fill out the device descriptor - if (!HIDManager->GetDescriptorFromPath(device_path, &DevDesc)) - { - return false; - } - - // Now open the device - DeviceHandle = open(device_path, O_RDWR); - if (DeviceHandle < 0) - { - OVR_DEBUG_LOG(("Failed 'CreateHIDFile' while opening device, error = 0x%X.", errno)); - DeviceHandle = -1; - return false; - } - - // fill out some values from the feature report descriptor - if (!initInfo()) - { - OVR_ASSERT_LOG(false, ("Failed to get HIDDevice info.")); - - close(DeviceHandle); - DeviceHandle = -1; - return false; - } - - // Add the device to the polling list - if (!HIDManager->DevManager->pThread->AddSelectFd(this, DeviceHandle)) - { - OVR_ASSERT_LOG(false, ("Failed to initialize polling for HIDDevice.")); - - close(DeviceHandle); - DeviceHandle = -1; - return false; - } - - return true; -} - -//----------------------------------------------------------------------------- -void HIDDevice::HIDShutdown() -{ - - HIDManager->DevManager->pThread->RemoveTicksNotifier(this); - HIDManager->RemoveNotificationDevice(this); - - if (DeviceHandle >= 0) // Device may already have been closed if unplugged. - { - closeDevice(false); - } - - LogText("OVR::Linux::HIDDevice - HIDShutdown '%s'\n", DevDesc.Path.ToCStr()); -} - -//----------------------------------------------------------------------------- -void HIDDevice::closeDevice(bool wasUnplugged) -{ - OVR_UNUSED(wasUnplugged); - OVR_ASSERT(DeviceHandle >= 0); - - - HIDManager->DevManager->pThread->RemoveSelectFd(this, DeviceHandle); - - close(DeviceHandle); // close the file handle - DeviceHandle = -1; - - LogText("OVR::Linux::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr()); -} - -//----------------------------------------------------------------------------- -void HIDDevice::closeDeviceOnIOError() -{ - LogText("OVR::Linux::HIDDevice - Lost connection to '%s'\n", DevDesc.Path.ToCStr()); - closeDevice(false); -} - -//----------------------------------------------------------------------------- -bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length) -{ - - if (DeviceHandle < 0) - return false; - - UByte reportID = data[0]; - - if (reportID == 0) - { - // Not using reports so remove from data packet. - data++; - length--; - } - - int r = ioctl(DeviceHandle, HIDIOCSFEATURE(length), data); - return (r >= 0); -} - -//----------------------------------------------------------------------------- -bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length) -{ - if (DeviceHandle < 0) - return false; - - int r = ioctl(DeviceHandle, HIDIOCGFEATURE(length), data); - return (r >= 0); -} - -//----------------------------------------------------------------------------- -double HIDDevice::OnTicks(double tickSeconds) -{ - if (Handler) - { - return Handler->OnTicks(tickSeconds); - } - - return DeviceManagerThread::Notifier::OnTicks(tickSeconds); -} - -//----------------------------------------------------------------------------- -void HIDDevice::OnEvent(int i, int fd) -{ - OVR_UNUSED(i); - // We have data to read from the device - int bytes = read(fd, ReadBuffer, ReadBufferSize); - if (bytes >= 0) - { -// TODO: I need to handle partial messages and package reconstruction - if (Handler) - { - Handler->OnInputReport(ReadBuffer, bytes); - } - } - else - { // Close the device on read error. - closeDeviceOnIOError(); - } -} - -//----------------------------------------------------------------------------- -bool HIDDevice::OnDeviceNotification(MessageType messageType, - HIDDeviceDesc* device_info, - bool* error) -{ - const char* device_path = device_info->Path.ToCStr(); - - if (messageType == Message_DeviceAdded && DeviceHandle < 0) - { - // Is this the correct device? - if (!(device_info->VendorId == DevDesc.VendorId - && device_info->ProductId == DevDesc.ProductId - && device_info->SerialNumber == DevDesc.SerialNumber)) - { - return false; - } - - // A closed device has been re-added. Try to reopen. - if (!openDevice(device_path)) - { - LogError("OVR::Linux::HIDDevice - Failed to reopen a device '%s' that was re-added.\n", - device_path); - *error = true; - return true; - } - - LogText("OVR::Linux::HIDDevice - Reopened device '%s'\n", device_path); - - if (Handler) - { - Handler->OnDeviceMessage(HIDHandler::HIDDeviceMessage_DeviceAdded); - } - } - else if (messageType == Message_DeviceRemoved) - { - // Is this the correct device? - // For disconnected device, the device description will be invalid so - // checking the path is the only way to match them - if (DevDesc.Path.CompareNoCase(device_path) != 0) - { - return false; - } - - if (DeviceHandle >= 0) - { - closeDevice(true); - } - - if (Handler) - { - Handler->OnDeviceMessage(HIDHandler::HIDDeviceMessage_DeviceRemoved); - } - } - else - { - OVR_ASSERT(0); - } - - *error = false; - return true; -} - -//----------------------------------------------------------------------------- -HIDDeviceManager* HIDDeviceManager::CreateInternal(Linux::DeviceManager* devManager) -{ - - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr manager = *new Linux::HIDDeviceManager(devManager); - - if (manager) - { - if (manager->Initialize()) - { - manager->AddRef(); - } - else - { - manager.Clear(); - } - } - - return manager.GetPtr(); -} - -} // namespace Linux - -//------------------------------------------------------------------------------------- -// ***** Creation - -// Creates a new HIDDeviceManager and initializes OVR. -HIDDeviceManager* HIDDeviceManager::Create(Ptr& deviceManager) -{ - - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr deviceManagerLinux = *new Linux::DeviceManager; - - if (!deviceManagerLinux) - { - return NULL; - } - - if (!deviceManagerLinux->Initialize(NULL)) - { - return NULL; - } - - deviceManager = deviceManagerLinux; - - return deviceManagerLinux->GetHIDDeviceManager(); -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_Linux_HIDDevice.h b/LibOVR/Src/OVR_Linux_HIDDevice.h deleted file mode 100644 index 52f2d69..0000000 --- a/LibOVR/Src/OVR_Linux_HIDDevice.h +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************************************************ -Filename : OVR_Linux_HIDDevice.h -Content : Linux HID device implementation. -Created : June 13, 2013 -Authors : Brant Lewis - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HIDDevice_h -#define OVR_LINUX_HIDDevice_h - -#include "OVR_HIDDevice.h" -#include "OVR_Linux_DeviceManager.h" -#include - -namespace OVR { namespace Linux { - -class HIDDeviceManager; - -//------------------------------------------------------------------------------------- -// ***** Linux HIDDevice - -class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier -{ -private: - friend class HIDDeviceManager; - -public: - HIDDevice(HIDDeviceManager* manager); - - // This is a minimal constructor used during enumeration for us to pass - // a HIDDevice to the visit function (so that it can query feature reports). - HIDDevice(HIDDeviceManager* manager, int device_handle); - - virtual ~HIDDevice(); - - bool HIDInitialize(const String& path); - void HIDShutdown(); - - virtual bool SetFeatureReport(UByte* data, UInt32 length); - virtual bool GetFeatureReport(UByte* data, UInt32 length); - - // DeviceManagerThread::Notifier - void OnEvent(int i, int fd); - double OnTicks(double tickSeconds); - - bool OnDeviceNotification(MessageType messageType, - HIDDeviceDesc* device_info, - bool* error); - -private: - bool initInfo(); - bool openDevice(const char* dev_path); - void closeDevice(bool wasUnplugged); - void closeDeviceOnIOError(); - bool setupDevicePluggedInNotification(); - - bool InMinimalMode; - HIDDeviceManager* HIDManager; - int DeviceHandle; // file handle to the device - HIDDeviceDesc DevDesc; - - enum { ReadBufferSize = 96 }; - UByte ReadBuffer[ReadBufferSize]; - - UInt16 InputReportBufferLength; - UInt16 OutputReportBufferLength; - UInt16 FeatureReportBufferLength; -}; - - -//------------------------------------------------------------------------------------- -// ***** Linux HIDDeviceManager - -class HIDDeviceManager : public OVR::HIDDeviceManager, public DeviceManagerThread::Notifier -{ - friend class HIDDevice; - -public: - HIDDeviceManager(Linux::DeviceManager* Manager); - virtual ~HIDDeviceManager(); - - virtual bool Initialize(); - virtual void Shutdown(); - - virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor); - virtual OVR::HIDDevice* Open(const String& path); - - static HIDDeviceManager* CreateInternal(DeviceManager* manager); - - void OnEvent(int i, int fd); - -private: - bool initializeManager(); - bool initVendorProductVersion(udev_device* device, HIDDeviceDesc* pDevDesc); - bool getPath(udev_device* device, String* pPath); - bool getIntProperty(udev_device* device, const char* key, int32_t* pResult); - bool getStringProperty(udev_device* device, - const char* propertyName, - OVR::String* pResult); - bool getFullDesc(udev_device* device, HIDDeviceDesc* desc); - bool GetDescriptorFromPath(const char* dev_path, HIDDeviceDesc* desc); - - bool AddNotificationDevice(HIDDevice* device); - bool RemoveNotificationDevice(HIDDevice* device); - - DeviceManager* DevManager; - - udev* UdevInstance; // a handle to the udev library instance - udev_monitor* HIDMonitor; - int HIDMonHandle; // the udev_monitor file handle - - Array NotificationDevices; -}; - -}} // namespace OVR::Linux - -#endif // OVR_Linux_HIDDevice_h diff --git a/LibOVR/Src/OVR_Linux_HMDDevice.cpp b/LibOVR/Src/OVR_Linux_HMDDevice.cpp deleted file mode 100644 index 98143d3..0000000 --- a/LibOVR/Src/OVR_Linux_HMDDevice.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Linux_HMDDevice.h -Content : Linux HMDDevice implementation -Created : June 17, 2013 -Authors : Brant Lewis - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HMDDevice.h" - -#include "OVR_Linux_DeviceManager.h" - -#include "OVR_Profile.h" - -#include "../../3rdParty/EDID/edid.h" - -namespace OVR { namespace Linux { - -//------------------------------------------------------------------------------------- - -HMDDeviceCreateDesc::HMDDeviceCreateDesc(DeviceFactory* factory, const String& displayDeviceName, long dispId) - : DeviceCreateDesc(factory, Device_HMD), - DisplayDeviceName(displayDeviceName), - Contents(0), - DisplayId(dispId) -{ - DeviceId = DisplayDeviceName; - - Desktop.X = 0; - Desktop.Y = 0; - ResolutionInPixels = Sizei(0); - ScreenSizeInMeters = Sizef(0.0f); - VCenterFromTopInMeters = 0.0f; - LensSeparationInMeters = 0.0f; -} - -HMDDeviceCreateDesc::HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other) - : DeviceCreateDesc(other.pFactory, Device_HMD), - DeviceId(other.DeviceId), DisplayDeviceName(other.DisplayDeviceName), - Contents(other.Contents), - DisplayId(other.DisplayId) -{ - Desktop.X = other.Desktop.X; - Desktop.Y = other.Desktop.Y; - ResolutionInPixels = other.ResolutionInPixels; - ScreenSizeInMeters = other.ScreenSizeInMeters; - VCenterFromTopInMeters = other.VCenterFromTopInMeters; - LensSeparationInMeters = other.LensSeparationInMeters; -} - -HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc** pcandidate) const -{ - if ((other.Type != Device_HMD) || (other.pFactory != pFactory)) - return Match_None; - - // There are several reasons we can come in here: - // a) Matching this HMD Monitor created desc to OTHER HMD Monitor desc - // - Require exact device DeviceId/DeviceName match - // b) Matching SensorDisplayInfo created desc to OTHER HMD Monitor desc - // - This DeviceId is empty; becomes candidate - // c) Matching this HMD Monitor created desc to SensorDisplayInfo desc - // - This other.DeviceId is empty; becomes candidate - - const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other; - - if ((DeviceId == s2.DeviceId) && - (DisplayId == s2.DisplayId)) - { - // Non-null DeviceId may match while size is different if screen size was overwritten - // by SensorDisplayInfo in prior iteration. - if (!DeviceId.IsEmpty() || - (ScreenSizeInMeters == s2.ScreenSizeInMeters) ) - { - *pcandidate = 0; - return Match_Found; - } - } - - - // DisplayInfo takes precedence, although we try to match it first. - if ((ResolutionInPixels == s2.ResolutionInPixels) && - (ScreenSizeInMeters == s2.ScreenSizeInMeters)) - { - if (DeviceId.IsEmpty() && !s2.DeviceId.IsEmpty()) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - - *pcandidate = 0; - return Match_Found; - } - - // SensorDisplayInfo may override resolution settings, so store as candidate. - if (s2.DeviceId.IsEmpty()) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - // OTHER HMD Monitor desc may initialize DeviceName/Id - else if (DeviceId.IsEmpty()) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - - return Match_None; -} - - -bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other, - bool* newDeviceFlag) -{ - // This candidate was the the "best fit" to apply sensor DisplayInfo to. - OVR_ASSERT(other.Type == Device_HMD); - - const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other; - - // Force screen size on resolution from SensorDisplayInfo. - // We do this because USB detection is more reliable as compared to HDMI EDID, - // which may be corrupted by splitter reporting wrong monitor - if (s2.DeviceId.IsEmpty()) - { - ScreenSizeInMeters = s2.ScreenSizeInMeters; - Contents |= Contents_Screen; - - if (s2.Contents & HMDDeviceCreateDesc::Contents_Distortion) - { - memcpy(DistortionK, s2.DistortionK, sizeof(float)*4); - // TODO: DistortionEqn - Contents |= Contents_Distortion; - } - DeviceId = s2.DeviceId; - DisplayId = s2.DisplayId; - DisplayDeviceName = s2.DisplayDeviceName; - Desktop.X = s2.Desktop.X; - Desktop.Y = s2.Desktop.Y; - if (newDeviceFlag) *newDeviceFlag = true; - } - else if (DeviceId.IsEmpty()) - { - // This branch is executed when 'fake' HMD descriptor is being replaced by - // the real one. - DeviceId = s2.DeviceId; - DisplayId = s2.DisplayId; - DisplayDeviceName = s2.DisplayDeviceName; - Desktop.X = s2.Desktop.X; - Desktop.Y = s2.Desktop.Y; - - // ScreenSize and Resolution are NOT assigned here, since they may have - // come from a sensor DisplayInfo (which has precedence over HDMI). - - if (newDeviceFlag) *newDeviceFlag = true; - } - else - { - if (newDeviceFlag) *newDeviceFlag = false; - } - - return true; -} - -bool HMDDeviceCreateDesc::MatchDevice(const String& path) -{ - return DeviceId.CompareNoCase(path) == 0; -} - -//------------------------------------------------------------------------------------- -// ***** HMDDeviceFactory - -HMDDeviceFactory &HMDDeviceFactory::GetInstance() -{ - static HMDDeviceFactory instance; - return instance; -} - -void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) -{ - // For now we'll assume the Rift DK1 is attached in extended monitor mode. Ultimately we need to - // use XFree86 to enumerate X11 screens in case the Rift is attached as a separate screen. - - bool foundHMD = false; - Display* display = XOpenDisplay(NULL); - XRRScreenResources *screen = XRRGetScreenResources(display, DefaultRootWindow(display)); - for (int iscres = screen->noutput - 1; iscres >= 0; --iscres) { - RROutput output = screen->outputs[iscres]; - MonitorInfo * mi = read_edid_data(display, output); - if (mi == NULL) { - continue; - } - - XRROutputInfo * info = XRRGetOutputInfo (display, screen, output); - if (info && (0 == memcmp(mi->manufacturer_code, "OVR", 3))) { - - // Generate a device ID string similar to the way Windows does it - char device_id[32]; - OVR_sprintf(device_id, 32, "%s%04d", mi->manufacturer_code, mi->product_code); - - // The default monitor coordinates - int mx = 0; - int my = 0; - int mwidth = 1280; - int mheight = 800; - - if (info->connection == RR_Connected && info->crtc) { - XRRCrtcInfo * crtc_info = XRRGetCrtcInfo (display, screen, info->crtc); - if (crtc_info) - { - mx = crtc_info->x; - my = crtc_info->y; - //mwidth = crtc_info->width; - //mheight = crtc_info->height; - XRRFreeCrtcInfo(crtc_info); - } - } - - String deviceID = device_id; - HMDDeviceCreateDesc hmdCreateDesc(this, deviceID, iscres); - - // Hard-coded defaults in case the device doesn't have the data itself. - if (strstr(device_id, "OVR0003")) - { // DK2 prototypes and variants (default to HmdType_DK2) - hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12576f, 0.07074f, 0.12576f*0.5f, 0.0635f ); - } - else if (strstr(device_id, "OVR0002")) - { // HD Prototypes (default to HmdType_DKHDProto) - hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12096f, 0.06804f, 0.06804f*0.5f, 0.0635f ); - } - else if (strstr(device_id, "OVR0001")) - { // DK1 - hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f, 0.0936f*0.5f, 0.0635f); - } - else if (strstr(device_id, "OVR00")) - { // Future Oculus HMD devices (default to DK1 dimensions) - hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f, 0.0936f*0.5f, 0.0635f); - } - else - { // Duct-tape prototype - hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.12096f, 0.0756f, 0.0756f*0.5f, 0.0635f); - } - - OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %s\n", device_id, mi->dsc_product_name)); - - // Notify caller about detected device. This will call EnumerateAddDevice - // if the this is the first time device was detected. - visitor.Visit(hmdCreateDesc); - foundHMD = true; - break; - } // if - - XRRFreeOutputInfo(info); - delete mi; - } // for - XRRFreeScreenResources(screen); - - - // Real HMD device is not found; however, we still may have a 'fake' HMD - // device created via SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo. - // Need to find it and set 'Enumerated' to true to avoid Removal notification. - if (!foundHMD) - { - Ptr hmdDevDesc = getManager()->FindDevice("", Device_HMD); - if (hmdDevDesc) - hmdDevDesc->Enumerated = true; - } -} - -#include "OVR_Common_HMDDevice.cpp" - -}} // namespace OVR::Linux - - diff --git a/LibOVR/Src/OVR_Linux_HMDDevice.h b/LibOVR/Src/OVR_Linux_HMDDevice.h deleted file mode 100644 index a8c044f..0000000 --- a/LibOVR/Src/OVR_Linux_HMDDevice.h +++ /dev/null @@ -1,154 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Linux_HMDDevice.h -Content : Linux HMDDevice implementation -Created : June 17, 2013 -Authors : Brant Lewis - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HMDDevice_h -#define OVR_Linux_HMDDevice_h - -#include "OVR_Linux_DeviceManager.h" -#include "OVR_Profile.h" - -namespace OVR { namespace Linux { - -class HMDDevice; - -//------------------------------------------------------------------------------------- - -// HMDDeviceFactory enumerates attached Oculus HMD devices. -// -// This is currently done by matching monitor device strings. - -class HMDDeviceFactory : public DeviceFactory -{ -public: - static HMDDeviceFactory &GetInstance(); - - // Enumerates devices, creating and destroying relevant objects in manager. - virtual void EnumerateDevices(EnumerateVisitor& visitor); - -protected: - DeviceManager* getManager() const { return (DeviceManager*) pManager; } -}; - - -class HMDDeviceCreateDesc : public DeviceCreateDesc -{ - friend class HMDDevice; - -protected: - enum - { - Contents_Screen = 1, - Contents_Distortion = 2, - }; - String DeviceId; - String DisplayDeviceName; - struct - { - int X, Y; - } Desktop; - unsigned int Contents; - - Sizei ResolutionInPixels; - Sizef ScreenSizeInMeters; - float VCenterFromTopInMeters; - float LensSeparationInMeters; - - // TODO: update these to splines. - DistortionEqnType DistortionEqn; - float DistortionK[4]; - - long DisplayId; - -public: - HMDDeviceCreateDesc(DeviceFactory* factory, - const String& displayDeviceName, long dispId); - HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other); - - virtual DeviceCreateDesc* Clone() const - { - return new HMDDeviceCreateDesc(*this); - } - - virtual DeviceBase* NewDeviceInstance(); - - virtual MatchResult MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc**) const; - - // Matches device by path. - virtual bool MatchDevice(const String& path); - - virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL); - - virtual bool GetDeviceInfo(DeviceInfo* info) const; - - void SetScreenParameters(int x, int y, - int hres, int vres, - float hsize, float vsize, - float vCenterFromTopInMeters, float lensSeparationInMeters); - void SetDistortion(const float* dks); - - HmdTypeEnum GetHmdType() const; -}; - - -//------------------------------------------------------------------------------------- - -// HMDDevice represents an Oculus HMD device unit. An instance of this class -// is typically created from the DeviceManager. -// After HMD device is created, we its sensor data can be obtained by -// first creating a Sensor object and then wrappig it in SensorFusion. - -class HMDDevice : public DeviceImpl -{ -public: - HMDDevice(HMDDeviceCreateDesc* createDesc); - ~HMDDevice(); - - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - // Requests the currently used default profile. This profile affects the - // settings reported by HMDInfo. - virtual Profile* GetProfile(); - virtual const char* GetProfileName(); - virtual bool SetProfileName(const char* name); - - // Query associated sensor. - virtual OVR::SensorDevice* GetSensor(); - -protected: - HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); } - - // User name for the profile used with this device. - String ProfileName; - mutable Ptr pCachedProfile; -}; - - -}} // namespace OVR::Linux - -#endif // OVR_Linux_HMDDevice_h - diff --git a/LibOVR/Src/OVR_Linux_SensorDevice.cpp b/LibOVR/Src/OVR_Linux_SensorDevice.cpp deleted file mode 100644 index 5b671a6..0000000 --- a/LibOVR/Src/OVR_Linux_SensorDevice.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Linux_SensorDevice.cpp -Content : Linux SensorDevice implementation -Created : June 13, 2013 -Authors : Brant Lewis - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HMDDevice.h" -#include "OVR_SensorImpl.h" -#include "OVR_DeviceImpl.h" - -namespace OVR { namespace Linux { - -} // namespace Linux - -//------------------------------------------------------------------------------------- -void SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo( const SensorDisplayInfoImpl& displayInfo, - DeviceFactory::EnumerateVisitor& visitor) -{ - Linux::HMDDeviceCreateDesc hmdCreateDesc(&Linux::HMDDeviceFactory::GetInstance(), String(), 0); - - hmdCreateDesc.SetScreenParameters( 0, 0, - displayInfo.HResolution, displayInfo.VResolution, - displayInfo.HScreenSize, displayInfo.VScreenSize, - displayInfo.VCenter, displayInfo.LensSeparation); - - if ((displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) == SensorDisplayInfoImpl::Base_Distortion) - { - // TODO: update to spline system. - hmdCreateDesc.SetDistortion(displayInfo.DistortionK); - } - - visitor.Visit(hmdCreateDesc); -} - -} // namespace OVR - - diff --git a/LibOVR/Src/OVR_OSX_DeviceManager.cpp b/LibOVR/Src/OVR_OSX_DeviceManager.cpp deleted file mode 100644 index 078936a..0000000 --- a/LibOVR/Src/OVR_OSX_DeviceManager.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_DeviceManager.cpp -Content : OSX specific DeviceManager implementation. -Created : March 14, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_OSX_DeviceManager.h" - -// Sensor & HMD Factories -#include "OVR_LatencyTestImpl.h" -#include "OVR_SensorImpl.h" -#include "OVR_OSX_HMDDevice.h" -#include "OVR_OSX_HIDDevice.h" - -#include "Kernel/OVR_Timer.h" -#include "Kernel/OVR_Std.h" -#include "Kernel/OVR_Log.h" - -#include -#include - - -namespace OVR { namespace OSX { - -//------------------------------------------------------------------------------------- -// **** OSX::DeviceManager - -DeviceManager::DeviceManager() -{ -} - -DeviceManager::~DeviceManager() -{ - OVR_DEBUG_LOG(("OSX::DeviceManager::~DeviceManager was called")); -} - -bool DeviceManager::Initialize(DeviceBase*) -{ - if (!DeviceManagerImpl::Initialize(0)) - return false; - - // Start the background thread. - pThread = *new DeviceManagerThread(); - if (!pThread || !pThread->Start()) - return false; - - // Wait for the thread to be fully up and running. - pThread->StartupEvent.Wait(); - - // Do this now that we know the thread's run loop. - HidDeviceManager = *HIDDeviceManager::CreateInternal(this); - - CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallBack, this); - - pCreateDesc->pDevice = this; - LogText("OVR::DeviceManager - initialized.\n"); - - return true; -} - -void DeviceManager::Shutdown() -{ - LogText("OVR::DeviceManager - shutting down.\n"); - - CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallBack, this); - - // Set Manager shutdown marker variable; this prevents - // any existing DeviceHandle objects from accessing device. - pCreateDesc->pLock->pManager = 0; - - // Push for thread shutdown *WITH NO WAIT*. - // This will have the following effect: - // - Exit command will get enqueued, which will be executed later on the thread itself. - // - Beyond this point, this DeviceManager object may be deleted by our caller. - // - Other commands, such as CreateDevice, may execute before ExitCommand, but they will - // fail gracefully due to pLock->pManager == 0. Future commands can't be enqued - // after pManager is null. - // - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last - // reference to the thread object. - pThread->Shutdown(); - pThread.Clear(); - - DeviceManagerImpl::Shutdown(); -} - -ThreadCommandQueue* DeviceManager::GetThreadQueue() -{ - return pThread; -} - -ThreadId DeviceManager::GetThreadId() const -{ - return pThread->GetThreadId(); -} - -bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const -{ - if ((info->InfoClassType != Device_Manager) && - (info->InfoClassType != Device_None)) - return false; - - info->Type = Device_Manager; - info->Version = 0; - info->ProductName = "DeviceManager"; - info->Manufacturer = "Oculus VR, Inc."; - return true; -} - -DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args) -{ - // TBD: Can this be avoided in the future, once proper device notification is in place? - pThread->PushCall((DeviceManagerImpl*)this, - &DeviceManager::EnumerateAllFactoryDevices, true); - - return DeviceManagerImpl::EnumerateDevicesEx(args); -} - -void DeviceManager::displayReconfigurationCallBack (CGDirectDisplayID display, - CGDisplayChangeSummaryFlags flags, - void *userInfo) -{ - DeviceManager* manager = reinterpret_cast(userInfo); - OVR_UNUSED(manager); - - if (flags & kCGDisplayAddFlag) - { - LogText("Display Added, id = %d\n", int(display)); - manager->EnumerateDevices(); - } - else if (flags & kCGDisplayRemoveFlag) - { - LogText("Display Removed, id = %d\n", int(display)); - manager->EnumerateDevices(); - } -} - -//------------------------------------------------------------------------------------- -// ***** DeviceManager Thread - -DeviceManagerThread::DeviceManagerThread() - : Thread(ThreadStackSize) -{ -} - -DeviceManagerThread::~DeviceManagerThread() -{ -} - -int DeviceManagerThread::Run() -{ - - SetThreadName("OVR::DeviceManagerThread"); - LogText("OVR::DeviceManagerThread - running (ThreadId=0x%p).\n", GetThreadId()); - - // Store out the run loop ref. - RunLoop = CFRunLoopGetCurrent(); - - // Create a 'source' to enable us to signal the run loop to process the command queue. - CFRunLoopSourceContext sourceContext; - memset(&sourceContext, 0, sizeof(sourceContext)); - sourceContext.version = 0; - sourceContext.info = this; - sourceContext.perform = &staticCommandQueueSourceCallback; - - CommandQueueSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0 , &sourceContext); - - CFRunLoopAddSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode); - - - // Signal to the parent thread that initialization has finished. - StartupEvent.SetEvent(); - - - ThreadCommand::PopBuffer command; - - while(!IsExiting()) - { - // PopCommand will reset event on empty queue. - if (PopCommand(&command)) - { - command.Execute(); - } - else - { - SInt32 exitReason = 0; - do { - - UInt32 waitMs = INT_MAX; - - // If devices have time-dependent logic registered, get the longest wait - // allowed based on current ticks. - if (!TicksNotifiers.IsEmpty()) - { - double timeSeconds = Timer::GetSeconds(); - unsigned waitAllowed; - - for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++) - { - waitAllowed = (unsigned)(TicksNotifiers[j]->OnTicks(timeSeconds) * Timer::MsPerSecond); - if (waitAllowed < (unsigned)waitMs) - waitMs = waitAllowed; - } - } - - // Enter blocking run loop. We may continue until we timeout in which - // case it's time to service the ticks. Or if commands arrive in the command - // queue then the source callback will call 'CFRunLoopStop' causing this - // to return. - CFTimeInterval blockInterval = 0.001 * (double) waitMs; - exitReason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, blockInterval, false); - - if (exitReason == kCFRunLoopRunFinished) - { - // Maybe this will occur during shutdown? - break; - } - else if (exitReason == kCFRunLoopRunStopped ) - { - // Commands need processing or we're being shutdown. - break; - } - else if (exitReason == kCFRunLoopRunTimedOut) - { - // Timed out so that we can service our ticks callbacks. - continue; - } - else if (exitReason == kCFRunLoopRunHandledSource) - { - // Should never occur since the last param when we call - // 'CFRunLoopRunInMode' is false. - OVR_ASSERT(false); - break; - } - else - { - OVR_ASSERT_LOG(false, ("CFRunLoopRunInMode returned unexpected code")); - break; - } - } - while(true); - } - } - - - CFRunLoopRemoveSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode); - CFRelease(CommandQueueSource); - - LogText("OVR::DeviceManagerThread - exiting (ThreadId=0x%p).\n", GetThreadId()); - - return 0; -} - -void DeviceManagerThread::staticCommandQueueSourceCallback(void* pContext) -{ - DeviceManagerThread* pThread = (DeviceManagerThread*) pContext; - pThread->commandQueueSourceCallback(); -} - -void DeviceManagerThread::commandQueueSourceCallback() -{ - CFRunLoopStop(RunLoop); -} - -bool DeviceManagerThread::AddTicksNotifier(Notifier* notify) -{ - TicksNotifiers.PushBack(notify); - return true; -} - -bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify) -{ - for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++) - { - if (TicksNotifiers[i] == notify) - { - TicksNotifiers.RemoveAt(i); - return true; - } - } - return false; -} - -void DeviceManagerThread::Shutdown() -{ - // Push for thread shutdown *WITH NO WAIT*. - // This will have the following effect: - // - Exit command will get enqueued, which will be executed later on the thread itself. - // - Beyond this point, this DeviceManager object may be deleted by our caller. - // - Other commands, such as CreateDevice, may execute before ExitCommand, but they will - // fail gracefully due to pLock->pManager == 0. Future commands can't be enqued - // after pManager is null. - // - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last - // reference to the thread object. - PushExitCommand(false); - - // make sure CFRunLoopRunInMode is woken up - CFRunLoopSourceSignal(CommandQueueSource); - CFRunLoopWakeUp(RunLoop); -} - -} // namespace OSX - - -//------------------------------------------------------------------------------------- -// ***** Creation - -// Creates a new DeviceManager and initializes OVR. -DeviceManager* DeviceManager::Create() -{ - - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr manager = *new OSX::DeviceManager; - - if (manager) - { - if (manager->Initialize(0)) - { - manager->AddFactory(&LatencyTestDeviceFactory::GetInstance()); - manager->AddFactory(&SensorDeviceFactory::GetInstance()); - manager->AddFactory(&OSX::HMDDeviceFactory::GetInstance()); - - manager->AddRef(); - } - else - { - manager.Clear(); - } - } - - return manager.GetPtr(); -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_OSX_DeviceManager.h b/LibOVR/Src/OVR_OSX_DeviceManager.h deleted file mode 100644 index 61af848..0000000 --- a/LibOVR/Src/OVR_OSX_DeviceManager.h +++ /dev/null @@ -1,128 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_DeviceManager.h -Content : OSX specific DeviceManager header. -Created : March 14, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_OSX_DeviceManager_h -#define OVR_OSX_DeviceManager_h - -#include "OVR_DeviceImpl.h" - -#include "Kernel/OVR_Timer.h" - -#include -#include - -namespace OVR { namespace OSX { - -class DeviceManagerThread; - -//------------------------------------------------------------------------------------- -// ***** OSX DeviceManager - -class DeviceManager : public DeviceManagerImpl -{ -public: - DeviceManager(); - ~DeviceManager(); - - // Initialize/Shutdown manager thread. - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - virtual ThreadCommandQueue* GetThreadQueue(); - virtual ThreadId GetThreadId() const; - - virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args); - - virtual bool GetDeviceInfo(DeviceInfo* info) const; - -protected: - static void displayReconfigurationCallBack (CGDirectDisplayID display, - CGDisplayChangeSummaryFlags flags, - void *userInfo); - -public: // data - Ptr pThread; -}; - -//------------------------------------------------------------------------------------- -// ***** Device Manager Background Thread - -class DeviceManagerThread : public Thread, public ThreadCommandQueue -{ - friend class DeviceManager; - enum { ThreadStackSize = 32 * 1024 }; -public: - DeviceManagerThread(); - ~DeviceManagerThread(); - - virtual int Run(); - - // ThreadCommandQueue notifications for CommandEvent handling. - virtual void OnPushNonEmpty_Locked() - { - CFRunLoopSourceSignal(CommandQueueSource); - CFRunLoopWakeUp(RunLoop); - } - - virtual void OnPopEmpty_Locked() {} - - - // Notifier used for different updates (EVENT or regular timing or messages). - class Notifier - { - public: - - // Called when timing ticks are updated. // Returns the largest number of microseconds - // this function can wait till next call. - virtual double OnTicks(double tickSeconds) - { OVR_UNUSED1(tickSeconds); return 1000.0; } - }; - - // Add notifier that will be called at regular intervals. - bool AddTicksNotifier(Notifier* notify); - bool RemoveTicksNotifier(Notifier* notify); - - CFRunLoopRef GetRunLoop() - { return RunLoop; } - - void Shutdown(); -private: - CFRunLoopRef RunLoop; - - CFRunLoopSourceRef CommandQueueSource; - - static void staticCommandQueueSourceCallback(void* pContext); - void commandQueueSourceCallback(); - - Event StartupEvent; - - // Ticks notifiers. Used for time-dependent events such as keep-alive. - Array TicksNotifiers; -}; - -}} // namespace OSX::OVR - -#endif // OVR_OSX_DeviceManager_h diff --git a/LibOVR/Src/OVR_OSX_HIDDevice.cpp b/LibOVR/Src/OVR_OSX_HIDDevice.cpp deleted file mode 100644 index af840e0..0000000 --- a/LibOVR/Src/OVR_OSX_HIDDevice.cpp +++ /dev/null @@ -1,924 +0,0 @@ -/************************************************************************************ -Filename : OVR_OSX_HIDDevice.cpp -Content : OSX HID device implementation. -Created : February 26, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_OSX_HIDDevice.h" - -#include - -namespace OVR { namespace OSX { - - -//------------------------------------------------------------------------------------- -// **** OSX::DeviceManager - -HIDDeviceManager::HIDDeviceManager(DeviceManager* manager) - : DevManager(manager) -{ - HIDManager = NULL; -} - -HIDDeviceManager::~HIDDeviceManager() -{ -} - -CFRunLoopRef HIDDeviceManager::getRunLoop() -{ - if (DevManager != NULL) - { - return DevManager->pThread->GetRunLoop(); - } - - return CFRunLoopGetCurrent(); -} - -bool HIDDeviceManager::initializeManager() -{ - if (HIDManager != NULL) - { - return true; - } - - HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - - if (!HIDManager) - { - return false; - } - - // Create a Matching Dictionary - CFMutableDictionaryRef matchDict = - CFDictionaryCreateMutable(kCFAllocatorDefault, - 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - // Specify a device manufacturer in the Matching Dictionary - UInt32 vendorId = Oculus_VendorId; - CFNumberRef vendorIdRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendorId); - CFDictionarySetValue(matchDict, - CFSTR(kIOHIDVendorIDKey), - vendorIdRef); - // Register the Matching Dictionary to the HID Manager - IOHIDManagerSetDeviceMatching(HIDManager, matchDict); - CFRelease(vendorIdRef); - CFRelease(matchDict); - - // Register a callback for USB device detection with the HID Manager - IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, &staticDeviceMatchingCallback, this); - - IOHIDManagerScheduleWithRunLoop(HIDManager, getRunLoop(), kCFRunLoopDefaultMode); - - return true; -} - -bool HIDDeviceManager::Initialize() -{ - return initializeManager(); -} - -void HIDDeviceManager::Shutdown() -{ - OVR_ASSERT_LOG(HIDManager, ("Should have called 'Initialize' before 'Shutdown'.")); - CFRelease(HIDManager); - - LogText("OVR::OSX::HIDDeviceManager - shutting down.\n"); -} - -bool HIDDeviceManager::getIntProperty(IOHIDDeviceRef device, CFStringRef propertyName, SInt32* pResult) -{ - - CFTypeRef ref = IOHIDDeviceGetProperty(device, propertyName); - - if (!ref) - { - return false; - } - - if (CFGetTypeID(ref) != CFNumberGetTypeID()) - { - return false; - } - - CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, pResult); - - return true; -} - -bool HIDDeviceManager::initVendorProductVersion(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc) -{ - - if (!getVendorId(device, &(pDevDesc->VendorId))) - { - return false; - } - - if (!getProductId(device, &(pDevDesc->ProductId))) - { - return false; - } - - SInt32 result; - if (!getIntProperty(device, CFSTR(kIOHIDVersionNumberKey), &result)) - { - return false; - } - pDevDesc->VersionNumber = result; - - return true; -} - -bool HIDDeviceManager::initUsage(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc) -{ - - SInt32 result; - - if (!getIntProperty(device, CFSTR(kIOHIDPrimaryUsagePageKey), &result)) - { - return false; - } - - pDevDesc->UsagePage = result; - - - if (!getIntProperty(device, CFSTR(kIOHIDPrimaryUsageKey), &result)) - { - return false; - } - - pDevDesc->Usage = result; - - return true; -} - -bool HIDDeviceManager::initSerialNumber(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc) -{ - return getSerialNumberString(device, &(pDevDesc->SerialNumber)); -} - -bool HIDDeviceManager::initStrings(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc) -{ - - // Regardless of whether they fail we'll try and get the remaining. - getStringProperty(device, CFSTR(kIOHIDManufacturerKey), &(pDevDesc->Manufacturer)); - getStringProperty(device, CFSTR(kIOHIDProductKey), &(pDevDesc->Product)); - - return true; -} - -bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device, - CFStringRef propertyName, - String* pResult) -{ - - CFStringRef str = (CFStringRef) IOHIDDeviceGetProperty(device, propertyName); - - if (!str) - { - return false; - } - - CFIndex length = CFStringGetLength(str); - CFRange range = CFRangeMake(0, length); - - // Test the conversion first to get required buffer size. - CFIndex bufferLength; - CFIndex numberOfChars = CFStringGetBytes(str, - range, - kCFStringEncodingUTF8, - (char) '?', - FALSE, - NULL, - 0, - &bufferLength); - - if (numberOfChars == 0) - { - return false; - } - - // Now allocate buffer. - char* buffer = new char[bufferLength+1]; - - numberOfChars = CFStringGetBytes(str, - range, - kCFStringEncodingUTF8, - (char) '?', - FALSE, - (UInt8*) buffer, - bufferLength, - NULL); - OVR_ASSERT_LOG(numberOfChars != 0, ("CFStringGetBytes failed.")); - - buffer[bufferLength] = '\0'; - *pResult = String(buffer); - - return true; -} - -bool HIDDeviceManager::getVendorId(IOHIDDeviceRef device, UInt16* pResult) -{ - SInt32 result; - - if (!getIntProperty(device, CFSTR(kIOHIDVendorIDKey), &result)) - { - return false; - } - - *pResult = result; - - return true; -} - -bool HIDDeviceManager::getProductId(IOHIDDeviceRef device, UInt16* pResult) -{ - SInt32 result; - - if (!getIntProperty(device, CFSTR(kIOHIDProductIDKey), &result)) - { - return false; - } - - *pResult = result; - - return true; -} - -bool HIDDeviceManager::getLocationId(IOHIDDeviceRef device, SInt32* pResult) -{ - SInt32 result; - - if (!getIntProperty(device, CFSTR(kIOHIDLocationIDKey), &result)) - { - return false; - } - - *pResult = result; - - return true; -} - -bool HIDDeviceManager::getSerialNumberString(IOHIDDeviceRef device, String* pResult) -{ - - if (!getStringProperty(device, CFSTR(kIOHIDSerialNumberKey), pResult)) - { - return false; - } - - return true; -} - -bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath) -{ - - String transport; - if (!getStringProperty(device, CFSTR(kIOHIDTransportKey), &transport)) - { - return false; - } - - UInt16 vendorId; - if (!getVendorId(device, &vendorId)) - { - return false; - } - - UInt16 productId; - if (!getProductId(device, &productId)) - { - return false; - } - - String serialNumber; - if (!getSerialNumberString(device, &serialNumber)) - { - return false; - } - - - StringBuffer buffer; - buffer.AppendFormat("%s:vid=%04hx:pid=%04hx:ser=%s", - transport.ToCStr(), - vendorId, - productId, - serialNumber.ToCStr()); - - *pPath = String(buffer); - - return true; -} - -bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) -{ - if (!initializeManager()) - { - return false; - } - - - CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager); - if (!deviceSet) - return false; - - CFIndex deviceCount = CFSetGetCount(deviceSet); - - // Allocate a block of memory and read the set into it. - IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount); - CFSetGetValues(deviceSet, (const void **) devices); - - - // Iterate over devices. - for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) - { - IOHIDDeviceRef hidDev = devices[deviceIndex]; - - if (!hidDev) - { - continue; - } - - HIDDeviceDesc devDesc; - - if (getPath(hidDev, &(devDesc.Path)) && - initVendorProductVersion(hidDev, &devDesc) && - enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) && - initUsage(hidDev, &devDesc)) - { - initStrings(hidDev, &devDesc); - initSerialNumber(hidDev, &devDesc); - - // Look for the device to check if it is already opened. - Ptr existingDevice = DevManager->FindHIDDevice(devDesc, true); - // if device exists and it is opened then most likely the CreateHIDFile - // will fail; therefore, we just set Enumerated to 'true' and continue. - if (existingDevice && existingDevice->pDevice) - { - existingDevice->Enumerated = true; - continue; - } - - // Construct minimal device that the visitor callback can get feature reports from. - OSX::HIDDevice device(this, hidDev); - - enumVisitor->Visit(device, devDesc); - } - } - - OVR_FREE(devices); - CFRelease(deviceSet); - - return true; -} - -OVR::HIDDevice* HIDDeviceManager::Open(const String& path) -{ - - Ptr device = *new OSX::HIDDevice(this); - - if (!device->HIDInitialize(path)) - { - return NULL; - } - - device->AddRef(); - - return device; -} - -bool HIDDeviceManager::getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc) -{ - - if (!initVendorProductVersion(device, desc)) - { - return false; - } - - if (!initUsage(device, desc)) - { - return false; - } - - if (!initSerialNumber(device, desc)) - { - return false; - } - - initStrings(device, desc); - - return true; -} - -// New USB device specified in the matching dictionary has been added (callback function) -void HIDDeviceManager::staticDeviceMatchingCallback(void *inContext, - IOReturn inResult, - void *inSender, - IOHIDDeviceRef inIOHIDDeviceRef) -{ - OVR_UNUSED(inResult); - OVR_UNUSED(inSender); - HIDDeviceManager* hidMgr = static_cast(inContext); - HIDDeviceDesc hidDevDesc; - hidMgr->getPath(inIOHIDDeviceRef, &hidDevDesc.Path); - hidMgr->getFullDesc(inIOHIDDeviceRef, &hidDevDesc); - - hidMgr->DevManager->DetectHIDDevice(hidDevDesc); -} - -//------------------------------------------------------------------------------------- -// **** OSX::HIDDevice - -HIDDevice::HIDDevice(HIDDeviceManager* manager) - : InMinimalMode(false), HIDManager(manager) -{ - Device = NULL; - RepluggedNotificationPort = 0; -} - -// This is a minimal constructor used during enumeration for us to pass -// a HIDDevice to the visit function (so that it can query feature reports). -HIDDevice::HIDDevice(HIDDeviceManager* manager, IOHIDDeviceRef device) -: InMinimalMode(true), HIDManager(manager), Device(device) -{ - RepluggedNotificationPort = 0; -} - -HIDDevice::~HIDDevice() -{ - if (!InMinimalMode) - { - HIDShutdown(); - } -} - -bool HIDDevice::HIDInitialize(const String& path) -{ - - DevDesc.Path = path; - - if (!openDevice()) - { - LogText("OVR::OSX::HIDDevice - Failed to open HIDDevice: %s", path.ToCStr()); - return false; - } - - // Setup notification for when a device is unplugged and plugged back in. - if (!setupDevicePluggedInNotification()) - { - LogText("OVR::OSX::HIDDevice - Failed to setup notification for when device plugged back in."); - closeDevice(false); - return false; - } - - HIDManager->DevManager->pThread->AddTicksNotifier(this); - - - LogText("OVR::OSX::HIDDevice - Opened '%s'\n" - " Manufacturer:'%s' Product:'%s' Serial#:'%s'\n", - DevDesc.Path.ToCStr(), - DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(), - DevDesc.SerialNumber.ToCStr()); - - return true; -} - -bool HIDDevice::initInfo() -{ - // Device must have been successfully opened. - OVR_ASSERT(Device); - - - // Get report lengths. - SInt32 bufferLength; - bool getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxInputReportSizeKey), &bufferLength); - OVR_ASSERT(getResult); - InputReportBufferLength = (UInt16) bufferLength; - - getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxOutputReportSizeKey), &bufferLength); - OVR_ASSERT(getResult); - OutputReportBufferLength = (UInt16) bufferLength; - - getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxFeatureReportSizeKey), &bufferLength); - OVR_ASSERT(getResult); - FeatureReportBufferLength = (UInt16) bufferLength; - - - if (ReadBufferSize < InputReportBufferLength) - { - OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer.")); - return false; - } - - // Get device desc. - if (!HIDManager->getFullDesc(Device, &DevDesc)) - { - OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device.")); - return false; - } - - return true; -} - -void HIDDevice::staticDeviceAddedCallback(void* pContext, io_iterator_t iterator) -{ - HIDDevice* pDevice = (HIDDevice*) pContext; - pDevice->deviceAddedCallback(iterator); -} - -void HIDDevice::deviceAddedCallback(io_iterator_t iterator) -{ - - if (Device == NULL) - { - if (openDevice()) - { - LogText("OVR::OSX::HIDDevice - Reopened device : %s", DevDesc.Path.ToCStr()); - - Ptr existingHIDDev = HIDManager->DevManager->FindHIDDevice(DevDesc, true); - if (existingHIDDev && existingHIDDev->pDevice) - { - HIDManager->DevManager->CallOnDeviceAdded(existingHIDDev); - } - } - } - - // Reset callback. - while (IOIteratorNext(iterator)) - ; -} - -bool HIDDevice::openDevice() -{ - - // Have to iterate through devices again to generate paths. - CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager->HIDManager); - CFIndex deviceCount = CFSetGetCount(deviceSet); - - // Allocate a block of memory and read the set into it. - IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount); - CFSetGetValues(deviceSet, (const void **) devices); - - - // Iterate over devices. - IOHIDDeviceRef device = NULL; - - for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) - { - IOHIDDeviceRef tmpDevice = devices[deviceIndex]; - - if (!tmpDevice) - { - continue; - } - - String path; - if (!HIDManager->getPath(tmpDevice, &path)) - { - continue; - } - - if (path == DevDesc.Path) - { - device = tmpDevice; - break; - } - } - - - OVR_FREE(devices); - - if (!device) - { - CFRelease(deviceSet); - return false; - } - - // Attempt to open device. - if (IOHIDDeviceOpen(device, kIOHIDOptionsTypeSeizeDevice) - != kIOReturnSuccess) - { - CFRelease(deviceSet); - return false; - } - - // Retain the device before we release the set. - CFRetain(device); - CFRelease(deviceSet); - - - Device = device; - - - if (!initInfo()) - { - IOHIDDeviceClose(Device, kIOHIDOptionsTypeSeizeDevice); - CFRelease(Device); - Device = NULL; - return false; - } - - - // Setup the Run Loop and callbacks. - IOHIDDeviceScheduleWithRunLoop(Device, - HIDManager->getRunLoop(), - kCFRunLoopDefaultMode); - - IOHIDDeviceRegisterInputReportCallback(Device, - ReadBuffer, - ReadBufferSize, - staticHIDReportCallback, - this); - - IOHIDDeviceRegisterRemovalCallback(Device, - staticDeviceRemovedCallback, - this); - - return true; -} - -void HIDDevice::HIDShutdown() -{ - - HIDManager->DevManager->pThread->RemoveTicksNotifier(this); - - if (Device != NULL) // Device may already have been closed if unplugged. - { - closeDevice(false); - } - - IOObjectRelease(RepluggedNotification); - if (RepluggedNotificationPort) - IONotificationPortDestroy(RepluggedNotificationPort); - - LogText("OVR::OSX::HIDDevice - HIDShutdown '%s'\n", DevDesc.Path.ToCStr()); -} - -bool HIDDevice::setupDevicePluggedInNotification() -{ - - // Setup notification when devices are plugged in. - RepluggedNotificationPort = IONotificationPortCreate(kIOMasterPortDefault); - - CFRunLoopSourceRef notificationRunLoopSource = - IONotificationPortGetRunLoopSource(RepluggedNotificationPort); - - CFRunLoopAddSource(HIDManager->getRunLoop(), - notificationRunLoopSource, - kCFRunLoopDefaultMode); - - CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); - - // Have to specify vendorId and productId. Doesn't seem to accept additional - // things like serial number. - SInt32 vendorId = DevDesc.VendorId; - CFNumberRef numberRef = CFNumberCreate(kCFAllocatorDefault, - kCFNumberSInt32Type, - &vendorId); - CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef); - CFRelease(numberRef); - - SInt32 deviceProductId = DevDesc.ProductId; - numberRef = CFNumberCreate(kCFAllocatorDefault, - kCFNumberSInt32Type, - &deviceProductId); - CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef); - CFRelease(numberRef); - - kern_return_t result = - IOServiceAddMatchingNotification(RepluggedNotificationPort, - kIOMatchedNotification, - matchingDict, - staticDeviceAddedCallback, - this, - &RepluggedNotification); - - if (result != KERN_SUCCESS) - { - CFRelease(RepluggedNotificationPort); - RepluggedNotificationPort = 0; - return false; - } - - // Iterate through to arm. - while (IOIteratorNext(RepluggedNotification)) - { - } - - return true; -} - -void HIDDevice::closeDevice(bool wasUnplugged) -{ - OVR_ASSERT(Device != NULL); - - if (!wasUnplugged) - { - // Clear the registered callbacks. - IOHIDDeviceRegisterInputReportCallback(Device, - ReadBuffer, - InputReportBufferLength, - NULL, - this); - - IOHIDDeviceRegisterRemovalCallback(Device, NULL, this); - - IOHIDDeviceUnscheduleFromRunLoop(Device, - HIDManager->getRunLoop(), - kCFRunLoopDefaultMode); - IOHIDDeviceClose(Device, kIOHIDOptionsTypeNone); - } - - CFRelease(Device); - Device = NULL; - - LogText("OVR::OSX::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr()); -} - -void HIDDevice::staticHIDReportCallback(void* pContext, - IOReturn result, - void* pSender, - IOHIDReportType reportType, - uint32_t reportId, - uint8_t* pReport, - CFIndex reportLength) -{ - OVR_UNUSED(result); - OVR_UNUSED(pSender); - OVR_UNUSED(reportType); - OVR_UNUSED(reportId); - - HIDDevice* pDevice = (HIDDevice*) pContext; - return pDevice->hidReportCallback(pReport, (UInt32)reportLength); -} - -void HIDDevice::hidReportCallback(UByte* pData, UInt32 length) -{ - - // We got data. - if (Handler) - { - Handler->OnInputReport(pData, length); - } -} - -void HIDDevice::staticDeviceRemovedCallback(void* pContext, IOReturn result, void* pSender) -{ - OVR_UNUSED(result); - OVR_UNUSED(pSender); - HIDDevice* pDevice = (HIDDevice*) pContext; - pDevice->deviceRemovedCallback(); -} - -void HIDDevice::deviceRemovedCallback() -{ - Ptr _this(this); // prevent from release - - Ptr existingHIDDev = HIDManager->DevManager->FindHIDDevice(DevDesc, true); - if (existingHIDDev && existingHIDDev->pDevice) - { - HIDManager->DevManager->CallOnDeviceRemoved(existingHIDDev); - } - closeDevice(true); -} - -CFStringRef HIDDevice::generateRunLoopModeString(IOHIDDeviceRef device) -{ - const UInt32 safeBuffSize = 256; - char nameBuff[safeBuffSize]; - OVR_sprintf(nameBuff, safeBuffSize, "%016lX", device); - - return CFStringCreateWithCString(NULL, nameBuff, kCFStringEncodingASCII); -} - -bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length) -{ - - if (!Device) - return false; - - UByte reportID = data[0]; - - if (reportID == 0) - { - // Not using reports so remove from data packet. - data++; - length--; - } - - IOReturn result = IOHIDDeviceSetReport( Device, - kIOHIDReportTypeFeature, - reportID, - data, - length); - - return (result == kIOReturnSuccess); -} - -bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length) -{ - if (!Device) - return false; - - CFIndex bufferLength = length; - - // Report id is in first byte of the buffer. - IOReturn result = IOHIDDeviceGetReport(Device, kIOHIDReportTypeFeature, data[0], data, &bufferLength); - - return (result == kIOReturnSuccess); -} - -double HIDDevice::OnTicks(double tickSeconds) -{ - - if (Handler) - { - return Handler->OnTicks(tickSeconds); - } - - return DeviceManagerThread::Notifier::OnTicks(tickSeconds); -} - -HIDDeviceManager* HIDDeviceManager::CreateInternal(OSX::DeviceManager* devManager) -{ - - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr manager = *new OSX::HIDDeviceManager(devManager); - - if (manager) - { - if (manager->Initialize()) - { - manager->AddRef(); - } - else - { - manager.Clear(); - } - } - - return manager.GetPtr(); -} - -} // namespace OSX - -//------------------------------------------------------------------------------------- -// ***** Creation - -// Creates a new HIDDeviceManager and initializes OVR. -HIDDeviceManager* HIDDeviceManager::Create(Ptr& deviceManager) -{ - - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr deviceManagerOSX = *new OSX::DeviceManager; - - if (!deviceManagerOSX) - { - return NULL; - } - - if (!deviceManagerOSX->Initialize(NULL)) - { - return NULL; - } - - deviceManager = deviceManagerOSX; - - return deviceManagerOSX->GetHIDDeviceManager(); -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_OSX_HIDDevice.h b/LibOVR/Src/OVR_OSX_HIDDevice.h deleted file mode 100644 index c6140cb..0000000 --- a/LibOVR/Src/OVR_OSX_HIDDevice.h +++ /dev/null @@ -1,160 +0,0 @@ -/************************************************************************************ -Filename : OVR_OSX_HIDDevice.h -Content : OSX HID device implementation. -Created : February 26, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_OSX_HIDDevice_h -#define OVR_OSX_HIDDevice_h - -#include "OVR_HIDDevice.h" - -#include "OVR_OSX_DeviceManager.h" - -#include - -namespace OVR { namespace OSX { - -class HIDDeviceManager; - -//------------------------------------------------------------------------------------- -// ***** OSX HIDDevice - -class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier -{ -private: - friend class HIDDeviceManager; - -public: - HIDDevice(HIDDeviceManager* manager); - - // This is a minimal constructor used during enumeration for us to pass - // a HIDDevice to the visit function (so that it can query feature reports). - HIDDevice(HIDDeviceManager* manager, IOHIDDeviceRef device); - - virtual ~HIDDevice(); - - bool HIDInitialize(const String& path); - void HIDShutdown(); - - virtual bool SetFeatureReport(UByte* data, UInt32 length); - virtual bool GetFeatureReport(UByte* data, UInt32 length); - - bool Write(UByte* data, UInt32 length); - - bool Read(UByte* pData, UInt32 length, UInt32 timeoutMilliS); - bool ReadBlocking(UByte* pData, UInt32 length); - - - // DeviceManagerThread::Notifier - double OnTicks(double tickSeconds); - -private: - bool initInfo(); - bool openDevice(); - void closeDevice(bool wasUnplugged); - bool setupDevicePluggedInNotification(); - CFStringRef generateRunLoopModeString(IOHIDDeviceRef device); - - static void staticHIDReportCallback(void* pContext, - IOReturn result, - void* pSender, - IOHIDReportType reportType, - uint32_t reportId, - uint8_t* pReport, - CFIndex reportLength); - void hidReportCallback(UByte* pData, UInt32 length); - - static void staticDeviceRemovedCallback(void* pContext, - IOReturn result, - void* pSender); - void deviceRemovedCallback(); - - static void staticDeviceAddedCallback(void* pContext, - io_iterator_t iterator); - void deviceAddedCallback(io_iterator_t iterator); - - bool InMinimalMode; - HIDDeviceManager* HIDManager; - IOHIDDeviceRef Device; - HIDDeviceDesc DevDesc; - - enum { ReadBufferSize = 96 }; - UByte ReadBuffer[ReadBufferSize]; - - UInt16 InputReportBufferLength; - UInt16 OutputReportBufferLength; - UInt16 FeatureReportBufferLength; - - IONotificationPortRef RepluggedNotificationPort; - io_iterator_t RepluggedNotification; -}; - - -//------------------------------------------------------------------------------------- -// ***** OSX HIDDeviceManager - -class HIDDeviceManager : public OVR::HIDDeviceManager -{ - friend class HIDDevice; - -public: - HIDDeviceManager(OSX::DeviceManager* Manager); - virtual ~HIDDeviceManager(); - - virtual bool Initialize(); - virtual void Shutdown(); - - virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor); - virtual OVR::HIDDevice* Open(const String& path); - - static HIDDeviceManager* CreateInternal(DeviceManager* manager); - -private: - CFRunLoopRef getRunLoop(); - bool initializeManager(); - bool initVendorProductVersion(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc); - bool initUsage(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc); - bool initStrings(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc); - bool initSerialNumber(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc); - bool getVendorId(IOHIDDeviceRef device, UInt16* pResult); - bool getProductId(IOHIDDeviceRef device, UInt16* pResult); - bool getLocationId(IOHIDDeviceRef device, SInt32* pResult); - bool getSerialNumberString(IOHIDDeviceRef device, String* pResult); - bool getPath(IOHIDDeviceRef device, String* pPath); - bool getIntProperty(IOHIDDeviceRef device, CFStringRef key, int32_t* pResult); - bool getStringProperty(IOHIDDeviceRef device, CFStringRef propertyName, String* pResult); - bool getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc); - - static void staticDeviceMatchingCallback(void *inContext, - IOReturn inResult, - void *inSender, - IOHIDDeviceRef inIOHIDDeviceRef); - - DeviceManager* DevManager; - - IOHIDManagerRef HIDManager; -}; - -}} // namespace OVR::OSX - -#endif // OVR_OSX_HIDDevice_h diff --git a/LibOVR/Src/OVR_OSX_HMDDevice.cpp b/LibOVR/Src/OVR_OSX_HMDDevice.cpp deleted file mode 100644 index e16de81..0000000 --- a/LibOVR/Src/OVR_OSX_HMDDevice.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_HMDDevice.cpp -Content : OSX Interface to HMD - detects HMD display -Created : September 21, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_OSX_HMDDevice.h" - -#include "OVR_OSX_DeviceManager.h" -#include "Util/Util_Render_Stereo.h" - -#include "OVR_OSX_HMDDevice.h" -#include -#include -#include -#include - -namespace OVR { namespace OSX { - -using namespace OVR::Util::Render; - -//------------------------------------------------------------------------------------- - -HMDDeviceCreateDesc::HMDDeviceCreateDesc(DeviceFactory* factory, - UInt32 vend, UInt32 prod, const String& displayDeviceName, int dispId) - : DeviceCreateDesc(factory, Device_HMD), - DisplayDeviceName(displayDeviceName), - Contents(0), - DisplayId(dispId) -{ - OVR_UNUSED(vend); - OVR_UNUSED(prod); - DeviceId = DisplayDeviceName; - - Desktop.X = 0; - Desktop.Y = 0; - ResolutionInPixels = Sizei(0); - ScreenSizeInMeters = Sizef(0.0f); - VCenterFromTopInMeters = 0.0f; - LensSeparationInMeters = 0.0f; -} - -HMDDeviceCreateDesc::HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other) - : DeviceCreateDesc(other.pFactory, Device_HMD), - DeviceId(other.DeviceId), DisplayDeviceName(other.DisplayDeviceName), - Contents(other.Contents), - DisplayId(other.DisplayId) -{ - Desktop.X = other.Desktop.X; - Desktop.Y = other.Desktop.Y; - ResolutionInPixels = other.ResolutionInPixels; - ScreenSizeInMeters = other.ScreenSizeInMeters; - VCenterFromTopInMeters = other.VCenterFromTopInMeters; - LensSeparationInMeters = other.LensSeparationInMeters; -} - -HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc** pcandidate) const -{ - if ((other.Type != Device_HMD) || (other.pFactory != pFactory)) - return Match_None; - - // There are several reasons we can come in here: - // a) Matching this HMD Monitor created desc to OTHER HMD Monitor desc - // - Require exact device DeviceId/DeviceName match - // b) Matching SensorDisplayInfo created desc to OTHER HMD Monitor desc - // - This DeviceId is empty; becomes candidate - // c) Matching this HMD Monitor created desc to SensorDisplayInfo desc - // - This other.DeviceId is empty; becomes candidate - - const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other; - - if ((DeviceId == s2.DeviceId) && - (DisplayId == s2.DisplayId)) - { - // Non-null DeviceId may match while size is different if screen size was overwritten - // by SensorDisplayInfo in prior iteration. - if (!DeviceId.IsEmpty() || - (ScreenSizeInMeters == s2.ScreenSizeInMeters) ) - { - *pcandidate = 0; - return Match_Found; - } - } - - - // DisplayInfo takes precedence, although we try to match it first. - if ((ResolutionInPixels == s2.ResolutionInPixels) && - (ScreenSizeInMeters == s2.ScreenSizeInMeters)) - { - if (DeviceId.IsEmpty() && !s2.DeviceId.IsEmpty()) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - - *pcandidate = 0; - return Match_Found; - } - - // SensorDisplayInfo may override resolution settings, so store as candidiate. - if (s2.DeviceId.IsEmpty() && s2.DisplayId == 0) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - // OTHER HMD Monitor desc may initialize DeviceName/Id - else if (DeviceId.IsEmpty() && DisplayId == 0) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - - return Match_None; -} - - -bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other, bool* newDeviceFlag) -{ - // This candidate was the the "best fit" to apply sensor DisplayInfo to. - OVR_ASSERT(other.Type == Device_HMD); - - const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other; - - // Force screen size on resolution from SensorDisplayInfo. - // We do this because USB detection is more reliable as compared to HDMI EDID, - // which may be corrupted by splitter reporting wrong monitor - if (s2.DeviceId.IsEmpty() && s2.DisplayId == 0) - { - ScreenSizeInMeters = s2.ScreenSizeInMeters; - Contents |= Contents_Screen; - - if (s2.Contents & HMDDeviceCreateDesc::Contents_Distortion) - { - memcpy(DistortionK, s2.DistortionK, sizeof(float)*4); - // TODO: DistortionEqn - Contents |= Contents_Distortion; - } - DeviceId = s2.DeviceId; - DisplayId = s2.DisplayId; - DisplayDeviceName = s2.DisplayDeviceName; - Desktop.X = s2.Desktop.X; - Desktop.Y = s2.Desktop.Y; - if (newDeviceFlag) *newDeviceFlag = true; - } - else if (DeviceId.IsEmpty()) - { - // This branch is executed when 'fake' HMD descriptor is being replaced by - // the real one. - DeviceId = s2.DeviceId; - DisplayId = s2.DisplayId; - DisplayDeviceName = s2.DisplayDeviceName; - Desktop.X = s2.Desktop.X; - Desktop.Y = s2.Desktop.Y; - - // ScreenSize and Resolution are NOT assigned here, since they may have - // come from a sensor DisplayInfo (which has precedence over HDMI). - - if (newDeviceFlag) *newDeviceFlag = true; - } - else - { - if (newDeviceFlag) *newDeviceFlag = false; - } - - return true; -} - - -//------------------------------------------------------------------------------------- - - -//------------------------------------------------------------------------------------- -// ***** HMDDeviceFactory - -HMDDeviceFactory &HMDDeviceFactory::GetInstance() -{ - static HMDDeviceFactory instance; - return instance; -} - -void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) -{ - CGDirectDisplayID Displays[32]; - uint32_t NDisplays = 0; - CGGetOnlineDisplayList(32, Displays, &NDisplays); - - for (unsigned int i = 0; i < NDisplays; i++) - { - io_service_t port = CGDisplayIOServicePort(Displays[i]); - CFDictionaryRef DispInfo = IODisplayCreateInfoDictionary(port, kIODisplayMatchingInfo); - - uint32_t vendor = CGDisplayVendorNumber(Displays[i]); - uint32_t product = CGDisplayModelNumber(Displays[i]); - - CGRect desktop = CGDisplayBounds(Displays[i]); - - if (vendor == 16082 && ( (product == 1)||(product == 2) ) ) // 7" or HD - { - char idstring[9]; - idstring[0] = 'A'-1+((vendor>>10) & 31); - idstring[1] = 'A'-1+((vendor>>5) & 31); - idstring[2] = 'A'-1+((vendor>>0) & 31); - snprintf(idstring+3, 5, "%04d", product); - - HMDDeviceCreateDesc hmdCreateDesc(this, vendor, product, idstring, Displays[i]); - - // Hard-coded defaults in case the device doesn't have the data itself. - if (product == 3) - { // DK2 prototypes and variants (default to HmdType_DK2) - hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y, - 1920, 1080, 0.12576f, 0.07074f, 0.12576f*0.5f, 0.0635f ); - } - else if (product == 2) - { // HD Prototypes (default to HmdType_DKHDProto) - hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y, - 1920, 1080, 0.12096f, 0.06804f, 0.06804f*0.5f, 0.0635f); - } - else if (product == 1) - { // DK1 - hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y, - 1280, 800, 0.14976f, 0.0936f, 0.0936f*0.5f, 0.0635f); - } - else - { // Future Oculus HMD devices (default to DK1 dimensions) - hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y, - 1280, 800, 0.14976f, 0.0936f, 0.0936f*0.5f, 0.0635f); - } - - OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %x:%x\n", vendor, product)); - - // Notify caller about detected device. This will call EnumerateAddDevice - // if the this is the first time device was detected. - visitor.Visit(hmdCreateDesc); - } - CFRelease(DispInfo); - } -} - -#include "OVR_Common_HMDDevice.cpp" - -}} // namespace OVR::OSX - - diff --git a/LibOVR/Src/OVR_OSX_HMDDevice.h b/LibOVR/Src/OVR_OSX_HMDDevice.h deleted file mode 100644 index dd5c0fe..0000000 --- a/LibOVR/Src/OVR_OSX_HMDDevice.h +++ /dev/null @@ -1,153 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_HMDDevice.h -Content : OSX HMDDevice implementation -Created : September 21, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_OSX_HMDDevice_h -#define OVR_OSX_HMDDevice_h - -#include "OVR_DeviceImpl.h" -#include "Kernel/OVR_String.h" -#include "OVR_Profile.h" - -namespace OVR { namespace OSX { - -class HMDDevice; - - -//------------------------------------------------------------------------------------- - -// HMDDeviceFactory enumerates attached Oculus HMD devices. -// -// This is currently done by matching monitor device strings. - -class HMDDeviceFactory : public DeviceFactory -{ -public: - static HMDDeviceFactory &GetInstance(); - - // Enumerates devices, creating and destroying relevant objects in manager. - virtual void EnumerateDevices(EnumerateVisitor& visitor); - -protected: - DeviceManager* getManager() const { return (DeviceManager*) pManager; } -}; - - -class HMDDeviceCreateDesc : public DeviceCreateDesc -{ - friend class HMDDevice; - -protected: - enum - { - Contents_Screen = 1, - Contents_Distortion = 2, - }; - String DeviceId; - String DisplayDeviceName; - struct - { - int X, Y; - } Desktop; - unsigned int Contents; - - Sizei ResolutionInPixels; - Sizef ScreenSizeInMeters; - float VCenterFromTopInMeters; - float LensSeparationInMeters; - - // TODO: update these to splines. - DistortionEqnType DistortionEqn; - float DistortionK[4]; - - int DisplayId; - -public: - HMDDeviceCreateDesc(DeviceFactory* factory, - UInt32 vendor, UInt32 product, const String& displayDeviceName, int dispId); - HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other); - - virtual DeviceCreateDesc* Clone() const - { - return new HMDDeviceCreateDesc(*this); - } - - virtual DeviceBase* NewDeviceInstance(); - - virtual MatchResult MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc**) const; - - virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL); - - virtual bool GetDeviceInfo(DeviceInfo* info) const; - - void SetScreenParameters(int x, int y, - int hres, int vres, - float hsize, float vsize, - float vCenterFromTopInMeters, float lensSeparationInMeters); - void SetDistortion(const float* dks); - - HmdTypeEnum GetHmdType() const; -}; - - -//------------------------------------------------------------------------------------- - -// HMDDevice represents an Oculus HMD device unit. An instance of this class -// is typically created from the DeviceManager. -// After HMD device is created, we its sensor data can be obtained by -// first creating a Sensor object and then wrappig it in SensorFusion. - -class HMDDevice : public DeviceImpl -{ -public: - HMDDevice(HMDDeviceCreateDesc* createDesc); - ~HMDDevice(); - - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - // Requests the currently used default profile. This profile affects the - // settings reported by HMDInfo. - virtual Profile* GetProfile(); - virtual const char* GetProfileName(); - virtual bool SetProfileName(const char* name); - - // Query associated sensor. - virtual OVR::SensorDevice* GetSensor(); - -protected: - HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); } - - // User name for the profile used with this device. - String ProfileName; - mutable Ptr pCachedProfile; -}; - - -}} // namespace OVR::OSX - -#endif // OVR_OSX_HMDDevice_h - diff --git a/LibOVR/Src/OVR_OSX_SensorDevice.cpp b/LibOVR/Src/OVR_OSX_SensorDevice.cpp deleted file mode 100644 index 9b783c6..0000000 --- a/LibOVR/Src/OVR_OSX_SensorDevice.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_SensorDevice.cpp -Content : OSX SensorDevice implementation -Created : March 14, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_OSX_HMDDevice.h" -#include "OVR_SensorImpl.h" -#include "OVR_DeviceImpl.h" - -namespace OVR { namespace OSX { - -} // namespace OSX - -//------------------------------------------------------------------------------------- -void SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo, - DeviceFactory::EnumerateVisitor& visitor) -{ - - OSX::HMDDeviceCreateDesc hmdCreateDesc(&OSX::HMDDeviceFactory::GetInstance(), 1, 1, "", 0); - - hmdCreateDesc.SetScreenParameters( 0, 0, - displayInfo.HResolution, displayInfo.VResolution, - displayInfo.HScreenSize, displayInfo.VScreenSize, - displayInfo.VCenter, displayInfo.LensSeparation); - - if ((displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) == SensorDisplayInfoImpl::Base_Distortion) - { - hmdCreateDesc.SetDistortion(displayInfo.DistortionK); - // TODO: add DistortionEqn - } - - visitor.Visit(hmdCreateDesc); -} - -} // namespace OVR - - diff --git a/LibOVR/Src/OVR_Profile.cpp b/LibOVR/Src/OVR_Profile.cpp index 4844c29..dcbc95d 100644 --- a/LibOVR/Src/OVR_Profile.cpp +++ b/LibOVR/Src/OVR_Profile.cpp @@ -12,16 +12,16 @@ Notes : can be accomplished in game via the Profile API or by the official Oculus Configuration Utility. -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -32,15 +32,17 @@ limitations under the License. ************************************************************************************/ #include "OVR_Profile.h" -#include "OVR_Device.h" #include "OVR_JSON.h" -#include "Kernel/OVR_Types.h" #include "Kernel/OVR_SysFile.h" #include "Kernel/OVR_Allocator.h" -#include "Kernel/OVR_Array.h" +#include "OVR_Stereo.h" #ifdef OVR_OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include #include +#elif defined(OVR_OS_MS) // Other Microsoft OSs +// Nothing, thanks. #else #include #include @@ -52,13 +54,69 @@ limitations under the License. #endif - #define PROFILE_VERSION 2.0 #define MAX_PROFILE_MAJOR_VERSION 2 #define MAX_DEVICE_PROFILE_MAJOR_VERSION 1 + namespace OVR { + +//----------------------------------------------------------------------------- +// ProfileDeviceKey + +ProfileDeviceKey::ProfileDeviceKey(const HMDInfo* info) : + Valid(false) +{ + if (info) + { + PrintedSerial = info->PrintedSerial; + ProductName = SanitizeProductName(info->ProductName); + ProductId = info->ProductId; + HmdType = info->HmdType; + + if (ProductId != 0) + { + Valid = true; + } + } + else + { + ProductId = 0; + HmdType = HmdType_None; + } +} + +String ProfileDeviceKey::SanitizeProductName(String productName) +{ + String result; + + if (!productName.IsEmpty()) + { + const char* product_name = productName.ToCStr(); + + // First strip off "Oculus" + const char* oculus = strstr(product_name, "Oculus "); + if (oculus) + { + product_name = oculus + OVR_strlen("Oculus "); + } + + // And remove spaces from the name + for (const char* s = product_name; *s != 0; s++) + { + if (*s != ' ') + { + result.AppendChar(*s); + } + } + } + + return result; +} + + + //----------------------------------------------------------------------------- // Returns the pathname of the JSON file containing the stored profiles String GetBaseOVRPath(bool create_dir) @@ -85,6 +143,12 @@ String GetBaseOVRPath(bool create_dir) CreateDirectory(wpath, NULL); } } + +#elif defined(OVR_OS_OS) // Other Microsoft OSs + + // TODO: figure this out. + OVR_UNUSED ( create_dir ); + path = ""; #elif defined(OVR_OS_MAC) @@ -107,8 +171,7 @@ String GetBaseOVRPath(bool create_dir) #else - passwd* pwd = getpwuid(getuid()); - const char* home = pwd->pw_dir; + const char* home = getenv("HOME"); path = home; path += "/.config/Oculus"; @@ -130,56 +193,9 @@ String GetBaseOVRPath(bool create_dir) return path; } -String ProfileManager::GetProfilePath(bool create_dir) -{ - String path = GetBaseOVRPath(create_dir); - path += "/ProfileDB.json"; - return path; -} - -bool ProfileManager::GetDeviceTags(const DeviceBase* device, String& product, String& serial) +String ProfileManager::GetProfilePath() { - product = ""; - serial = ""; - - if (device && device->GetType() == Device_HMD) - { - HMDDevice* hmd = (HMDDevice*)device; - - Ptr sensor = *(hmd->GetSensor()); - if (sensor) - { - SensorInfo sinfo; - sensor->GetDeviceInfo(&sinfo); - serial = sinfo.SerialNumber; // get the serial number - - // Derive the product tag from the HMD product name - HMDInfo hmdinfo; - hmd->GetDeviceInfo(&hmdinfo); - - const char* product_name = NULL; - - // If the HMD is unrecognized then use the name stamped into the - // sensor firmware - if (hmdinfo.HmdType == HmdType_None || hmdinfo.HmdType == HmdType_Unknown) - product_name = sinfo.ProductName.ToCStr(); - else - product_name = hmdinfo.ProductName.ToCStr(); - - // First strip off "Oculus" - const char* oculus = strstr(product_name, "Oculus "); - if (oculus) - product_name = oculus + OVR_strlen("Oculus "); - // And remove spaces from the name - for (const char* s=product_name; *s != 0; s++) - { - if (*s != ' ') - product.AppendChar(*s); - } - } - } - - return (!product.IsEmpty() && !serial.IsEmpty()); + return BasePath + "/ProfileDB.json"; } static JSON* FindTaggedData(JSON* data, const char** tag_names, const char** qtags, int num_qtags) @@ -257,64 +273,127 @@ static void FilterTaggedData(JSON* data, const char* tag_name, const char* qtag, } } + //----------------------------------------------------------------------------- // ***** ProfileManager -ProfileManager::ProfileManager() +template<> ProfileManager* OVR::SystemSingletonBase::SlowGetInstance() { - Changed = false; + static OVR::Lock lock; + OVR::Lock::Locker locker(&lock); + if (!SingletonInstance) SingletonInstance = new ProfileManager(true); + return SingletonInstance; +} + +ProfileManager::ProfileManager(bool sys_register) : + Changed(false) +{ + // Attempt to get the base path automatically, but this may fail + BasePath = GetBaseOVRPath(false); + + if (sys_register) + PushDestroyCallbacks(); } ProfileManager::~ProfileManager() { - ClearCache(); + ClearProfileData(); } -ProfileManager* ProfileManager::Create() +void ProfileManager::OnSystemDestroy() { - return new ProfileManager(); + delete this; } -// Clear the local profile cache -void ProfileManager::ClearCache() +// In the service process it is important to set the base path because this cannot be detected automatically +void ProfileManager::SetBasePath(String basePath) { - Lock::Locker lockScope(&ProfileLock); - //ProfileCache.Clear(); - if (ProfileCache) + if (basePath != BasePath) { - //ProfileCache->Release(); - ProfileCache = NULL; + BasePath = basePath; + LoadCache(false); } +} + +// Clear the local profile cache +void ProfileManager::ClearProfileData() +{ + Lock::Locker lockScope(&ProfileLock); + + ProfileCache.Clear(); + Changed = false; +} + +// Serializes the profiles to disk. +void ProfileManager::Save() +{ + Lock::Locker lockScope(&ProfileLock); + + if (ProfileCache == NULL) + return; + + // Save the profile to disk + BasePath = GetBaseOVRPath(true); // create the base directory if it doesn't exist + String path = GetProfilePath(); + ProfileCache->Save(path); Changed = false; } // Returns a profile with all system default values -Profile* ProfileManager::GetDefaultProfile(const DeviceBase* device) +Profile* ProfileManager::GetDefaultProfile(HmdTypeEnum device) { // In the absence of any data, set some reasonable profile defaults. // However, this is not future proof and developers should still // provide reasonable default values for queried fields. + + // Biometric data Profile* profile = CreateProfile(); - profile->SetValue(OVR_KEY_USER, "default"); - profile->SetValue(OVR_KEY_NAME, "Default"); - profile->SetValue(OVR_KEY_GENDER, OVR_DEFAULT_GENDER); + profile->SetValue(OVR_KEY_USER, "default"); + profile->SetValue(OVR_KEY_NAME, "Default"); + profile->SetValue(OVR_KEY_GENDER, OVR_DEFAULT_GENDER); profile->SetFloatValue(OVR_KEY_PLAYER_HEIGHT, OVR_DEFAULT_PLAYER_HEIGHT); - profile->SetFloatValue(OVR_KEY_EYE_HEIGHT, 1.675f); - profile->SetFloatValue(OVR_KEY_IPD, OVR_DEFAULT_IPD); + profile->SetFloatValue(OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT); + profile->SetFloatValue(OVR_KEY_IPD, OVR_DEFAULT_IPD); + float half_ipd[2] = { OVR_DEFAULT_IPD / 2, OVR_DEFAULT_IPD / 2 }; + profile->SetFloatValues(OVR_KEY_EYE_TO_NOSE_DISTANCE, half_ipd, 2); float dist[2] = {OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, OVR_DEFAULT_NECK_TO_EYE_VERTICAL}; profile->SetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, dist, 2); - //profile->SetFloatValue(OVR_KEY_NECK_TO_EYE_VERTICAL, 0.12f); - - // TODO: Provide device specific defaults - OVR_UNUSED(device); + + // Device specific data + if (device != HmdType_None) + { + if (device == HmdType_CrystalCoveProto || device == HmdType_DK2) + { + profile->SetValue("EyeCup", "A"); + profile->SetIntValue(OVR_KEY_EYE_RELIEF_DIAL, OVR_DEFAULT_EYE_RELIEF_DIAL); - // DK1 default - //profile->SetValue("EyeCup", "A"); + // TODO: These defaults are a little bogus and designed for continuity with 0.3 + // eye-relief values. We need better measurement-based numbers in future releases + float max_eye_plate[2] = { 0.01965f + 0.018f, 0.01965f + 0.018f }; + profile->SetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, max_eye_plate, 2); + } + else + { // DK1 and DKHD variants + profile->SetValue("EyeCup", "A"); + profile->SetIntValue(OVR_KEY_EYE_RELIEF_DIAL, OVR_DEFAULT_EYE_RELIEF_DIAL); + + // TODO: These defaults are a little bogus and designed for continuity with 0.3 + // DK1 distortion. We need better measurement-based numbers in future releases + float max_eye_plate[2] = { 0.02357f + 0.017f, 0.02357f + 0.017f }; + profile->SetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, max_eye_plate, 2); + } + } return profile; } -// Poplulates the local profile cache. This occurs on the first access of the profile +//------------------------------------------------------------------------------ +void ProfileManager::Read() +{ + LoadCache(false); +} + +// Populates the local profile cache. This occurs on the first access of the profile // data. All profile operations are performed against the local cache until the // ProfileManager is released or goes out of scope at which time the cache is serialized // to disk. @@ -322,14 +401,14 @@ void ProfileManager::LoadCache(bool create) { Lock::Locker lockScope(&ProfileLock); - ClearCache(); + ClearProfileData(); - String path = GetProfilePath(false); + String path = GetProfilePath(); Ptr root = *JSON::Load(path); if (root == NULL) { - path = GetBaseOVRPath(false) + "/Profiles.json"; // look for legacy profile + path = BasePath + "/Profiles.json"; // look for legacy profile root = *JSON::Load(path); if (root == NULL) @@ -366,7 +445,7 @@ void ProfileManager::LoadCache(bool create) { // Verify the file format and version JSON* version_item = root->GetFirstItem(); - if (version_item->Name == "Oculus Profile Version") + if (version_item && version_item->Name == "Oculus Profile Version") { int major = atoi(version_item->Value.ToCStr()); if (major != 2) @@ -387,6 +466,10 @@ void ProfileManager::LoadV1Profiles(JSON* v1) JSON* item1 = v1->GetNextItem(item0); JSON* item2 = v1->GetNextItem(item1); + OVR_ASSERT(item1 && item2); + if(!item1 || !item2) + return; + // Create the new profile database Ptr root = *JSON::CreateObject(); root->AddNumberItem("Oculus Profile Version", 2.0); @@ -591,6 +674,37 @@ bool ProfileManager::CreateUser(const char* user, const char* name) return true; } +bool ProfileManager::HasUser(const char* user) +{ + Lock::Locker lockScope(&ProfileLock); + + if (ProfileCache == NULL) + { // Load the cache + LoadCache(false); + if (ProfileCache == NULL) + return false; + } + + JSON* users = ProfileCache->GetItemByName("Users"); + if (users == NULL) + return false; + + // Remove this user from the User table + JSON* user_item = users->GetFirstItem(); + while (user_item) + { + JSON* userid = user_item->GetItemByName("User"); + if (OVR_strcmp(user, userid->Value) == 0) + { + return true; + } + + user_item = users->GetNextItem(user_item); + } + + return false; +} + // Returns the user id of a specific user in the list. The returned // memory is locally allocated and should not be stored or deleted. Returns NULL // if the index is invalid @@ -673,28 +787,28 @@ bool ProfileManager::RemoveUser(const char* user) Profile* ProfileManager::CreateProfile() { - Profile* profile = new Profile(); + Profile* profile = new Profile(BasePath); return profile; } +const char* ProfileManager::GetDefaultUser(const ProfileDeviceKey& deviceKey) +{ + const char* product_str = deviceKey.ProductName.IsEmpty() ? NULL : deviceKey.ProductName.ToCStr(); + const char* serial_str = deviceKey.PrintedSerial.IsEmpty() ? NULL : deviceKey.PrintedSerial.ToCStr(); + + return GetDefaultUser(product_str, serial_str); +} + // Returns the name of the profile that is marked as the current default user. -const char* ProfileManager::GetDefaultUser(const DeviceBase* device) +const char* ProfileManager::GetDefaultUser(const char* product, const char* serial) { const char* tag_names[2] = {"Product", "Serial"}; const char* tags[2]; - String product; - String serial; - if (!GetDeviceTags(device, product, serial)) - return NULL; - - const char* product_str = product.IsEmpty() ? NULL : product.ToCStr(); - const char* serial_str = serial.IsEmpty() ? NULL : serial.ToCStr(); - - if (product_str && serial_str) + if (product && serial) { - tags[0] = product_str; - tags[1] = serial_str; + 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) @@ -717,18 +831,13 @@ const char* ProfileManager::GetDefaultUser(const DeviceBase* device) } //----------------------------------------------------------------------------- -bool ProfileManager::SetDefaultUser(const DeviceBase* device, const char* user) +bool ProfileManager::SetDefaultUser(const ProfileDeviceKey& deviceKey, const char* user) { const char* tag_names[2] = {"Product", "Serial"}; const char* tags[2]; - String product; - String serial; - if (!GetDeviceTags(device, product, serial)) - return NULL; - - const char* product_str = product.IsEmpty() ? NULL : product.ToCStr(); - const char* serial_str = serial.IsEmpty() ? NULL : serial.ToCStr(); + const char* product_str = deviceKey.ProductName.IsEmpty() ? NULL : deviceKey.ProductName.ToCStr(); + const char* serial_str = deviceKey.PrintedSerial.IsEmpty() ? NULL : deviceKey.PrintedSerial.ToCStr(); if (product_str && serial_str) { @@ -760,7 +869,7 @@ Profile* ProfileManager::GetTaggedProfile(const char** tag_names, const char** t if (tagged_data == NULL) return NULL; - Profile* profile = new Profile(); + Profile* profile = new Profile(BasePath); JSON* vals = FindTaggedData(tagged_data, tag_names, tags, num_tags); if (vals) @@ -899,16 +1008,21 @@ bool ProfileManager::SetTaggedProfile(const char** tag_names, const char** tags, if (!found) { // Add the new value + Changed = true; + if (value->Type == JSON_String) vals->AddStringItem(value->Name, value->Value); else if (value->Type == JSON_Bool) - vals->AddBoolItem(value->Name, (value->dValue != 0)); + vals->AddBoolItem(value->Name, ((int)value->dValue != 0)); + else if (value->Type == JSON_Number) + vals->AddNumberItem(value->Name, value->dValue); else if (value->Type == JSON_Array) vals->AddItem(value->Name, value->Copy()); else - vals->AddNumberItem(value->Name, value->dValue); - - Changed = true; + { + OVR_ASSERT(false); + Changed = false; + } } } @@ -916,7 +1030,22 @@ bool ProfileManager::SetTaggedProfile(const char** tag_names, const char** tags, } //----------------------------------------------------------------------------- -Profile* ProfileManager::GetProfile(const DeviceBase* device, const char* user) +Profile* ProfileManager::GetDefaultUserProfile(const ProfileDeviceKey& deviceKey) +{ + const char* userName = GetDefaultUser(deviceKey); + + Profile* profile = GetProfile(deviceKey, userName); + + if (!profile) + { + profile = GetDefaultProfile(deviceKey.HmdType); + } + + return profile; +} + +//----------------------------------------------------------------------------- +Profile* ProfileManager::GetProfile(const ProfileDeviceKey& deviceKey, const char* user) { Lock::Locker lockScope(&ProfileLock); @@ -927,11 +1056,11 @@ Profile* ProfileManager::GetProfile(const DeviceBase* device, const char* user) return NULL; } - Profile* profile = new Profile(); + Profile* profile = new Profile(BasePath); - if (device) + if (deviceKey.Valid) { - if (!profile->LoadDeviceProfile(device) && (user == NULL)) + if (!profile->LoadDeviceProfile(deviceKey) && (user == NULL)) { profile->Release(); return NULL; @@ -940,12 +1069,8 @@ Profile* ProfileManager::GetProfile(const DeviceBase* device, const char* user) if (user) { - String product; - String serial; - GetDeviceTags(device, product, serial); - - const char* product_str = product.IsEmpty() ? NULL : product.ToCStr(); - const char* serial_str = serial.IsEmpty() ? NULL : serial.ToCStr(); + const char* product_str = deviceKey.ProductName.IsEmpty() ? NULL : deviceKey.ProductName.ToCStr(); + const char* serial_str = deviceKey.PrintedSerial.IsEmpty() ? NULL : deviceKey.PrintedSerial.ToCStr(); if (!profile->LoadProfile(ProfileCache.GetPtr(), user, product_str, serial_str)) { @@ -957,6 +1082,7 @@ Profile* ProfileManager::GetProfile(const DeviceBase* device, const char* user) return profile; } + //----------------------------------------------------------------------------- // ***** Profile @@ -1003,13 +1129,12 @@ void Profile::CopyItems(JSON* root, String prefix) } //----------------------------------------------------------------------------- -bool Profile::LoadDeviceFile(unsigned int device_id, const char* serial) +bool Profile::LoadDeviceFile(unsigned int productId, const char* printedSerialNumber) { - if (serial[0] == 0) + if (printedSerialNumber[0] == 0) return false; - String path = GetBaseOVRPath(false); - path += "/Devices.json"; + String path = BasePath + "/Devices.json"; // Load the device profiles Ptr root = *JSON::Load(path); @@ -1029,7 +1154,6 @@ bool Profile::LoadDeviceFile(unsigned int device_id, const char* serial) return false; } - JSON* device = root->GetNextItem(version); while (device) { @@ -1037,8 +1161,8 @@ bool Profile::LoadDeviceFile(unsigned int device_id, const char* serial) { JSON* product_item = device->GetItemByName("ProductID"); JSON* serial_item = device->GetItemByName("Serial"); - if (product_item && serial_item - && (product_item->dValue == device_id) && (serial_item->Value == serial)) + if (product_item && serial_item && + (product_item->dValue == productId) && (serial_item->Value == printedSerialNumber)) { // found the entry for this device so recursively copy all the settings to the profile CopyItems(device, ""); @@ -1052,6 +1176,7 @@ bool Profile::LoadDeviceFile(unsigned int device_id, const char* serial) return false; } +#if 0 //----------------------------------------------------------------------------- static int BCDByte(unsigned int byte) { @@ -1060,51 +1185,32 @@ static int BCDByte(unsigned int byte) int decimal = digit1 * 10 + digit2; return decimal; } +#endif //----------------------------------------------------------------------------- -bool Profile::LoadDeviceProfile(const DeviceBase* device) +bool Profile::LoadDeviceProfile(const ProfileDeviceKey& deviceKey) { bool success = false; - if (device == NULL) - return false; - - SensorDevice* sensor = NULL; - - if (device->GetType() == Device_HMD) - { - // Convert the HMD device to Sensor - sensor = ((HMDDevice*)device)->GetSensor(); - device = sensor; - if (device == NULL) + if (!deviceKey.Valid) return false; - } - - if (device->GetType() == Device_Sensor) - { - SensorDevice* sensor = (SensorDevice*)device; - - SensorInfo sinfo; - sensor->GetDeviceInfo(&sinfo); +#if 0 int dev_major = BCDByte((sinfo.Version >> 8) & 0x00ff); OVR_UNUSED(dev_major); - int dev_minor = BCDByte(sinfo.Version & 0xff); + //int dev_minor = BCDByte(sinfo.Version & 0xff); - if (dev_minor > 18) - { // If the firmware supports hardware stored profiles then grab the device profile + //if (dev_minor > 18) + //{ // If the firmware supports hardware stored profiles then grab the device profile // from the sensor // TBD: Implement this - } - else + //} + //else { +#endif // Grab the model and serial number from the device and use it to access the device // profile file stored on the local machine - success = LoadDeviceFile(sinfo.ProductId, sinfo.SerialNumber); - } - } - - if (sensor) - sensor->Release(); // release the sensor handle + success = LoadDeviceFile(deviceKey.ProductId, deviceKey.PrintedSerial); + //} return success; } @@ -1331,15 +1437,15 @@ int Profile::GetDoubleValues(const char* key, double* values, int num_vals) cons return count; } - else - { - return 0; - } + return 0; } //----------------------------------------------------------------------------- void Profile::SetValue(JSON* val) { + if (val == NULL) + return; + if (val->Type == JSON_Number) SetDoubleValue(val->Name, val->dValue); else if (val->Type == JSON_Bool) @@ -1348,9 +1454,6 @@ void Profile::SetValue(JSON* val) SetValue(val->Name, val->Value); else if (val->Type == JSON_Array) { - if (val == NULL) - return; - // Create a copy of the array JSON* value = val->Copy(); Values.PushBack(value); @@ -1514,4 +1617,11 @@ void Profile::SetDoubleValues(const char* key, const double* vals, int num_vals) value->AddArrayNumber(vals[val_count]); } -} // OVR +//------------------------------------------------------------------------------ +bool Profile::IsDefaultProfile() +{ + return 0 == OVR::String::CompareNoCase("Default", GetValue(OVR_KEY_NAME)); +} + + +} // namespace OVR diff --git a/LibOVR/Src/OVR_Profile.h b/LibOVR/Src/OVR_Profile.h index e34820a..911ad06 100644 --- a/LibOVR/Src/OVR_Profile.h +++ b/LibOVR/Src/OVR_Profile.h @@ -1,6 +1,5 @@ /************************************************************************************ -PublicHeader: OVR.h Filename : OVR_Profile.h Content : Structs and functions for loading and storing device profile settings Created : February 14, 2013 @@ -11,16 +10,16 @@ Notes : can be accomplished in game via the Profile API or by the official Oculus Configuration Utility. -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -33,18 +32,47 @@ limitations under the License. #ifndef OVR_Profile_h #define OVR_Profile_h -#include "OVR_DeviceConstants.h" +#include "OVR_CAPI_Keys.h" + +#include "Sensors/OVR_DeviceConstants.h" #include "Kernel/OVR_String.h" #include "Kernel/OVR_RefCount.h" #include "Kernel/OVR_Array.h" #include "Kernel/OVR_StringHash.h" +#include "Kernel/OVR_System.h" namespace OVR { +class HMDInfo; // Opaque forward declaration class Profile; -class DeviceBase; class JSON; + +// Device key for looking up profiles +struct ProfileDeviceKey +{ + ProfileDeviceKey(const HMDInfo* info); + + // Initialized properly? + bool Valid; + + // The HMD type + HmdTypeEnum HmdType; + + // This is the 12 character serial number printed on the HMD + String PrintedSerial; + + // This is the product name string of the USB sensor device + // Note: It has been modified from the original to remove spaces and strip off "Oculus" + String ProductName; + + // This is the product id from the HID info of the USB sensor device + unsigned ProductId; + + static String SanitizeProductName(String productName); +}; + + // ----------------------------------------------------------------------------- // ***** ProfileManager @@ -64,8 +92,15 @@ class JSON; // { // Retrieve the current profile settings // } // } // Profile will be destroyed and any disk I/O completed when going out of scope -class ProfileManager : public RefCountBase +class ProfileManager : public NewOverrideBase, public SystemSingletonBase { + friend class OVR::SystemSingletonBase; + +protected: + ProfileManager(bool sys_register); + virtual ~ProfileManager(); + virtual void OnSystemDestroy(); + protected: // Synchronize ProfileManager access since it may be accessed from multiple threads, // as it's shared through DeviceManager. @@ -73,34 +108,39 @@ protected: Ptr ProfileCache; bool Changed; String TempBuff; + String BasePath; public: - static ProfileManager* Create(); + // In the service process it is important to set the base path because this cannot be detected automatically + void SetBasePath(String basePath); int GetUserCount(); const char* GetUser(unsigned int index); bool CreateUser(const char* user, const char* name); + bool HasUser(const char* user); bool RemoveUser(const char* user); - const char* GetDefaultUser(const DeviceBase* device); - bool SetDefaultUser(const DeviceBase* device, const char* user); + const char* GetDefaultUser(const ProfileDeviceKey& deviceKey); + bool SetDefaultUser(const ProfileDeviceKey& deviceKey, const char* user); virtual Profile* CreateProfile(); - Profile* GetProfile(const DeviceBase* device, const char* user); - Profile* GetDefaultProfile(const DeviceBase* device); + Profile* GetProfile(const ProfileDeviceKey& deviceKey, const char* user); + Profile* GetDefaultUserProfile(const ProfileDeviceKey& deviceKey); + Profile* GetDefaultProfile(HmdTypeEnum device); Profile* GetTaggedProfile(const char** key_names, const char** keys, int num_keys); bool SetTaggedProfile(const char** key_names, const char** keys, int num_keys, Profile* profile); - bool GetDeviceTags(const DeviceBase* device, String& product, String& serial); - + // Force re-reading the settings + void Read(); + protected: - ProfileManager(); - ~ProfileManager(); - String GetProfilePath(bool create_dir); + // Force writing the settings + void ClearProfileData(); + void Save(); + + String GetProfilePath(); void LoadCache(bool create); - void ClearCache(); void LoadV1Profiles(JSON* v1); - - + const char* GetDefaultUser(const char* product, const char* serial); }; @@ -116,6 +156,7 @@ protected: OVR::Hash ValMap; OVR::Array Values; OVR::String TempVal; + String BasePath; public: ~Profile(); @@ -137,23 +178,26 @@ public: void SetFloatValues(const char* key, const float* vals, int num_vals); void SetDoubleValue(const char* key, double val); void SetDoubleValues(const char* key, const double* vals, int num_vals); + + bool IsDefaultProfile(); bool Close(); protected: - Profile() {}; - + Profile(String basePath) : + BasePath(basePath) + { + } void SetValue(JSON* val); - - static bool LoadProfile(const DeviceBase* device, + static bool LoadProfile(const ProfileDeviceKey& deviceKey, const char* user, Profile** profile); void CopyItems(JSON* root, String prefix); bool LoadDeviceFile(unsigned int device_id, const char* serial); - bool LoadDeviceProfile(const DeviceBase* device); + bool LoadDeviceProfile(const ProfileDeviceKey& deviceKey); bool LoadProfile(JSON* root, const char* user, @@ -165,39 +209,14 @@ protected: const char* device_name, const char* device_serial); - friend class ProfileManager; + friend class WProfileManager; }; -// # defined() check for CAPI compatibility near term that re-defines these -// for now. To be unified. -#if !defined(OVR_KEY_USER) - -#define OVR_KEY_USER "User" -#define OVR_KEY_NAME "Name" -#define OVR_KEY_GENDER "Gender" -#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" -#define OVR_KEY_EYE_HEIGHT "EyeHeight" -#define OVR_KEY_IPD "IPD" -#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" -#define OVR_KEY_EYE_RELIEF_DIAL "EyeReliefDial" -#define OVR_KEY_EYE_TO_NOSE_DISTANCE "EyeToNoseDist" -#define OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE "MaxEyeToPlateDist" -#define OVR_KEY_EYE_CUP "EyeCup" -#define OVR_KEY_CUSTOM_EYE_RENDER "CustomEyeRender" - -#define OVR_DEFAULT_GENDER "Male" -#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.09f -#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.15f -#define OVR_DEFAULT_EYE_RELIEF_DIAL 3 - -#endif // OVR_KEY_USER - +// This path should be passed into the ProfileManager String GetBaseOVRPath(bool create_dir); -} -#endif // OVR_Profile_h \ No newline at end of file +} // namespace OVR + +#endif // OVR_Profile_h diff --git a/LibOVR/Src/OVR_Recording.cpp b/LibOVR/Src/OVR_Recording.cpp deleted file mode 100644 index a2006c8..0000000 --- a/LibOVR/Src/OVR_Recording.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************************ - -Filename : Recording.h -Content : Support for recording sensor + camera data -Created : May 12, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_Math.h" -#include "Kernel/OVR_Array.h" -#include "OVR_DeviceMessages.h" -#include "OVR_Recording.h" - -namespace OVR { namespace Recording { - -// global instance that doesn't do anything -Recorder r; - -}} // OVR::Recording - diff --git a/LibOVR/Src/OVR_Recording.h b/LibOVR/Src/OVR_Recording.h deleted file mode 100644 index fc83270..0000000 --- a/LibOVR/Src/OVR_Recording.h +++ /dev/null @@ -1,83 +0,0 @@ -/************************************************************************************ - -Filename : Recording.h -Content : Support for recording sensor + camera data -Created : March 14, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_Recording_h -#define OVR_Recording_h - -namespace OVR { namespace Recording { - -enum RecordingMode -{ - RecordingOff = 0x0, - RecordForPlayback = 0x1, - RecordForLogging = 0x2 -}; - -}} // OVR::Recording - -#ifdef ENABLE_RECORDING - -#include "Recording/Recording_Recorder.h" - -#else -// If Recording is not enabled, then stub it out - -namespace OVR { - -struct PositionCalibrationReport; -namespace Vision { - class CameraIntrinsics; - class DistortionCoefficients; - class Blob; -}; - -namespace Recording { - -class Recorder -{ -public: - OVR_FORCE_INLINE void RecordCameraParams(const Vision::CameraIntrinsics&, - const Vision::DistortionCoefficients&) { } - OVR_FORCE_INLINE void RecordLedPositions(const Array&) { } - OVR_FORCE_INLINE void RecordUserParams(const Vector3f&, float) { } - OVR_FORCE_INLINE void RecordDeviceIfcVersion(UByte) { } - OVR_FORCE_INLINE void RecordMessage(const Message&) { } - OVR_FORCE_INLINE void RecordCameraFrameUsed(UInt32) { } - OVR_FORCE_INLINE void RecordVisionSuccess(UInt32) { } - template OVR_FORCE_INLINE void LogData(const char*, const T&) { } - OVR_FORCE_INLINE void SetRecordingMode(RecordingMode) { } - OVR_FORCE_INLINE RecordingMode GetRecordingMode() { return RecordingOff; } -}; - -extern Recorder r; - -OVR_FORCE_INLINE Recorder& GetRecorder() { return r; } - -}} // namespace OVR::Recording - -#endif // ENABLE_RECORDING - -#endif // OVR_Recording_h \ No newline at end of file diff --git a/LibOVR/Src/OVR_Sensor2Impl.cpp b/LibOVR/Src/OVR_Sensor2Impl.cpp deleted file mode 100644 index 95d486c..0000000 --- a/LibOVR/Src/OVR_Sensor2Impl.cpp +++ /dev/null @@ -1,1124 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Sensor2Impl.cpp -Content : DK2 sensor device specific implementation. -Created : January 21, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_Sensor2Impl.h" -#include "OVR_SensorImpl_Common.h" -#include "OVR_Sensor2ImplUtil.h" -#include "Kernel/OVR_Alg.h" - -//extern FILE *SF_LOG_fp; - -namespace OVR { - -//------------------------------------------------------------------------------------- -// ***** Oculus Sensor2-specific packet data structures - -enum { - Sensor2_VendorId = Oculus_VendorId, - Sensor2_ProductId = 0x0021, - - Sensor2_BootLoader = 0x1001, - - Sensor2_DefaultReportRate = 1000, // Hz -}; - - -// Messages we care for -enum Tracker2MessageType -{ - Tracker2Message_None = 0, - Tracker2Message_Sensors = 11, - Tracker2Message_Unknown = 0x100, - Tracker2Message_SizeError = 0x101, -}; - - -struct Tracker2Sensors -{ - UInt16 LastCommandID; - UByte NumSamples; - UInt16 RunningSampleCount; // Named 'SampleCount' in the firmware docs. - SInt16 Temperature; - UInt32 SampleTimestamp; - TrackerSample Samples[2]; - SInt16 MagX, MagY, MagZ; - UInt16 FrameCount; - UInt32 FrameTimestamp; - UByte FrameID; - UByte CameraPattern; - UInt16 CameraFrameCount; // Named 'CameraCount' in the firmware docs. - UInt32 CameraTimestamp; - - Tracker2MessageType Decode(const UByte* buffer, int size) - { - if (size < 64) - return Tracker2Message_SizeError; - - LastCommandID = DecodeUInt16(buffer + 1); - NumSamples = buffer[3]; - RunningSampleCount = DecodeUInt16(buffer + 4); - Temperature = DecodeSInt16(buffer + 6); - SampleTimestamp = DecodeUInt32(buffer + 8); - - // Only unpack as many samples as there actually are. - UByte iterationCount = (NumSamples > 1) ? 2 : NumSamples; - - for (UByte i = 0; i < iterationCount; i++) - { - UnpackSensor(buffer + 12 + 16 * i, &Samples[i].AccelX, &Samples[i].AccelY, &Samples[i].AccelZ); - UnpackSensor(buffer + 20 + 16 * i, &Samples[i].GyroX, &Samples[i].GyroY, &Samples[i].GyroZ); - } - - MagX = DecodeSInt16(buffer + 44); - MagY = DecodeSInt16(buffer + 46); - MagZ = DecodeSInt16(buffer + 48); - - FrameCount = DecodeUInt16(buffer + 50); - - FrameTimestamp = DecodeUInt32(buffer + 52); - FrameID = buffer[56]; - CameraPattern = buffer[57]; - CameraFrameCount = DecodeUInt16(buffer + 58); - CameraTimestamp = DecodeUInt32(buffer + 60); - - return Tracker2Message_Sensors; - } -}; - -struct Tracker2Message -{ - Tracker2MessageType Type; - Tracker2Sensors Sensors; -}; - -// Sensor reports data in the following coordinate system: -// Accelerometer: 10^-4 m/s^2; X forward, Y right, Z Down. -// Gyro: 10^-4 rad/s; X positive roll right, Y positive pitch up; Z positive yaw right. - - -// We need to convert it to the following RHS coordinate system: -// X right, Y Up, Z Back (out of screen) -// -Vector3f AccelFromBodyFrameUpdate(const Tracker2Sensors& update, UByte sampleNumber) -{ - const TrackerSample& sample = update.Samples[sampleNumber]; - float ax = (float)sample.AccelX; - float ay = (float)sample.AccelY; - float az = (float)sample.AccelZ; - - return Vector3f(ax, ay, az) * 0.0001f; -} - - -Vector3f MagFromBodyFrameUpdate(const Tracker2Sensors& update) -{ - return Vector3f( (float)update.MagX, (float)update.MagY, (float)update.MagZ) * 0.0001f; -} - -Vector3f EulerFromBodyFrameUpdate(const Tracker2Sensors& update, UByte sampleNumber) -{ - const TrackerSample& sample = update.Samples[sampleNumber]; - float gx = (float)sample.GyroX; - float gy = (float)sample.GyroY; - float gz = (float)sample.GyroZ; - - return Vector3f(gx, gy, gz) * 0.0001f; -} - -bool Sensor2DeviceImpl::decodeTracker2Message(Tracker2Message* message, UByte* buffer, int size) -{ - memset(message, 0, sizeof(Tracker2Message)); - - if (size < 4) - { - message->Type = Tracker2Message_SizeError; - return false; - } - - switch (buffer[0]) - { - case Tracker2Message_Sensors: - message->Type = message->Sensors.Decode(buffer, size); - break; - - default: - message->Type = Tracker2Message_Unknown; - break; - } - - return (message->Type < Tracker2Message_Unknown) && (message->Type != Tracker2Message_None); -} - -//------------------------------------------------------------------------------------- -// ***** Sensor2Device - -Sensor2DeviceImpl::Sensor2DeviceImpl(SensorDeviceCreateDesc* createDesc) - : SensorDeviceImpl(createDesc), - LastNumSamples(0), - LastRunningSampleCount(0), - FullCameraFrameCount(0), - LastCameraTime("C"), - LastFrameTime("F"), - LastSensorTime("S"), - LastFrameTimestamp(0) -{ - // 15 samples ok in min-window for DK2 since it uses microsecond clock. - TimeFilter = SensorTimeFilter(SensorTimeFilter::Settings(15)); - - pCalibration = new SensorCalibration(this); -} - -Sensor2DeviceImpl::~Sensor2DeviceImpl() -{ - delete pCalibration; -} - -void Sensor2DeviceImpl::openDevice() -{ - - // Read the currently configured range from sensor. - SensorRangeImpl sr(SensorRange(), 0); - - if (GetInternalDevice()->GetFeatureReport(sr.Buffer, SensorRangeImpl::PacketSize)) - { - sr.Unpack(); - sr.GetSensorRange(&CurrentRange); - } - - // Read the currently configured calibration from sensor. - SensorFactoryCalibrationImpl sc; - if (GetInternalDevice()->GetFeatureReport(sc.Buffer, SensorFactoryCalibrationImpl::PacketSize)) - { - sc.Unpack(); - AccelCalibrationOffset = sc.AccelOffset; - GyroCalibrationOffset = sc.GyroOffset; - AccelCalibrationMatrix = sc.AccelMatrix; - GyroCalibrationMatrix = sc.GyroMatrix; - CalibrationTemperature = sc.Temperature; - } - - // If the sensor has "DisplayInfo" data, use HMD coordinate frame by default. - SensorDisplayInfoImpl displayInfo; - if (GetInternalDevice()->GetFeatureReport(displayInfo.Buffer, SensorDisplayInfoImpl::PacketSize)) - { - displayInfo.Unpack(); - Coordinates = (displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) ? - Coord_HMD : Coord_Sensor; - } - Coordinates = Coord_HMD; // TODO temporary to force it behave - - // Read/Apply sensor config. - setCoordinateFrame(Coordinates); - setReportRate(Sensor2_DefaultReportRate); - setOnboardCalibrationEnabled(false); - - // Must send DK2 keep-alive. Set Keep-alive at 10 seconds. - KeepAliveMuxReport keepAlive; - keepAlive.CommandId = 0; - keepAlive.INReport = 11; - keepAlive.Interval = 10 * 1000; - - // Device creation is done from background thread so we don't need to add this to the command queue. - KeepAliveMuxImpl keepAliveImpl(keepAlive); - GetInternalDevice()->SetFeatureReport(keepAliveImpl.Buffer, KeepAliveMuxImpl::PacketSize); - - // Read the temperature data from the device - pCalibration->Initialize(); -} - -bool Sensor2DeviceImpl::SetTrackingReport(const TrackingReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setTrackingReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setTrackingReport(const TrackingReport& data) -{ - TrackingImpl ci(data); - return GetInternalDevice()->SetFeatureReport(ci.Buffer, TrackingImpl::PacketSize); -} - -bool Sensor2DeviceImpl::GetTrackingReport(TrackingReport* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getTrackingReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getTrackingReport(TrackingReport* data) -{ - TrackingImpl ci; - if (GetInternalDevice()->GetFeatureReport(ci.Buffer, TrackingImpl::PacketSize)) - { - ci.Unpack(); - *data = ci.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::SetDisplayReport(const DisplayReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setDisplayReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setDisplayReport(const DisplayReport& data) -{ - DisplayImpl di(data); - return GetInternalDevice()->SetFeatureReport(di.Buffer, DisplayImpl::PacketSize); -} - -bool Sensor2DeviceImpl::GetDisplayReport(DisplayReport* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getDisplayReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getDisplayReport(DisplayReport* data) -{ - DisplayImpl di; - if (GetInternalDevice()->GetFeatureReport(di.Buffer, DisplayImpl::PacketSize)) - { - di.Unpack(); - *data = di.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::SetMagCalibrationReport(const MagCalibrationReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setMagCalibrationReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setMagCalibrationReport(const MagCalibrationReport& data) -{ - MagCalibrationImpl mci(data); - return GetInternalDevice()->SetFeatureReport(mci.Buffer, MagCalibrationImpl::PacketSize); -} - -bool Sensor2DeviceImpl::GetMagCalibrationReport(MagCalibrationReport* data) -{ - // direct call if we are already on the device manager thread - if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId()) - { - return getMagCalibrationReport(data); - } - - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getMagCalibrationReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getMagCalibrationReport(MagCalibrationReport* data) -{ - MagCalibrationImpl mci; - if (GetInternalDevice()->GetFeatureReport(mci.Buffer, MagCalibrationImpl::PacketSize)) - { - mci.Unpack(); - *data = mci.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::SetPositionCalibrationReport(const PositionCalibrationReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setPositionCalibrationReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setPositionCalibrationReport(const PositionCalibrationReport& data) -{ - UByte version = GetDeviceInterfaceVersion(); - if (version < 5) - { - PositionCalibrationImpl_Pre5 pci(data); - return GetInternalDevice()->SetFeatureReport(pci.Buffer, PositionCalibrationImpl_Pre5::PacketSize); - } - - PositionCalibrationImpl pci(data); - return GetInternalDevice()->SetFeatureReport(pci.Buffer, PositionCalibrationImpl::PacketSize); -} - -bool Sensor2DeviceImpl::getPositionCalibrationReport(PositionCalibrationReport* data) -{ - UByte version = GetDeviceInterfaceVersion(); - if (version < 5) - { - PositionCalibrationImpl_Pre5 pci; - if (GetInternalDevice()->GetFeatureReport(pci.Buffer, PositionCalibrationImpl_Pre5::PacketSize)) - { - pci.Unpack(); - *data = pci.Settings; - return true; - } - - return false; - } - - PositionCalibrationImpl pci; - if (GetInternalDevice()->GetFeatureReport(pci.Buffer, PositionCalibrationImpl::PacketSize)) - { - pci.Unpack(); - *data = pci.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::GetAllPositionCalibrationReports(Array* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getAllPositionCalibrationReports, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getAllPositionCalibrationReports(Array* data) -{ - PositionCalibrationReport pc; - bool result = getPositionCalibrationReport(&pc); - if (!result) - return false; - - int positions = pc.NumPositions; - data->Clear(); - data->Resize(positions); - - for (int i = 0; i < positions; i++) - { - result = getPositionCalibrationReport(&pc); - if (!result) - return false; - OVR_ASSERT(pc.NumPositions == positions); - - (*data)[pc.PositionIndex] = pc; - // IMU should be the last one - OVR_ASSERT(pc.PositionType == (pc.PositionIndex == positions - 1) ? - PositionCalibrationReport::PositionType_IMU : PositionCalibrationReport::PositionType_LED); - } - return true; -} - -bool Sensor2DeviceImpl::SetCustomPatternReport(const CustomPatternReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setCustomPatternReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setCustomPatternReport(const CustomPatternReport& data) -{ - CustomPatternImpl cpi(data); - return GetInternalDevice()->SetFeatureReport(cpi.Buffer, CustomPatternImpl::PacketSize); -} - -bool Sensor2DeviceImpl::GetCustomPatternReport(CustomPatternReport* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getCustomPatternReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getCustomPatternReport(CustomPatternReport* data) -{ - CustomPatternImpl cpi; - if (GetInternalDevice()->GetFeatureReport(cpi.Buffer, CustomPatternImpl::PacketSize)) - { - cpi.Unpack(); - *data = cpi.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::SetManufacturingReport(const ManufacturingReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setManufacturingReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setManufacturingReport(const ManufacturingReport& data) -{ - ManufacturingImpl mi(data); - return GetInternalDevice()->SetFeatureReport(mi.Buffer, ManufacturingImpl::PacketSize); -} - -bool Sensor2DeviceImpl::GetManufacturingReport(ManufacturingReport* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getManufacturingReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getManufacturingReport(ManufacturingReport* data) -{ - ManufacturingImpl mi; - if (GetInternalDevice()->GetFeatureReport(mi.Buffer, ManufacturingImpl::PacketSize)) - { - mi.Unpack(); - *data = mi.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::SetLensDistortionReport(const LensDistortionReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setLensDistortionReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setLensDistortionReport(const LensDistortionReport& data) -{ - LensDistortionImpl ui(data); - return GetInternalDevice()->SetFeatureReport(ui.Buffer, LensDistortionImpl::PacketSize); -} - -bool Sensor2DeviceImpl::GetLensDistortionReport(LensDistortionReport* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getLensDistortionReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getLensDistortionReport(LensDistortionReport* data) -{ - LensDistortionImpl ui; - if (GetInternalDevice()->GetFeatureReport(ui.Buffer, LensDistortionImpl::PacketSize)) - { - ui.Unpack(); - *data = ui.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::SetUUIDReport(const UUIDReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setUUIDReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setUUIDReport(const UUIDReport& data) -{ - UUIDImpl ui(data); - return GetInternalDevice()->SetFeatureReport(ui.Buffer, UUIDImpl::PacketSize); -} - -bool Sensor2DeviceImpl::GetUUIDReport(UUIDReport* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getUUIDReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getUUIDReport(UUIDReport* data) -{ - UUIDImpl ui; - if (GetInternalDevice()->GetFeatureReport(ui.Buffer, UUIDImpl::PacketSize)) - { - ui.Unpack(); - *data = ui.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::SetKeepAliveMuxReport(const KeepAliveMuxReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setKeepAliveMuxReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setKeepAliveMuxReport(const KeepAliveMuxReport& data) -{ - KeepAliveMuxImpl kami(data); - return GetInternalDevice()->SetFeatureReport(kami.Buffer, KeepAliveMuxImpl::PacketSize); -} - -bool Sensor2DeviceImpl::GetKeepAliveMuxReport(KeepAliveMuxReport* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getKeepAliveMuxReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getKeepAliveMuxReport(KeepAliveMuxReport* data) -{ - KeepAliveMuxImpl kami; - if (GetInternalDevice()->GetFeatureReport(kami.Buffer, KeepAliveMuxImpl::PacketSize)) - { - kami.Unpack(); - *data = kami.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::SetTemperatureReport(const TemperatureReport& data) -{ - // direct call if we are already on the device manager thread - if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId()) - { - return setTemperatureReport(data); - } - - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setTemperatureReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::setTemperatureReport(const TemperatureReport& data) -{ - TemperatureImpl ti(data); - return GetInternalDevice()->SetFeatureReport(ti.Buffer, TemperatureImpl::PacketSize); -} - -bool Sensor2DeviceImpl::getTemperatureReport(TemperatureReport* data) -{ - TemperatureImpl ti; - if (GetInternalDevice()->GetFeatureReport(ti.Buffer, TemperatureImpl::PacketSize)) - { - ti.Unpack(); - *data = ti.Settings; - return true; - } - - return false; -} - -bool Sensor2DeviceImpl::GetAllTemperatureReports(Array >* data) -{ - // direct call if we are already on the device manager thread - if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId()) - { - return getAllTemperatureReports(data); - } - - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getAllTemperatureReports, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getAllTemperatureReports(Array >* data) -{ - TemperatureReport t; - bool result = getTemperatureReport(&t); - if (!result) - return false; - - int bins = t.NumBins, samples = t.NumSamples; - data->Clear(); - data->Resize(bins); - for (int i = 0; i < bins; i++) - (*data)[i].Resize(samples); - - for (int i = 0; i < bins; i++) - for (int j = 0; j < samples; j++) - { - result = getTemperatureReport(&t); - if (!result) - return false; - OVR_ASSERT(t.NumBins == bins && t.NumSamples == samples); - - (*data)[t.Bin][t.Sample] = t; - } - return true; -} - -bool Sensor2DeviceImpl::GetGyroOffsetReport(GyroOffsetReport* data) -{ - // direct call if we are already on the device manager thread - if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId()) - { - return getGyroOffsetReport(data); - } - - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getGyroOffsetReport, &result, data)) - { - return false; - } - - return result; -} - -bool Sensor2DeviceImpl::getGyroOffsetReport(GyroOffsetReport* data) -{ - GyroOffsetImpl goi; - if (GetInternalDevice()->GetFeatureReport(goi.Buffer, GyroOffsetImpl::PacketSize)) - { - goi.Unpack(); - *data = goi.Settings; - return true; - } - - return false; -} - -void Sensor2DeviceImpl::onTrackerMessage(Tracker2Message* message) -{ - if (message->Type != Tracker2Message_Sensors) - return; - - const float sampleIntervalTimeUnit = (1.0f / 1000.f); - double scaledSampleIntervalTimeUnit = sampleIntervalTimeUnit; - Tracker2Sensors& s = message->Sensors; - - double absoluteTimeSeconds = 0.0; - - if (SequenceValid) - { - UInt32 runningSampleCountDelta; - - if (s.RunningSampleCount < LastRunningSampleCount) - { - // The running sample count on the device rolled around the 16 bit counter - // (expect to happen about once per minute), so RunningSampleCount - // needs a high word increment. - runningSampleCountDelta = ((((int)s.RunningSampleCount) + 0x10000) - (int)LastRunningSampleCount); - } - else - { - runningSampleCountDelta = (s.RunningSampleCount - LastRunningSampleCount); - } - - absoluteTimeSeconds = LastSensorTime.TimeSeconds; - scaledSampleIntervalTimeUnit = TimeFilter.ScaleTimeUnit(sampleIntervalTimeUnit); - - // If we missed a small number of samples, replicate the last sample. - if ((runningSampleCountDelta > LastNumSamples) && (runningSampleCountDelta <= 254)) - { - if (HandlerRef.HasHandlers()) - { - MessageBodyFrame sensors(this); - - sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - s.NumSamples * scaledSampleIntervalTimeUnit; - sensors.TimeDelta = (float) ((runningSampleCountDelta - LastNumSamples) * scaledSampleIntervalTimeUnit); - sensors.Acceleration = LastAcceleration; - sensors.RotationRate = LastRotationRate; - sensors.MagneticField = LastMagneticField; - sensors.Temperature = LastTemperature; - - pCalibration->Apply(sensors); - HandlerRef.Call(sensors); - } - } - } - else - { - LastAcceleration = Vector3f(0); - LastRotationRate = Vector3f(0); - LastMagneticField= Vector3f(0); - LastTemperature = 0; - SequenceValid = true; - } - - LastNumSamples = s.NumSamples; - LastRunningSampleCount = s.RunningSampleCount; - - if (HandlerRef.HasHandlers()) - { - MessageBodyFrame sensors(this); - UByte iterations = s.NumSamples; - - if (s.NumSamples > 2) - { - iterations = 2; - sensors.TimeDelta = (float) ((s.NumSamples - 1) * scaledSampleIntervalTimeUnit); - } - else - { - sensors.TimeDelta = (float) scaledSampleIntervalTimeUnit; - } - - for (UByte i = 0; i < iterations; i++) - { - sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - ( iterations - 1 - i ) * scaledSampleIntervalTimeUnit; - sensors.Acceleration = AccelFromBodyFrameUpdate(s, i); - sensors.RotationRate = EulerFromBodyFrameUpdate(s, i); - sensors.MagneticField= MagFromBodyFrameUpdate(s); - sensors.Temperature = s.Temperature * 0.01f; - - pCalibration->Apply(sensors); - HandlerRef.Call(sensors); - - // TimeDelta for the last two sample is always fixed. - sensors.TimeDelta = (float) scaledSampleIntervalTimeUnit; - } - - // Send pixel read only when frame timestamp changes. - if (LastFrameTimestamp != s.FrameTimestamp) - { - MessagePixelRead pixelRead(this); - // Prepare message for pixel read - pixelRead.PixelReadValue = s.FrameID; - pixelRead.RawFrameTime = s.FrameTimestamp; - pixelRead.RawSensorTime = s.SampleTimestamp; - pixelRead.SensorTimeSeconds = LastSensorTime.TimeSeconds; - pixelRead.FrameTimeSeconds = LastFrameTime.TimeSeconds; - - HandlerRef.Call(pixelRead); - LastFrameTimestamp = s.FrameTimestamp; - } - - UInt16 lowFrameCount = (UInt16) FullCameraFrameCount; - // Send message only when frame counter changes - if (lowFrameCount != s.CameraFrameCount) - { - // check for the rollover in the counter - if (s.CameraFrameCount < lowFrameCount) - FullCameraFrameCount += 0x10000; - // update the low bits - FullCameraFrameCount = (FullCameraFrameCount & ~0xFFFF) | s.CameraFrameCount; - - MessageExposureFrame vision(this); - vision.CameraPattern = s.CameraPattern; - vision.CameraFrameCount = FullCameraFrameCount; - vision.CameraTimeSeconds = LastCameraTime.TimeSeconds; - - HandlerRef.Call(vision); - } - - LastAcceleration = sensors.Acceleration; - LastRotationRate = sensors.RotationRate; - LastMagneticField= sensors.MagneticField; - LastTemperature = sensors.Temperature; - - //LastPixelRead = pixelRead.PixelReadValue; - //LastPixelReadTimeStamp = LastFrameTime; - } - else - { - if (s.NumSamples != 0) - { - UByte i = (s.NumSamples > 1) ? 1 : 0; - LastAcceleration = AccelFromBodyFrameUpdate(s, i); - LastRotationRate = EulerFromBodyFrameUpdate(s, i); - LastMagneticField = MagFromBodyFrameUpdate(s); - LastTemperature = s.Temperature * 0.01f; - } - } -} - -// Helper function to handle wrap-around of timestamps from Tracker2Message and convert them -// to system time. -// - Any timestamps that didn't increment keep their old system time. -// - This is a bit tricky since we don't know which one of timestamps has most recent time. -// - The first timestamp must be the IMU one; we assume that others can't be too much ahead of it - -void UpdateDK2Timestamps(SensorTimeFilter& tf, - SensorTimestampMapping** timestamps, UInt32 *rawValues, int count) -{ - int updateIndices[4]; - int updateCount = 0; - int i; - double now = Timer::GetSeconds(); - - OVR_ASSERT(count <= sizeof(updateIndices)/sizeof(int)); - - // Update timestamp wrapping for any values that changed. - for (i = 0; i < count; i++) - { - UInt32 lowMks = (UInt32)timestamps[i]->TimestampMks; // Low 32-bits are raw old timestamp. - - if (rawValues[i] != lowMks) - { - if (i == 0) - { - // Only check for rollover in the IMU timestamp - if (rawValues[i] < lowMks) - { - LogText("Timestamp %d rollover, was: %u, now: %u\n", i, lowMks, rawValues[i]); - timestamps[i]->TimestampMks += 0x100000000; - } - // Update the low bits - timestamps[i]->TimestampMks = (timestamps[i]->TimestampMks & 0xFFFFFFFF00000000) | rawValues[i]; - } - else - { - // Take the high bits from the main timestamp first (not a typo in the first argument!) - timestamps[i]->TimestampMks = - (timestamps[0]->TimestampMks & 0xFFFFFFFF00000000) | rawValues[i]; - // Now force it into the reasonable range around the expanded main timestamp - if (timestamps[i]->TimestampMks > timestamps[0]->TimestampMks + 0x1000000) - timestamps[i]->TimestampMks -= 0x100000000; - else if (timestamps[i]->TimestampMks + 0x100000000 < timestamps[0]->TimestampMks + 0x1000000) - timestamps[i]->TimestampMks += 0x100000000; - } - - updateIndices[updateCount] = i; - updateCount++; - } - } - - - // TBD: Simplify. Update indices should no longer be needed with new TimeFilter accepting - // previous values. - // We might want to have multi-element checking time roll-over. - - static const double mksToSec = 1.0 / 1000000.0; - - for (int i = 0; i < updateCount; i++) - { - SensorTimestampMapping& ts = *timestamps[updateIndices[i]]; - - ts.TimeSeconds = tf.SampleToSystemTime(((double)ts.TimestampMks) * mksToSec, - now, ts.TimeSeconds, ts.DebugTag); - } -} - - -void Sensor2DeviceImpl::OnInputReport(UByte* pData, UInt32 length) -{ - bool processed = false; - if (!processed) - { - Tracker2Message message; - if (decodeTracker2Message(&message, pData, length)) - { - processed = true; - - // Process microsecond timestamps from DK2 tracker. - // Mapped and raw values must correspond to one another in each array. - // IMU timestamp must be the first one! - SensorTimestampMapping* tsMaps[3] = - { - &LastSensorTime, - &LastCameraTime, - &LastFrameTime - }; - UInt32 tsRawMks[3] = - { - message.Sensors.SampleTimestamp, - message.Sensors.CameraTimestamp, - message.Sensors.FrameTimestamp - }; - // Handle wrap-around and convert samples to system time for any samples that changed. - UpdateDK2Timestamps(TimeFilter, tsMaps, tsRawMks, sizeof(tsRawMks)/sizeof(tsRawMks[0])); - - onTrackerMessage(&message); - - /* - if (SF_LOG_fp) - { - static UInt32 lastFrameTs = 0; - static UInt32 lastCameraTs = 0; - - if ((lastFrameTs != message.Sensors.FrameTimestamp) || - (lastCameraTs = message.Sensors.CameraTimestamp)) - fprintf(SF_LOG_fp, "msg cameraTs: 0x%X frameTs: 0x%X sensorTs: 0x%X\n", - message.Sensors.CameraTimestamp, message.Sensors.FrameTimestamp, - message.Sensors.SampleTimestamp); - - lastFrameTs = message.Sensors.FrameTimestamp; - lastCameraTs = message.Sensors.CameraTimestamp; - } - */ - -#if 0 - // Checks for DK2 firmware bug. - static unsigned SLastSampleTime = 0; - if ((SLastSampleTime > message.Sensors.SampleTimestamp) && message.Sensors.SampleTimestamp > 1000000 ) - { - fprintf(SF_LOG_fp, "*** Sample Timestamp Wrap! ***\n"); - OVR_ASSERT (SLastSampleTime <= message.Sensors.SampleTimestamp); - } - SLastSampleTime = message.Sensors.SampleTimestamp; - - static unsigned SLastCameraTime = 0; - if ((SLastCameraTime > message.Sensors.CameraTimestamp) && message.Sensors.CameraTimestamp > 1000000 ) - { - fprintf(SF_LOG_fp, "*** Camera Timestamp Wrap! ***\n"); - OVR_ASSERT (SLastCameraTime <= message.Sensors.CameraTimestamp); - } - SLastCameraTime = message.Sensors.CameraTimestamp; - - static unsigned SLastFrameTime = 0; - if ((SLastFrameTime > message.Sensors.FrameTimestamp) && message.Sensors.FrameTimestamp > 1000000 ) - { - fprintf(SF_LOG_fp, "*** Frame Timestamp Wrap! ***\n"); - OVR_ASSERT (SLastFrameTime <= message.Sensors.FrameTimestamp); - } - SLastFrameTime = message.Sensors.FrameTimestamp; -#endif - } - } -} - -double Sensor2DeviceImpl::OnTicks(double tickSeconds) -{ - - if (tickSeconds >= NextKeepAliveTickSeconds) - { - // Must send DK2 keep-alive. Set Keep-alive at 10 seconds. - KeepAliveMuxReport keepAlive; - keepAlive.CommandId = 0; - keepAlive.INReport = 11; - keepAlive.Interval = 10 * 1000; - - // Device creation is done from background thread so we don't need to add this to the command queue. - KeepAliveMuxImpl keepAliveImpl(keepAlive); - GetInternalDevice()->SetFeatureReport(keepAliveImpl.Buffer, KeepAliveMuxImpl::PacketSize); - - // Emit keep-alive every few seconds. - double keepAliveDelta = 3.0; // Use 3-second interval. - NextKeepAliveTickSeconds = tickSeconds + keepAliveDelta; - } - return NextKeepAliveTickSeconds - tickSeconds; -} - -/* -// TBD: don't report calibration for now, until we figure out the logic between camera and mag yaw correction -bool Sensor2DeviceImpl::IsMagCalibrated() -{ - return pCalibration->IsMagCalibrated(); -} -*/ - -} // namespace OVR diff --git a/LibOVR/Src/OVR_Sensor2Impl.h b/LibOVR/Src/OVR_Sensor2Impl.h deleted file mode 100644 index 4555eed..0000000 --- a/LibOVR/Src/OVR_Sensor2Impl.h +++ /dev/null @@ -1,153 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Sensor2Impl.h -Content : DK2 sensor device specific implementation. -Created : January 21, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_Sensor2Impl_h -#define OVR_Sensor2Impl_h - -#include "OVR_SensorImpl.h" -#include "OVR_SensorCalibration.h" - -namespace OVR { - -struct Tracker2Message; - -//------------------------------------------------------------------------------------- -// Used to convert DK2 Mks timestamps to system TimeSeconds -struct SensorTimestampMapping -{ - UInt64 TimestampMks; - double TimeSeconds; - const char* DebugTag; - - SensorTimestampMapping(const char* debugTag) - : TimestampMks(0), TimeSeconds(0.0), DebugTag(debugTag) { } -}; - -//------------------------------------------------------------------------------------- -// ***** OVR::Sensor2DeviceImpl - -// Oculus Sensor2 interface. -class Sensor2DeviceImpl : public SensorDeviceImpl -{ -public: - Sensor2DeviceImpl(SensorDeviceCreateDesc* createDesc); - ~Sensor2DeviceImpl(); - - // HIDDevice::Notifier interface. - virtual void OnInputReport(UByte* pData, UInt32 length); - virtual double OnTicks(double tickSeconds); - - // Get/set feature reports added for DK2. See 'DK2 Firmware Specification' document details. - virtual bool SetTrackingReport(const TrackingReport& data); - virtual bool GetTrackingReport(TrackingReport* data); - - virtual bool SetDisplayReport(const DisplayReport& data); - virtual bool GetDisplayReport(DisplayReport* data); - - virtual bool SetMagCalibrationReport(const MagCalibrationReport& data); - virtual bool GetMagCalibrationReport(MagCalibrationReport* data); - - virtual bool SetPositionCalibrationReport(const PositionCalibrationReport& data); - virtual bool GetAllPositionCalibrationReports(Array* data); - - virtual bool SetCustomPatternReport(const CustomPatternReport& data); - virtual bool GetCustomPatternReport(CustomPatternReport* data); - - virtual bool SetKeepAliveMuxReport(const KeepAliveMuxReport& data); - virtual bool GetKeepAliveMuxReport(KeepAliveMuxReport* data); - - virtual bool SetManufacturingReport(const ManufacturingReport& data); - virtual bool GetManufacturingReport(ManufacturingReport* data); - - virtual bool SetUUIDReport(const UUIDReport& data); - virtual bool GetUUIDReport(UUIDReport* data); - - virtual bool SetTemperatureReport(const TemperatureReport& data); - virtual bool GetAllTemperatureReports(Array >*); - - virtual bool GetGyroOffsetReport(GyroOffsetReport* data); - - virtual bool SetLensDistortionReport(const LensDistortionReport& data); - virtual bool GetLensDistortionReport(LensDistortionReport* data); - -protected: - virtual void openDevice(); - - bool decodeTracker2Message(Tracker2Message* message, UByte* buffer, int size); - - bool setTrackingReport(const TrackingReport& data); - bool getTrackingReport(TrackingReport* data); - - bool setDisplayReport(const DisplayReport& data); - bool getDisplayReport(DisplayReport* data); - - bool setMagCalibrationReport(const MagCalibrationReport& data); - bool getMagCalibrationReport(MagCalibrationReport* data); - - bool setPositionCalibrationReport(const PositionCalibrationReport& data); - bool getPositionCalibrationReport(PositionCalibrationReport* data); - bool getAllPositionCalibrationReports(Array* data); - - bool setCustomPatternReport(const CustomPatternReport& data); - bool getCustomPatternReport(CustomPatternReport* data); - - bool setKeepAliveMuxReport(const KeepAliveMuxReport& data); - bool getKeepAliveMuxReport(KeepAliveMuxReport* data); - - bool setManufacturingReport(const ManufacturingReport& data); - bool getManufacturingReport(ManufacturingReport* data); - - bool setUUIDReport(const UUIDReport& data); - bool getUUIDReport(UUIDReport* data); - - bool setTemperatureReport(const TemperatureReport& data); - bool getTemperatureReport(TemperatureReport* data); - bool getAllTemperatureReports(Array >*); - - bool getGyroOffsetReport(GyroOffsetReport* data); - - bool setLensDistortionReport(const LensDistortionReport& data); - bool getLensDistortionReport(LensDistortionReport* data); - - // Called for decoded messages - void onTrackerMessage(Tracker2Message* message); - - UByte LastNumSamples; - UInt16 LastRunningSampleCount; - UInt32 FullCameraFrameCount; - - SensorTimestampMapping LastCameraTime; - SensorTimestampMapping LastFrameTime; - SensorTimestampMapping LastSensorTime; - // Record last frame timestamp to know when to send pixelRead messages. - UInt32 LastFrameTimestamp; - - SensorCalibration *pCalibration; -}; - -} // namespace OVR - -#endif // OVR_Sensor2Impl_h diff --git a/LibOVR/Src/OVR_Sensor2ImplUtil.h b/LibOVR/Src/OVR_Sensor2ImplUtil.h deleted file mode 100644 index 91b2195..0000000 --- a/LibOVR/Src/OVR_Sensor2ImplUtil.h +++ /dev/null @@ -1,676 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Sensor2ImplUtil.h -Content : DK2 sensor device feature report utils. -Created : January 27, 2014 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_Sensor2ImplUtil_h -#define OVR_Sensor2ImplUtil_h - -#include "OVR_Device.h" -#include "OVR_SensorImpl_Common.h" -#include "Kernel/OVR_Alg.h" - -namespace OVR { - -using namespace Alg; - -// Tracking feature report. -struct TrackingImpl -{ - enum { PacketSize = 13 }; - UByte Buffer[PacketSize]; - - TrackingReport Settings; - - TrackingImpl() - { - for (int i=0; i> 4) & 0x02); - Settings.UseRolling = (Buffer[4] & 0x40) != 0; - Settings.ReverseRolling = (Buffer[4] & 0x80) != 0; - Settings.HighBrightness = (Buffer[5] & 0x01) != 0; - Settings.SelfRefresh = (Buffer[5] & 0x02) != 0; - Settings.ReadPixel = (Buffer[5] & 0x04) != 0; - Settings.DirectPentile = (Buffer[5] & 0x08) != 0; - Settings.Persistence = DecodeUInt16(Buffer+8); - Settings.LightingOffset = DecodeUInt16(Buffer+10); - Settings.PixelSettle = DecodeUInt16(Buffer+12); - Settings.TotalRows = DecodeUInt16(Buffer+14); - } -}; - -// MagCalibration feature report. -struct MagCalibrationImpl -{ - enum { PacketSize = 52 }; - UByte Buffer[PacketSize]; - - MagCalibrationReport Settings; - - MagCalibrationImpl() - { - memset(Buffer, 0, sizeof(Buffer)); - Buffer[0] = 14; - } - - MagCalibrationImpl(const MagCalibrationReport& settings) - : Settings(settings) - { - Pack(); - } - - void Pack() - { - Buffer[0] = 14; - EncodeUInt16(Buffer+1, Settings.CommandId); - Buffer[3] = Settings.Version; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 4; j++) - { - SInt32 value = SInt32(Settings.Calibration.M[i][j] * 1e4f); - EncodeSInt32(Buffer + 4 + 4 * (4 * i + j), value); - } - } - - void Unpack() - { - Settings.CommandId = DecodeUInt16(Buffer+1); - Settings.Version = Buffer[3]; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 4; j++) - { - SInt32 value = DecodeSInt32(Buffer + 4 + 4 * (4 * i + j)); - Settings.Calibration.M[i][j] = (float)value * 1e-4f; - } - } -}; - -//------------------------------------------------------------------------------------- -// PositionCalibration feature report. -// - Sensor interface versions before 5 do not support Normal and Rotation. - -struct PositionCalibrationImpl -{ - enum { PacketSize = 30 }; - UByte Buffer[PacketSize]; - - PositionCalibrationReport Settings; - - PositionCalibrationImpl() - { - for (int i=0; i> 8); - Buffer[3] = UByte(Settings.Version); - - Vector3d offset = Settings.Offset * 1e4; - PackSensor(Buffer + 4, (SInt32) offset.x, (SInt32) offset.y, (SInt32) offset.z); - - EncodeSInt16(Buffer + 16, SInt16(Settings.Temperature * 1e2)); - } - - void Unpack() - { - Settings.CommandId = DecodeUInt16(Buffer + 1); - Settings.Version = GyroOffsetReport::VersionEnum(Buffer[3]); - - SInt32 x, y, z; - UnpackSensor(Buffer + 4, &x, &y, &z); - Settings.Offset = Vector3d(x, y, z) * 1e-4f; - - Settings.Temperature = DecodeSInt16(Buffer + 16) * 1e-2; - } -}; - -} // namespace OVR - -#endif // OVR_Sensor2ImplUtil_h diff --git a/LibOVR/Src/OVR_SensorCalibration.cpp b/LibOVR/Src/OVR_SensorCalibration.cpp deleted file mode 100644 index 94fbb27..0000000 --- a/LibOVR/Src/OVR_SensorCalibration.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SensorCalibration.cpp -Content : Calibration data implementation for the IMU messages -Created : January 28, 2014 -Authors : Max Katsev - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorCalibration.h" -#include "Kernel/OVR_Log.h" -#include "Kernel/OVR_Threads.h" -#include - -namespace OVR { - -using namespace Alg; - -const UByte VERSION = 2; -const UByte MAX_COMPAT_VERSION = 15; - -SensorCalibration::SensorCalibration(SensorDevice* pSensor) - : MagCalibrated(false), GyroFilter(6000), GyroAutoTemperature(0) -{ - this->pSensor = pSensor; -}; - -void SensorCalibration::Initialize() -{ - // read factory calibration - pSensor->GetFactoryCalibration(&AccelOffset, &GyroAutoOffset, &AccelMatrix, &GyroMatrix, &GyroAutoTemperature); - - // if the headset has an autocalibrated offset, prefer it over the factory defaults - GyroOffsetReport gyroReport; - bool result = pSensor->GetGyroOffsetReport(&gyroReport); - if (result && gyroReport.Version != GyroOffsetReport::Version_NoOffset) - { - GyroAutoOffset = (Vector3f) gyroReport.Offset; - GyroAutoTemperature = (float) gyroReport.Temperature; - } - - // read the temperature tables and prepare the interpolation structures - result = pSensor->GetAllTemperatureReports(&TemperatureReports); - OVR_ASSERT(result); - for (int i = 0; i < 3; i++) - Interpolators[i].Initialize(TemperatureReports, i); - - // read the mag calibration - MagCalibrationReport report; - result = pSensor->GetMagCalibrationReport(&report); - MagCalibrated = result && report.Version > 0; - MagMatrix = report.Calibration; - if (!MagCalibrated) - { - // OVR_ASSERT(false); - LogError("Magnetometer calibration not found!\n"); - } -} - -void SensorCalibration::DebugPrintLocalTemperatureTable() -{ - LogText("TemperatureReports:\n"); - for (int i = 0; i < (int)TemperatureReports.GetSize(); i++) - { - for (int j = 0; j < (int)TemperatureReports[i].GetSize(); j++) - { - TemperatureReport& tr = TemperatureReports[i][j]; - - LogText("[%d][%d]: Version=%3d, Bin=%d/%d, " - "Sample=%d/%d, TargetTemp=%3.1lf, " - "ActualTemp=%4.1lf, " - "Offset=(%7.2lf, %7.2lf, %7.2lf), " - "Time=%d\n", i, j, tr.Version, - tr.Bin, tr.NumBins, - tr.Sample, tr.NumSamples, - tr.TargetTemperature, - tr.ActualTemperature, - tr.Offset.x, tr.Offset.y, tr.Offset.z, - tr.Time); - } - } -} - -void SensorCalibration::DebugClearHeadsetTemperatureReports() -{ - OVR_ASSERT(pSensor != NULL); - - bool result; - - Array > temperatureReports; - pSensor->GetAllTemperatureReports(&temperatureReports); - - OVR_ASSERT(temperatureReports.GetSize() > 0); - OVR_ASSERT(temperatureReports[0].GetSize() > 0); - - TemperatureReport& tr = TemperatureReports[0][0]; - - tr.ActualTemperature = 0.0; - tr.Time = 0; - tr.Version = 0; - tr.Offset.x = tr.Offset.y = tr.Offset.z = 0.0; - - for (UByte i = 0; i < tr.NumBins; i++) - { - tr.Bin = i; - - for (UByte j = 0; j < tr.NumSamples; j++) - { - tr.Sample = j; - - result = pSensor->SetTemperatureReport(tr); - OVR_ASSERT(result); - - // Need to wait for the tracker board to finish writing to eeprom. - Thread::MSleep(50); - } - } -} - -void SensorCalibration::Apply(MessageBodyFrame& msg) -{ - AutocalibrateGyro(msg); - - // compute the interpolated offset - Vector3f gyroOffset; - for (int i = 0; i < 3; i++) - gyroOffset[i] = (float) Interpolators[i].GetOffset(msg.Temperature, GyroAutoTemperature, GyroAutoOffset[i]); - - // apply calibration - msg.RotationRate = GyroMatrix.Transform(msg.RotationRate - gyroOffset); - msg.Acceleration = AccelMatrix.Transform(msg.Acceleration - AccelOffset); - if (MagCalibrated) - msg.MagneticField = MagMatrix.Transform(msg.MagneticField); -} - -void SensorCalibration::AutocalibrateGyro(MessageBodyFrame const& msg) -{ - const float alpha = 0.4f; - // 1.25f is a scaling factor related to conversion from per-axis comparison to length comparison - const float absLimit = 1.25f * 0.349066f; - const float noiseLimit = 1.25f * 0.03f; - - Vector3f gyro = msg.RotationRate; - // do a moving average to reject short term noise - Vector3f avg = (GyroFilter.IsEmpty()) ? gyro : gyro * alpha + GyroFilter.PeekBack() * (1 - alpha); - - // Make sure the absolute value is below what is likely motion - // Make sure it is close enough to the current average that it is probably noise and not motion - if (avg.Length() >= absLimit || (avg - GyroFilter.Mean()).Length() >= noiseLimit) - GyroFilter.Clear(); - GyroFilter.PushBack(avg); - - // if had a reasonable number of samples already use it for the current offset - if (GyroFilter.GetSize() > GyroFilter.GetCapacity() / 2) - { - GyroAutoOffset = GyroFilter.Mean(); - GyroAutoTemperature = msg.Temperature; - // After ~6 seconds of no motion, use the average as the new zero rate offset - if (GyroFilter.IsFull()) - StoreAutoOffset(); - } -} - -void SensorCalibration::StoreAutoOffset() -{ - const double maxDeltaT = 2.5; - const double minExtraDeltaT = 0.5; - const UInt32 minDelay = 24 * 3600; // 1 day in seconds - - // find the best bin - UPInt binIdx = 0; - for (UPInt i = 1; i < TemperatureReports.GetSize(); i++) - if (Abs(GyroAutoTemperature - TemperatureReports[i][0].TargetTemperature) < - Abs(GyroAutoTemperature - TemperatureReports[binIdx][0].TargetTemperature)) - binIdx = i; - - // find the oldest and newest samples - // NB: uninitialized samples have Time == 0, so they will get picked as the oldest - UPInt newestIdx = 0, oldestIdx = 0; - for (UPInt i = 1; i < TemperatureReports[binIdx].GetSize(); i++) - { - // if the version is newer - do nothing - if (TemperatureReports[binIdx][i].Version > VERSION) - return; - if (TemperatureReports[binIdx][i].Time > TemperatureReports[binIdx][newestIdx].Time) - newestIdx = i; - if (TemperatureReports[binIdx][i].Time < TemperatureReports[binIdx][oldestIdx].Time) - oldestIdx = i; - } - TemperatureReport& oldestReport = TemperatureReports[binIdx][oldestIdx]; - TemperatureReport& newestReport = TemperatureReports[binIdx][newestIdx]; - OVR_ASSERT((oldestReport.Sample == 0 && newestReport.Sample == 0 && newestReport.Version == 0) || - oldestReport.Sample == (newestReport.Sample + 1) % newestReport.NumSamples); - - bool writeSuccess = false; - UInt32 now = (UInt32) time(0); - if (now - newestReport.Time > minDelay) - { - // only write a new sample if the temperature is close enough - if (Abs(GyroAutoTemperature - oldestReport.TargetTemperature) < maxDeltaT) - { - oldestReport.Time = now; - oldestReport.ActualTemperature = GyroAutoTemperature; - oldestReport.Offset = (Vector3d) GyroAutoOffset; - oldestReport.Version = VERSION; - writeSuccess = pSensor->SetTemperatureReport(oldestReport); - OVR_ASSERT(writeSuccess); - } - } - else - { - // if the newest sample is too recent - _update_ it if significantly closer to the target temp - if (Abs(GyroAutoTemperature - newestReport.TargetTemperature) + minExtraDeltaT - < Abs(newestReport.ActualTemperature - newestReport.TargetTemperature)) - { - // (do not update the time!) - newestReport.ActualTemperature = GyroAutoTemperature; - newestReport.Offset = (Vector3d) GyroAutoOffset; - newestReport.Version = VERSION; - writeSuccess = pSensor->SetTemperatureReport(newestReport); - OVR_ASSERT(writeSuccess); - } - } - - // update the interpolators with the new data - // this is not particularly expensive call and would only happen rarely - // but if performance is a problem, it's possible to only recompute the data that has changed - if (writeSuccess) - for (int i = 0; i < 3; i++) - Interpolators[i].Initialize(TemperatureReports, i); -} - -const TemperatureReport& median(const Array& temperatureReportsBin, int coord) -{ - Array values; - values.Reserve(temperatureReportsBin.GetSize()); - for (unsigned i = 0; i < temperatureReportsBin.GetSize(); i++) - if (temperatureReportsBin[i].ActualTemperature != 0) - values.PushBack(temperatureReportsBin[i].Offset[coord]); - if (values.GetSize() > 0) - { - double med = Median(values); - // this is kind of a hack - for (unsigned i = 0; i < temperatureReportsBin.GetSize(); i++) - if (temperatureReportsBin[i].Offset[coord] == med) - return temperatureReportsBin[i]; - // if we haven't found the median in the original array, something is wrong - OVR_DEBUG_BREAK; - } - return temperatureReportsBin[0]; -} - -void OffsetInterpolator::Initialize(Array > const& temperatureReports, int coord) -{ - int bins = (int) temperatureReports.GetSize(); - Temperatures.Clear(); - Temperatures.Reserve(bins); - Values.Clear(); - Values.Reserve(bins); - - for (int bin = 0; bin < bins; bin++) - { - OVR_ASSERT(temperatureReports[bin].GetSize() == temperatureReports[0].GetSize()); - const TemperatureReport& report = median(temperatureReports[bin], coord); - if (report.Version > 0 && report.Version <= MAX_COMPAT_VERSION) - { - Temperatures.PushBack(report.ActualTemperature); - Values.PushBack(report.Offset[coord]); - } - } -} - -double OffsetInterpolator::GetOffset(double targetTemperature, double autoTemperature, double autoValue) -{ - const double autoRangeExtra = 1.0; - const double minInterpolationDist = 0.5; - - // difference between current and autocalibrated temperature adjusted for preference over historical data - const double adjustedDeltaT = Abs(autoTemperature - targetTemperature) - autoRangeExtra; - - int count = (int) Temperatures.GetSize(); - // handle special cases when we don't have enough data for proper interpolation - if (count == 0) - return autoValue; - if (count == 1) - { - if (adjustedDeltaT < Abs(Temperatures[0] - targetTemperature)) - return autoValue; - else - return Values[0]; - } - - // first, find the interval that contains targetTemperature - // if all points are on the same side of targetTemperature, find the adjacent interval - int l; - if (targetTemperature < Temperatures[1]) - l = 0; - else if (targetTemperature >= Temperatures[count - 2]) - l = count - 2; - else - for (l = 1; l < count - 2; l++) - if (Temperatures[l] <= targetTemperature && targetTemperature < Temperatures[l+1]) - break; - int u = l + 1; - - // extend the interval if it's too small and the interpolation is unreliable - if (Temperatures[u] - Temperatures[l] < minInterpolationDist) - { - if (l > 0 - && (u == count - 1 || Temperatures[u] - Temperatures[l - 1] < Temperatures[u + 1] - Temperatures[l])) - l--; - else if (u < count - 1) - u++; - } - - // verify correctness - OVR_ASSERT(l >= 0 && u < count); - OVR_ASSERT(l == 0 || Temperatures[l] <= targetTemperature); - OVR_ASSERT(u == count - 1 || targetTemperature < Temperatures[u]); - OVR_ASSERT((l == 0 && u == count - 1) || Temperatures[u] - Temperatures[l] > minInterpolationDist); - OVR_ASSERT(Temperatures[l] <= Temperatures[u]); - - // perform the interpolation - double slope; - if (Temperatures[u] - Temperatures[l] >= minInterpolationDist) - slope = (Values[u] - Values[l]) / (Temperatures[u] - Temperatures[l]); - else - // avoid a badly conditioned problem - slope = 0; - if (adjustedDeltaT < Abs(Temperatures[u] - targetTemperature)) - // use the autocalibrated value, if it's close - return autoValue + slope * (targetTemperature - autoTemperature); - else - return Values[u] + slope * (targetTemperature - Temperatures[u]); -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_SensorCalibration.h b/LibOVR/Src/OVR_SensorCalibration.h deleted file mode 100644 index 62883d2..0000000 --- a/LibOVR/Src/OVR_SensorCalibration.h +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SensorCalibration.h -Content : Calibration data implementation for the IMU messages -Created : January 28, 2014 -Authors : Max Katsev - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorCalibration_h -#define OVR_SensorCalibration_h - -#include "OVR_Device.h" -#include "OVR_SensorFilter.h" - -namespace OVR { - -class OffsetInterpolator -{ -public: - void Initialize(Array > const& temperatureReports, int coord); - double GetOffset(double targetTemperature, double autoTemperature, double autoValue); - - Array Temperatures; - Array Values; -}; - -class SensorCalibration : public NewOverrideBase -{ -public: - SensorCalibration(SensorDevice* pSensor); - - // Load data from the HW and perform the necessary preprocessing - void Initialize(); - // Apply the calibration - void Apply(MessageBodyFrame& msg); - // Is mag calibration available? - bool IsMagCalibrated() { return MagCalibrated; } - -protected: - void StoreAutoOffset(); - void AutocalibrateGyro(MessageBodyFrame const& msg); - - void DebugPrintLocalTemperatureTable(); - void DebugClearHeadsetTemperatureReports(); - - SensorDevice* pSensor; - - // Factory calibration data - bool MagCalibrated; - Matrix4f AccelMatrix, GyroMatrix, MagMatrix; - Vector3f AccelOffset; - - // Temperature based data - Array > TemperatureReports; - OffsetInterpolator Interpolators[3]; - - // Autocalibration data - SensorFilterf GyroFilter; - Vector3f GyroAutoOffset; - float GyroAutoTemperature; -}; - -} // namespace OVR -#endif //OVR_SensorCalibration_h diff --git a/LibOVR/Src/OVR_SensorFilter.cpp b/LibOVR/Src/OVR_SensorFilter.cpp deleted file mode 100644 index 2c660ae..0000000 --- a/LibOVR/Src/OVR_SensorFilter.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_SensorFilter.cpp -Content : Basic filtering of sensor this->Data -Created : March 7, 2013 -Authors : Steve LaValle, Anna Yershova, Max Katsev - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorFilter.h" - -namespace OVR { - -template -Vector3 SensorFilter::Median() const -{ - Vector3 result; - T* slice = (T*) OVR_ALLOC(this->ElemCount * sizeof(T)); - - for (int coord = 0; coord < 3; coord++) - { - for (int i = 0; i < this->ElemCount; i++) - slice[i] = this->Data[i][coord]; - result[coord] = Alg::Median(ArrayAdaptor(slice, this->ElemCount)); - } - - OVR_FREE(slice); - return result; -} - -// Only the diagonal of the covariance matrix. -template -Vector3 SensorFilter::Variance() const -{ - Vector3 mean = this->Mean(); - Vector3 total; - for (int i = 0; i < this->ElemCount; i++) - { - total.x += (this->Data[i].x - mean.x) * (this->Data[i].x - mean.x); - total.y += (this->Data[i].y - mean.y) * (this->Data[i].y - mean.y); - total.z += (this->Data[i].z - mean.z) * (this->Data[i].z - mean.z); - } - return total / (float) this->ElemCount; -} - -template -Matrix3 SensorFilter::Covariance() const -{ - Vector3 mean = this->Mean(); - Matrix3 total; - for (int i = 0; i < this->ElemCount; i++) - { - total.M[0][0] += (this->Data[i].x - mean.x) * (this->Data[i].x - mean.x); - total.M[1][0] += (this->Data[i].y - mean.y) * (this->Data[i].x - mean.x); - total.M[2][0] += (this->Data[i].z - mean.z) * (this->Data[i].x - mean.x); - total.M[1][1] += (this->Data[i].y - mean.y) * (this->Data[i].y - mean.y); - total.M[2][1] += (this->Data[i].z - mean.z) * (this->Data[i].y - mean.y); - total.M[2][2] += (this->Data[i].z - mean.z) * (this->Data[i].z - mean.z); - } - total.M[0][1] = total.M[1][0]; - total.M[0][2] = total.M[2][0]; - total.M[1][2] = total.M[2][1]; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - total.M[i][j] /= (float) this->ElemCount; - return total; -} - -template -Vector3 SensorFilter::PearsonCoefficient() const -{ - Matrix3 cov = this->Covariance(); - Vector3 pearson; - pearson.x = cov.M[0][1]/(sqrt(cov.M[0][0])*sqrt(cov.M[1][1])); - pearson.y = cov.M[1][2]/(sqrt(cov.M[1][1])*sqrt(cov.M[2][2])); - pearson.z = cov.M[2][0]/(sqrt(cov.M[2][2])*sqrt(cov.M[0][0])); - - return pearson; -} - -} //namespace OVR diff --git a/LibOVR/Src/OVR_SensorFilter.h b/LibOVR/Src/OVR_SensorFilter.h deleted file mode 100644 index 0805d57..0000000 --- a/LibOVR/Src/OVR_SensorFilter.h +++ /dev/null @@ -1,307 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_SensorFilter.h -Content : Basic filtering of sensor data -Created : March 7, 2013 -Authors : Steve LaValle, Anna Yershova, Max Katsev - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorFilter_h -#define OVR_SensorFilter_h - -#include "Kernel/OVR_Math.h" -#include "Kernel/OVR_Deque.h" -#include "Kernel/OVR_Alg.h" - -namespace OVR { - -// A base class for filters that maintains a buffer of sensor data taken over time and implements -// various simple filters, most of which are linear functions of the data history. -// Maintains the running sum of its elements for better performance on large capacity values -template -class SensorFilterBase : public CircularBuffer -{ -protected: - T RunningTotal; // Cached sum of the elements - -public: - SensorFilterBase(int capacity = CircularBuffer::DefaultCapacity) - : CircularBuffer(capacity), RunningTotal() - { - this->Clear(); - }; - - // The following methods are augmented to update the cached running sum value - void PushBack(const T &e) - { - CircularBuffer::PushBack(e); - RunningTotal += e; - if (this->End == 0) - { - // update the cached total to avoid error accumulation - RunningTotal = T(); - for (int i = 0; i < this->ElemCount; i++) - RunningTotal += this->Data[i]; - } - } - - void PushFront(const T &e) - { - CircularBuffer::PushFront(e); - RunningTotal += e; - if (this->Beginning == 0) - { - // update the cached total to avoid error accumulation - RunningTotal = T(); - for (int i = 0; i < this->ElemCount; i++) - RunningTotal += this->Data[i]; - } - } - - T PopBack() - { - T e = CircularBuffer::PopBack(); - RunningTotal -= e; - return e; - } - - T PopFront() - { - T e = CircularBuffer::PopFront(); - RunningTotal -= e; - return e; - } - - void Clear() - { - CircularBuffer::Clear(); - RunningTotal = T(); - } - - // Simple statistics - T Total() const - { - return RunningTotal; - } - - T Mean() const - { - return this->IsEmpty() ? T() : (Total() / (float) this->ElemCount); - } - - T MeanN(int n) const - { - OVR_ASSERT(n > 0); - OVR_ASSERT(this->Capacity >= n); - T total = T(); - for (int i = 0; i < n; i++) - { - total += this->PeekBack(i); - } - return total / n; - } - - // A popular family of smoothing filters and smoothed derivatives - - T SavitzkyGolaySmooth4() - { - OVR_ASSERT(this->Capacity >= 4); - return this->PeekBack(0)*0.7f + - this->PeekBack(1)*0.4f + - this->PeekBack(2)*0.1f - - this->PeekBack(3)*0.2f; - } - - T SavitzkyGolaySmooth8() const - { - OVR_ASSERT(this->Capacity >= 8); - return this->PeekBack(0)*0.41667f + - this->PeekBack(1)*0.33333f + - this->PeekBack(2)*0.25f + - this->PeekBack(3)*0.16667f + - this->PeekBack(4)*0.08333f - - this->PeekBack(6)*0.08333f - - this->PeekBack(7)*0.16667f; - } - - T SavitzkyGolayDerivative4() const - { - OVR_ASSERT(this->Capacity >= 4); - return this->PeekBack(0)*0.3f + - this->PeekBack(1)*0.1f - - this->PeekBack(2)*0.1f - - this->PeekBack(3)*0.3f; - } - - T SavitzkyGolayDerivative5() const - { - OVR_ASSERT(this->Capacity >= 5); - return this->PeekBack(0)*0.2f + - this->PeekBack(1)*0.1f - - this->PeekBack(3)*0.1f - - this->PeekBack(4)*0.2f; - } - - T SavitzkyGolayDerivative12() const - { - OVR_ASSERT(this->Capacity >= 12); - return this->PeekBack(0)*0.03846f + - this->PeekBack(1)*0.03147f + - this->PeekBack(2)*0.02448f + - this->PeekBack(3)*0.01748f + - this->PeekBack(4)*0.01049f + - this->PeekBack(5)*0.0035f - - this->PeekBack(6)*0.0035f - - this->PeekBack(7)*0.01049f - - this->PeekBack(8)*0.01748f - - this->PeekBack(9)*0.02448f - - this->PeekBack(10)*0.03147f - - this->PeekBack(11)*0.03846f; - } - - T SavitzkyGolayDerivativeN(int n) const - { - OVR_ASSERT(this->capacity >= n); - int m = (n-1)/2; - T result = T(); - for (int k = 1; k <= m; k++) - { - int ind1 = m - k; - int ind2 = n - m + k - 1; - result += (this->PeekBack(ind1) - this->PeekBack(ind2)) * (float) k; - } - float coef = 3.0f/(m*(m+1.0f)*(2.0f*m+1.0f)); - result = result*coef; - return result; - } - - T Median() const - { - T* copy = (T*) OVR_ALLOC(this->ElemCount * sizeof(T)); - T result = Alg::Median(ArrayAdaptor(copy)); - OVR_FREE(copy); - return result; - } -}; - -// This class maintains a buffer of sensor data taken over time and implements -// various simple filters, most of which are linear functions of the data history. -template -class SensorFilter : public SensorFilterBase > -{ -public: - SensorFilter(int capacity = SensorFilterBase >::DefaultCapacity) : SensorFilterBase >(capacity) { }; - - // Simple statistics - Vector3 Median() const; - Vector3 Variance() const; // The diagonal of covariance matrix - Matrix3 Covariance() const; - Vector3 PearsonCoefficient() const; -}; - -typedef SensorFilter SensorFilterf; -typedef SensorFilter SensorFilterd; - -// This filter operates on the values that are measured in the body frame and rotate with the device -class SensorFilterBodyFrame : public SensorFilterBase -{ -private: - // low pass filter gain - double gain; - // sum of squared norms of the values - double runningTotalLengthSq; - // cumulative rotation quaternion - Quatd Q; - // current low pass filter output - Vector3d output; - - // make private so it isn't used by accident - // in addition to the normal SensorFilterBase::PushBack, keeps track of running sum of LengthSq - // for the purpose of variance computations - void PushBack(const Vector3d &e) - { - runningTotalLengthSq += this->IsFull() ? (e.LengthSq() - this->PeekFront().LengthSq()) : e.LengthSq(); - SensorFilterBase::PushBack(e); - if (this->End == 0) - { - // update the cached total to avoid error accumulation - runningTotalLengthSq = 0; - for (int i = 0; i < this->ElemCount; i++) - runningTotalLengthSq += this->Data[i].LengthSq(); - } - } - -public: - SensorFilterBodyFrame(int capacity = SensorFilterBase::DefaultCapacity) - : SensorFilterBase(capacity), gain(2.5), - runningTotalLengthSq(0), Q(), output() { }; - - // return the scalar variance of the filter values (rotated to be in the same frame) - double Variance() const - { - return this->IsEmpty() ? 0 : (runningTotalLengthSq / this->ElemCount - this->Mean().LengthSq()); - } - - // return the scalar standard deviation of the filter values (rotated to be in the same frame) - double StdDev() const - { - return sqrt(Variance()); - } - - // confidence value based on the stddev of the data (between 0.0 and 1.0, more is better) - double Confidence() const - { - return Alg::Clamp(0.48 - 0.1 * log(StdDev()), 0.0, 1.0) * this->ElemCount / this->Capacity; - } - - // add a new element to the filter - // takes rotation increment since the last update - // in order to rotate the previous value to the current body frame - void Update(Vector3d value, double deltaT, Quatd deltaQ = Quatd()) - { - if (this->IsEmpty()) - { - output = value; - } - else - { - // rotate by deltaQ - output = deltaQ.Inverted().Rotate(output); - // apply low-pass filter - output += (value - output) * gain * deltaT; - } - - // put the value into the fixed frame for the stddev computation - Q = Q * deltaQ; - PushBack(Q.Rotate(output)); - } - - // returns the filter average in the current body frame - Vector3d GetFilteredValue() const - { - return Q.Inverted().Rotate(this->Mean()); - } -}; - -} //namespace OVR - -#endif // OVR_SensorFilter_h diff --git a/LibOVR/Src/OVR_SensorFusion.cpp b/LibOVR/Src/OVR_SensorFusion.cpp deleted file mode 100644 index 5c21178..0000000 --- a/LibOVR/Src/OVR_SensorFusion.cpp +++ /dev/null @@ -1,904 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SensorFusion.cpp -Content : Methods that determine head orientation from sensor data over time -Created : October 9, 2012 -Authors : Michael Antonov, Steve LaValle, Dov Katz, Max Katsev, Dan Gierl - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorFusion.h" -#include "Kernel/OVR_Log.h" -#include "Kernel/OVR_System.h" -#include "OVR_JSON.h" -#include "OVR_Profile.h" -#include "OVR_Stereo.h" -#include "OVR_Recording.h" - -// Temporary for debugging -bool Global_Flag_1 = true; - -//Convenient global variables to temporarily extract this data. -float TPH_CameraPoseOrientationWxyz[4]; -double TPH_CameraPoseConfidence; -double TPH_CameraPoseConfidenceThresholdOverrideIfNonZero = 0; -bool TPH_IsPositionTracked = false; - - -namespace OVR { - -const Transformd DefaultWorldFromCamera(Quatd(), Vector3d(0, 0, -1)); - -//------------------------------------------------------------------------------------- -// ***** Sensor Fusion - -SensorFusion::SensorFusion(SensorDevice* sensor) - : ExposureRecordHistory(100), LastMessageExposureFrame(NULL), - FocusDirection(Vector3d(0, 0, 0)), FocusFOV(0.0), - FAccelInImuFrame(1000), FAccelInCameraFrame(1000), FAngV(20), - EnableGravity(true), EnableYawCorrection(true), MagCalibrated(false), - EnableCameraTiltCorrection(true), - MotionTrackingEnabled(true), VisionPositionEnabled(true), - CenterPupilDepth(0.0) -{ - pHandler = new BodyFrameHandler(this); - - // And the clock is running... - LogText("*** SensorFusion Startup: TimeSeconds = %f\n", Timer::GetSeconds()); - - if (sensor) - AttachToSensor(sensor); - - Reset(); -} - -SensorFusion::~SensorFusion() -{ - delete(pHandler); -} - -bool SensorFusion::AttachToSensor(SensorDevice* sensor) -{ - pHandler->RemoveHandlerFromDevices(); - Reset(); - - if (sensor != NULL) - { - // cache mag calibration state - MagCalibrated = sensor->IsMagCalibrated(); - - // Load IMU position - Array reports; - bool result = sensor->GetAllPositionCalibrationReports(&reports); - if (result) - { - PositionCalibrationReport imu = reports[reports.GetSize() - 1]; - OVR_ASSERT(imu.PositionType == PositionCalibrationReport::PositionType_IMU); - // convert from vision to the world frame - // TBD convert rotation as necessary? - imu.Position.x *= -1.0; - imu.Position.z *= -1.0; - - ImuFromScreen = Transformd(Quatd(imu.Normal, imu.Angle), imu.Position).Inverted(); - - Recording::GetRecorder().RecordLedPositions(reports); - Recording::GetRecorder().RecordDeviceIfcVersion(sensor->GetDeviceInterfaceVersion()); - } - - // Repopulate CPFOrigin - SetCenterPupilDepth(CenterPupilDepth); - - // Subscribe to sensor updates - sensor->AddMessageHandler(pHandler); - - // Initialize the sensor state - // TBD: This is a hack to avoid a race condition if sensor status is checked immediately - // after sensor creation but before any data has flowed through. We should probably - // not depend strictly on data flow to determine capabilities like orientation and position - // tracking, or else use some sort of synchronous method to wait for data - LocklessState init; - init.StatusFlags = Status_OrientationTracked; - UpdatedState.SetState(init); - } - - return true; -} - -// Resets the current orientation -void SensorFusion::Reset() -{ - Lock::Locker lockScope(pHandler->GetHandlerLock()); - - UpdatedState.SetState(LocklessState()); - WorldFromImu = PoseState(); - WorldFromImu.Pose = ImuFromCpf.Inverted(); // place CPF at the origin, not the IMU - CameraFromImu = PoseState(); - VisionError = PoseState(); - WorldFromCamera = DefaultWorldFromCamera; - WorldFromCameraConfidence = -1; - - ExposureRecordHistory.Clear(); - NextExposureRecord = ExposureRecord(); - LastMessageExposureFrame = MessageExposureFrame(NULL); - LastVisionAbsoluteTime = 0; - Stage = 0; - - MagRefs.Clear(); - MagRefIdx = -1; - MagCorrectionIntegralTerm = Quatd(); - AccelOffset = Vector3d(); - - FAccelInCameraFrame.Clear(); - FAccelInImuFrame.Clear(); - FAngV.Clear(); - - setNeckPivotFromPose ( WorldFromImu.Pose ); -} - -//------------------------------------------------------------------------------------- -// Vision & message processing - -void SensorFusion::OnVisionFailure() -{ - // do nothing - Recording::GetRecorder().RecordVisionSuccess(false); -} - -void SensorFusion::OnVisionPreviousFrame(const Transform& cameraFromImu) -{ - // simply save the observation for use in the next OnVisionSuccess call; - // this should not have unintended side-effects for position filtering, - // since the vision time is not updated and the system keeps thinking we don't have vision yet - CameraFromImu.Pose = cameraFromImu; -} - -void SensorFusion::OnVisionSuccess(const Transform& cameraFromImu, UInt32 exposureCounter) -{ - Lock::Locker lockScope(pHandler->GetHandlerLock()); - - Recording::GetRecorder().RecordVisionSuccess(true); - - LastVisionAbsoluteTime = GetTime(); - - // ********* LastVisionExposureRecord ********* - - // Skip old data and use the record that matches the exposure counter - while (!ExposureRecordHistory.IsEmpty() && - (ExposureRecordHistory.PeekFront().ExposureCounter <= exposureCounter)) - { - LastVisionExposureRecord = ExposureRecordHistory.PopFront(); - } - - // Use current values if we don't have historical data - // Right now, this will happen if we get first frame after prediction failure, - // and this exposure wasn't in the buffer. (TBD: Unlikely.. unless IMU message wasn't sent?) - if (LastVisionExposureRecord.ExposureCounter != exposureCounter) - LastVisionExposureRecord = ExposureRecord(exposureCounter, GetTime(), WorldFromImu, PoseState()); - - // ********* CameraFromImu ********* - - // This is stored in the camera frame, so need to be careful when combining with the IMU data, - // which is in the world frame - - Transformd cameraFromImuPrev = CameraFromImu.Pose; - CameraFromImu.Pose = cameraFromImu; - CameraFromImu.TimeInSeconds = LastVisionExposureRecord.ExposureTime; - - // Check LastVisionExposureRecord.Delta.TimeInSeconds to avoid divide by zero, which we could (rarely) - // get if we didn't have exposures delta for history (skipped exposure counters - // due to video mode change that stalls USB, etc). - if (LastVisionExposureRecord.ImuOnlyDelta.TimeInSeconds > 0.001) - { - Vector3d visionVelocityInImuFrame = (cameraFromImu.Translation - cameraFromImuPrev.Translation) / - LastVisionExposureRecord.ImuOnlyDelta.TimeInSeconds; - // Use the accel data to estimate the velocity at the exposure time - // (as opposed to the average velocity between exposures) - Vector3d imuVelocityInWorldFrame = LastVisionExposureRecord.ImuOnlyDelta.LinearVelocity - - LastVisionExposureRecord.ImuOnlyDelta.Pose.Translation / LastVisionExposureRecord.ImuOnlyDelta.TimeInSeconds; - CameraFromImu.LinearVelocity = visionVelocityInImuFrame + - WorldFromCamera.Inverted().Rotate(imuVelocityInWorldFrame); - } - else - { - CameraFromImu.LinearVelocity = Vector3d(0,0,0); - } -} - -PoseStated SensorFusion::computeVisionError() -{ - PoseStated worldFromImuVision = WorldFromCamera * CameraFromImu; - // Here we need to compute the difference between worldFromImuVision and WorldFromImu. - // However this difference needs to be represented in the World frame, not IMU frame. - // Therefore the computation is different from simply worldFromImuVision.Pose * WorldFromImu.Pose.Inverted(). - PoseStated err; - err.Pose.Rotation = worldFromImuVision.Pose.Rotation * - LastVisionExposureRecord.WorldFromImu.Pose.Rotation.Inverted(); - err.Pose.Translation = worldFromImuVision.Pose.Translation - - LastVisionExposureRecord.WorldFromImu.Pose.Translation; - err.LinearVelocity = worldFromImuVision.LinearVelocity - - LastVisionExposureRecord.WorldFromImu.LinearVelocity; - return err; -} - -Transform SensorFusion::GetVisionPrediction(UInt32 exposureCounter) -{ - Lock::Locker lockScope(pHandler->GetHandlerLock()); - - // Combine the small deltas together - // Should only be one iteration, unless we are skipping camera frames - ExposureRecord record; - PoseState delta = PoseState(); - - while (!ExposureRecordHistory.IsEmpty() && - (ExposureRecordHistory.PeekFront().ExposureCounter <= exposureCounter)) - { - record = ExposureRecordHistory.PopFront(); - delta.AdvanceByDelta(record.ImuOnlyDelta); - } - // Put the combine exposure record back in the history, for use in HandleVisionSuccess(...) - record.ImuOnlyDelta = delta; - ExposureRecordHistory.PushFront(record); - - Transformd result; - if (record.VisionTrackingAvailable) - { - // if the tracking is working normally, use the change in the main state (SFusion output) - // to compute the prediction - result = CameraFromImu.Pose * - LastVisionExposureRecord.WorldFromImu.Pose.Inverted() * record.WorldFromImu.Pose; - } - else - { - // if we just acquired vision, the main state probably doesn't have the correct position, - // so can't rely on it for prediction - - // solution: use the accelerometer and vision velocity to propagate the previous sample forward - // (don't forget to transform IMU to the camera frame) - result = Transform - ( - CameraFromImu.Pose.Rotation * delta.Pose.Rotation, - CameraFromImu.Pose.Translation + CameraFromImu.LinearVelocity * delta.TimeInSeconds + - WorldFromCamera.Inverted().Rotate(delta.Pose.Translation) - ); - } - - return result; -} - -void SensorFusion::handleMessage(const MessageBodyFrame& msg) -{ - if (msg.Type != Message_BodyFrame || !IsMotionTrackingEnabled()) - return; - - // Put the sensor readings into convenient local variables - Vector3d gyro(msg.RotationRate); - Vector3d accel(msg.Acceleration); - Vector3d mag(msg.MagneticField); - double DeltaT = msg.TimeDelta; - - // Keep track of time - WorldFromImu.TimeInSeconds = msg.AbsoluteTimeSeconds; - // We got an update in the last 60ms and the data is not very old - bool visionIsRecent = (GetTime() - LastVisionAbsoluteTime < 0.07) && (GetVisionLatency() < 0.25); - Stage++; - - // Insert current sensor data into filter history - FAngV.PushBack(gyro); - FAccelInImuFrame.Update(accel, DeltaT, Quatd(gyro, gyro.Length() * DeltaT)); - - // Process raw inputs - // in the future the gravity offset can be calibrated using vision feedback - Vector3d accelInWorldFrame = WorldFromImu.Pose.Rotate(accel) - Vector3d(0, 9.8, 0); - - // Recompute the vision error to account for all the corrections and the new data - VisionError = computeVisionError(); - - // Update headset orientation - WorldFromImu.StoreAndIntegrateGyro(gyro, DeltaT); - // Tilt correction based on accelerometer - if (EnableGravity) - applyTiltCorrection(DeltaT); - // Yaw correction based on camera - if (EnableYawCorrection && visionIsRecent) - applyVisionYawCorrection(DeltaT); - // Yaw correction based on magnetometer - if (EnableYawCorrection && MagCalibrated) // MagCalibrated is always false for DK2 for now - applyMagYawCorrection(mag, DeltaT); - // Focus Correction - if ((FocusDirection.x != 0.0f || FocusDirection.z != 0.0f) && FocusFOV < Mathf::Pi) - applyFocusCorrection(DeltaT); - - // Update camera orientation - if (EnableCameraTiltCorrection && visionIsRecent) - applyCameraTiltCorrection(accel, DeltaT); - - // The quaternion magnitude may slowly drift due to numerical error, - // so it is periodically normalized. - if ((Stage & 0xFF) == 0) - { - WorldFromImu.Pose.Rotation.Normalize(); - WorldFromCamera.Rotation.Normalize(); - } - - // Update headset position - if (VisionPositionEnabled && visionIsRecent) - { - // Integrate UMI and velocity here up to a fixed amount of time after vision. - WorldFromImu.StoreAndIntegrateAccelerometer(accelInWorldFrame + AccelOffset, DeltaT); - // Position correction based on camera - applyPositionCorrection(DeltaT); - // Compute where the neck pivot would be. - setNeckPivotFromPose(WorldFromImu.Pose); - } - else - { - // Fall back onto internal head model - // Use the last-known neck pivot position to figure out the expected IMU position. - // (should be the opposite of SensorFusion::setNeckPivotFromPose) - WorldFromNeck.Rotation = WorldFromImu.Pose.Rotation; - WorldFromImu.Pose = WorldFromNeck * (ImuFromCpf * CpfFromNeck).Inverted(); - - // We can't trust velocity past this point. - WorldFromImu.LinearVelocity = Vector3d(0,0,0); - WorldFromImu.LinearAcceleration = accelInWorldFrame; - } - - // Compute the angular acceleration - WorldFromImu.AngularAcceleration = (FAngV.GetSize() >= 12 && DeltaT > 0) ? - (FAngV.SavitzkyGolayDerivative12() / DeltaT) : Vector3d(); - - // Update the dead reckoning state used for incremental vision tracking - NextExposureRecord.ImuOnlyDelta.StoreAndIntegrateGyro(gyro, DeltaT); - NextExposureRecord.ImuOnlyDelta.StoreAndIntegrateAccelerometer(accelInWorldFrame, DeltaT); - NextExposureRecord.ImuOnlyDelta.TimeInSeconds = WorldFromImu.TimeInSeconds - LastMessageExposureFrame.CameraTimeSeconds; - NextExposureRecord.VisionTrackingAvailable &= (VisionPositionEnabled && visionIsRecent); - - Recording::GetRecorder().LogData("sfTimeSeconds", WorldFromImu.TimeInSeconds); - Recording::GetRecorder().LogData("sfStage", (double)Stage); - Recording::GetRecorder().LogData("sfPose", WorldFromImu.Pose); - //Recorder::LogData("sfAngAcc", State.AngularAcceleration); - //Recorder::LogData("sfAngVel", State.AngularVelocity); - //Recorder::LogData("sfLinAcc", State.LinearAcceleration); - //Recorder::LogData("sfLinVel", State.LinearVelocity); - - // Store the lockless state. - LocklessState lstate; - lstate.StatusFlags = Status_OrientationTracked; - if (VisionPositionEnabled) - lstate.StatusFlags |= Status_PositionConnected; - if (VisionPositionEnabled && visionIsRecent) - lstate.StatusFlags |= Status_PositionTracked; - - //A convenient means to temporarily extract this flag - TPH_IsPositionTracked = visionIsRecent; - - lstate.State = WorldFromImu; - lstate.Temperature = msg.Temperature; - lstate.Magnetometer = mag; - UpdatedState.SetState(lstate); -} - -void SensorFusion::handleExposure(const MessageExposureFrame& msg) -{ - NextExposureRecord.ExposureCounter = msg.CameraFrameCount; - NextExposureRecord.ExposureTime = msg.CameraTimeSeconds; - NextExposureRecord.WorldFromImu = WorldFromImu; - NextExposureRecord.ImuOnlyDelta.TimeInSeconds = msg.CameraTimeSeconds - LastMessageExposureFrame.CameraTimeSeconds; - ExposureRecordHistory.PushBack(NextExposureRecord); - - // Every new exposure starts from zero - NextExposureRecord = ExposureRecord(); - LastMessageExposureFrame = msg; -} - -// If you have a known-good pose, this sets the neck pivot position. -void SensorFusion::setNeckPivotFromPose(Transformd const &worldFromImu) -{ - WorldFromNeck = worldFromImu * ImuFromCpf * CpfFromNeck; -} - -// These two functions need to be moved into Quat class -// Compute a rotation required to transform "from" into "to". -Quatd vectorAlignmentRotation(const Vector3d &from, const Vector3d &to) -{ - Vector3d axis = from.Cross(to); - if (axis.LengthSq() == 0) - // this handles both collinear and zero-length input cases - return Quatd(); - double angle = from.Angle(to); - return Quatd(axis, angle); -} - -// Compute the part of the quaternion that rotates around Y axis -Quatd extractYawRotation(const Quatd &error) -{ - if (error.y == 0) - return Quatd(); - double phi = atan2(error.w, error.y); - double alpha = Mathd::Pi - 2 * phi; - return Quatd(Axis_Y, alpha); -} - -void SensorFusion::applyPositionCorrection(double deltaT) -{ - // Each component of gainPos is equivalent to a Kalman gain of (sigma_process / sigma_observation) - const Vector3d gainPos = Vector3d(10, 10, 8); - const Vector3d gainVel = gainPos.EntrywiseMultiply(gainPos) * 0.5; - const Vector3d gainAccel = gainVel * 0.5; - const double snapThreshold = 0.1; // Large value (previously 0.01, which caused frequent jumping) - - Vector3d correctionPos, correctionVel; - if (VisionError.Pose.Translation.LengthSq() > (snapThreshold * snapThreshold) || - !(UpdatedState.GetState().StatusFlags & Status_PositionTracked)) - { - // high error or just reacquired position from vision - apply full correction - - // to know where we are right now, take the vision pose (which is slightly old) - // and update it using the imu data since then - PoseStated worldFromImuVision = WorldFromCamera * CameraFromImu; - for (unsigned int i = 0; i < ExposureRecordHistory.GetSize(); i++) - worldFromImuVision.AdvanceByDelta(ExposureRecordHistory.PeekFront(i).ImuOnlyDelta); - worldFromImuVision.AdvanceByDelta(NextExposureRecord.ImuOnlyDelta); - - correctionPos = worldFromImuVision.Pose.Translation - WorldFromImu.Pose.Translation; - correctionVel = worldFromImuVision.LinearVelocity - WorldFromImu.LinearVelocity; - AccelOffset = Vector3d(); - } - else - { - correctionPos = VisionError.Pose.Translation.EntrywiseMultiply(gainPos) * deltaT; - correctionVel = VisionError.Pose.Translation.EntrywiseMultiply(gainVel) * deltaT; - AccelOffset += VisionError.Pose.Translation.EntrywiseMultiply(gainAccel) * deltaT; - } - - WorldFromImu.Pose.Translation += correctionPos; - WorldFromImu.LinearVelocity += correctionVel; - - // Update the exposure records so that we don't apply the same correction twice - LastVisionExposureRecord.WorldFromImu.Pose.Translation += correctionPos; - LastVisionExposureRecord.WorldFromImu.LinearVelocity += correctionVel; - for (unsigned int i = 0; i < ExposureRecordHistory.GetSize(); i++) - { - PoseStated& state = ExposureRecordHistory.PeekBack(i).WorldFromImu; - state.Pose.Translation += correctionPos; - state.LinearVelocity += correctionVel; - } -} - -void SensorFusion::applyVisionYawCorrection(double deltaT) -{ - const double gain = 0.25; - const double snapThreshold = 0.1; - - Quatd yawError = extractYawRotation(VisionError.Pose.Rotation); - - Quatd correction; - if (Alg::Abs(yawError.w) < cos(snapThreshold / 2)) // angle(yawError) > snapThreshold - // high error, jump to the vision position - correction = yawError; - else - correction = yawError.Nlerp(Quatd(), gain * deltaT); - - WorldFromImu.Pose.Rotation = correction * WorldFromImu.Pose.Rotation; - - // Update the exposure records so that we don't apply the same correction twice - LastVisionExposureRecord.WorldFromImu.Pose.Rotation = correction * LastVisionExposureRecord.WorldFromImu.Pose.Rotation; - for (unsigned int i = 0; i < ExposureRecordHistory.GetSize(); i++) - { - PoseStated& state = ExposureRecordHistory.PeekBack(i).WorldFromImu; - state.Pose.Rotation = correction * state.Pose.Rotation; - } -} - -void SensorFusion::applyMagYawCorrection(Vector3d mag, double deltaT) -{ - const double minMagLengthSq = Mathd::Tolerance; // need to use a real value to discard very weak fields - const double maxMagRefDist = 0.1; - const double maxTiltError = 0.05; - const double proportionalGain = 0.01; - const double integralGain = 0.0005; - - Vector3d magInWorldFrame = WorldFromImu.Pose.Rotate(mag); - // verify that the horizontal component is sufficient - if (magInWorldFrame.x * magInWorldFrame.x + magInWorldFrame.z * magInWorldFrame.z < minMagLengthSq) - return; - magInWorldFrame.Normalize(); - - // Delete a bad point - if (MagRefIdx >= 0 && MagRefs[MagRefIdx].Score < 0) - { - MagRefs.RemoveAtUnordered(MagRefIdx); - MagRefIdx = -1; - } - - // Update the reference point if needed - if (MagRefIdx < 0 || mag.Distance(MagRefs[MagRefIdx].InImuFrame) > maxMagRefDist) - { - // Find a new one - MagRefIdx = -1; - double bestDist = maxMagRefDist; - for (unsigned int i = 0; i < MagRefs.GetSize(); i++) - { - double dist = mag.Distance(MagRefs[i].InImuFrame); - if (bestDist > dist) - { - bestDist = dist; - MagRefIdx = i; - } - } - - // Create one if needed - if (MagRefIdx < 0 && MagRefs.GetSize() < MagMaxReferences) - { - MagRefs.PushBack(MagReferencePoint(mag, WorldFromImu.Pose, 1000)); - } - } - - if (MagRefIdx >= 0) - { - Vector3d magRefInWorldFrame = MagRefs[MagRefIdx].WorldFromImu.Rotate(MagRefs[MagRefIdx].InImuFrame); - magRefInWorldFrame.Normalize(); - - // If the vertical angle is wrong, decrease the score and do nothing - if (Alg::Abs(magRefInWorldFrame.y - magInWorldFrame.y) > maxTiltError) - { - MagRefs[MagRefIdx].Score -= 1; - return; - } - - MagRefs[MagRefIdx].Score += 2; -#if 0 - // this doesn't seem to work properly, need to investigate - Quatd error = vectorAlignmentRotation(magW, magRefW); - Quatd yawError = extractYawRotation(error); -#else - // Correction is computed in the horizontal plane - magInWorldFrame.y = magRefInWorldFrame.y = 0; - Quatd yawError = vectorAlignmentRotation(magInWorldFrame, magRefInWorldFrame); -#endif - Quatd correction = yawError.Nlerp(Quatd(), proportionalGain * deltaT) * - MagCorrectionIntegralTerm.Nlerp(Quatd(), deltaT); - MagCorrectionIntegralTerm = MagCorrectionIntegralTerm * yawError.Nlerp(Quatd(), integralGain * deltaT); - - WorldFromImu.Pose.Rotation = correction * WorldFromImu.Pose.Rotation; - } -} - -void SensorFusion::applyTiltCorrection(double deltaT) -{ - const double gain = 0.25; - const double snapThreshold = 0.1; - const Vector3d up(0, 1, 0); - - Vector3d accelInWorldFrame = WorldFromImu.Pose.Rotate(FAccelInImuFrame.GetFilteredValue()); - Quatd error = vectorAlignmentRotation(accelInWorldFrame, up); - - Quatd correction; - if (FAccelInImuFrame.GetSize() == 1 || - ((Alg::Abs(error.w) < cos(snapThreshold / 2) && FAccelInImuFrame.Confidence() > 0.75))) - // full correction for start-up - // or large error with high confidence - correction = error; - else if (FAccelInImuFrame.Confidence() > 0.5) - correction = error.Nlerp(Quatd(), gain * deltaT); - else - // accelerometer is unreliable due to movement - return; - - WorldFromImu.Pose.Rotation = correction * WorldFromImu.Pose.Rotation; -} - -void SensorFusion::applyCameraTiltCorrection(Vector3d accel, double deltaT) -{ - const double snapThreshold = 0.02; // in radians - const double maxCameraPositionOffset = 0.2; - const Vector3d up(0, 1, 0), forward(0, 0, -1); - - // for startup use filtered value instead of instantaneous for stability - if (FAccelInCameraFrame.IsEmpty()) - accel = FAccelInImuFrame.GetFilteredValue(); - - Transformd cameraFromImu = WorldFromCamera.Inverted() * VisionError.Pose * WorldFromImu.Pose; - // this is what the hypothetical camera-mounted accelerometer would show - Vector3d accelInCameraFrame = cameraFromImu.Rotate(accel); - FAccelInCameraFrame.Update(accelInCameraFrame, deltaT); - Vector3d cameraAccelInWorldFrame = WorldFromCamera.Rotate(FAccelInCameraFrame.GetFilteredValue()); - - Quatd error1 = vectorAlignmentRotation(cameraAccelInWorldFrame, up); - // cancel out yaw rotation - Vector3d forwardCamera = (error1 * WorldFromCamera.Rotation).Rotate(forward); - forwardCamera.y = 0; - Quatd error2 = vectorAlignmentRotation(forwardCamera, forward); - // combined error - Quatd error = error2 * error1; - - double confidence = FAccelInCameraFrame.Confidence(); - // penalize the confidence if looking away from the camera - // TODO: smooth fall-off - if (CameraFromImu.Pose.Rotate(forward).Angle(forward) > 1) - confidence *= 0.5; - - //Convenient global variable to temporarily extract this data. - TPH_CameraPoseConfidence = confidence; - //Allow override of confidence threshold - double confidenceThreshold = 0.75f; - if (TPH_CameraPoseConfidenceThresholdOverrideIfNonZero) - { - confidenceThreshold = TPH_CameraPoseConfidenceThresholdOverrideIfNonZero; - } - - Quatd correction; - if (FAccelInCameraFrame.GetSize() == 1 || - confidence > WorldFromCameraConfidence + 0.2 || - // disabled due to false positives when moving side to side -// (Alg::Abs(error.w) < cos(5 * snapThreshold / 2) && confidence > 0.55) || - (Alg::Abs(error.w) < cos(snapThreshold / 2) && confidence > confidenceThreshold)) - { - // large error with high confidence - correction = error; - // update the confidence level - WorldFromCameraConfidence = confidence; - } - else - { - // accelerometer is unreliable due to movement - return; - } - - Transformd newWorldFromCamera(correction * WorldFromCamera.Rotation, Vector3d()); - - // compute a camera position change that together with the camera rotation would result in zero player movement - newWorldFromCamera.Translation += (WorldFromCamera * CameraFromImu.Pose).Translation - - (newWorldFromCamera * CameraFromImu.Pose).Translation; - // if the new position is too far, reset to default - // (can't hide the rotation, might as well use it to reset the position) - if (newWorldFromCamera.Translation.DistanceSq(DefaultWorldFromCamera.Translation) > maxCameraPositionOffset * maxCameraPositionOffset) - newWorldFromCamera.Translation = DefaultWorldFromCamera.Translation; - - WorldFromCamera = newWorldFromCamera; - - //Convenient global variable to temporarily extract this data. - TPH_CameraPoseOrientationWxyz[0] = (float) WorldFromCamera.Rotation.w; - TPH_CameraPoseOrientationWxyz[1] = (float) WorldFromCamera.Rotation.x; - TPH_CameraPoseOrientationWxyz[2] = (float) WorldFromCamera.Rotation.y; - TPH_CameraPoseOrientationWxyz[3] = (float) WorldFromCamera.Rotation.z; -} - -void SensorFusion::applyFocusCorrection(double deltaT) -{ - Vector3d up = Vector3d(0, 1, 0); - double gain = 0.01; - Vector3d currentDir = WorldFromImu.Pose.Rotate(Vector3d(0, 0, 1)); - - Vector3d focusYawComponent = FocusDirection.ProjectToPlane(up); - Vector3d currentYawComponent = currentDir.ProjectToPlane(up); - - double angle = focusYawComponent.Angle(currentYawComponent); - - if( angle > FocusFOV ) - { - Quatd yawError; - if ( FocusFOV != 0.0f) - { - Vector3d lFocus = Quatd(up, -FocusFOV).Rotate(focusYawComponent); - Vector3d rFocus = Quatd(up, FocusFOV).Rotate(focusYawComponent); - double lAngle = lFocus.Angle(currentYawComponent); - double rAngle = rFocus.Angle(currentYawComponent); - if(lAngle < rAngle) - { - yawError = vectorAlignmentRotation(currentDir, lFocus); - } - else - { - yawError = vectorAlignmentRotation(currentDir, rFocus); - } - } - else - { - yawError = vectorAlignmentRotation(currentYawComponent, focusYawComponent); - } - - Quatd correction = yawError.Nlerp(Quatd(), gain * deltaT); - WorldFromImu.Pose.Rotation = correction * WorldFromImu.Pose.Rotation; - } -} - -//------------------------------------------------------------------------------------ -// Focus filter setting functions - -void SensorFusion::SetFocusDirection() -{ - SetFocusDirection(WorldFromImu.Pose.Rotate(Vector3d(0.0, 0.0, 1.0))); -} - -void SensorFusion::SetFocusDirection(Vector3d direction) -{ - FocusDirection = direction; -} - -void SensorFusion::SetFocusFOV(double fov) -{ - OVR_ASSERT(fov >= 0.0); - FocusFOV = fov; -} - -void SensorFusion::ClearFocus() -{ - FocusDirection = Vector3d(0.0, 0.0, 0.0); - FocusFOV = 0.0f; -} - -//------------------------------------------------------------------------------------- -// Head model functions. - -// Sets up head-and-neck model and device-to-pupil dimensions from the user's profile. -void SensorFusion::SetUserHeadDimensions(Profile const &profile, HmdRenderInfo const &hmdRenderInfo) -{ - float neckeye[2]; - int count = profile.GetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, neckeye, 2); - // Make sure these are vaguely sensible values. - if (count == 2) - { - OVR_ASSERT ( ( neckeye[0] > 0.05f ) && ( neckeye[0] < 0.5f ) ); - OVR_ASSERT ( ( neckeye[1] > 0.05f ) && ( neckeye[1] < 0.5f ) ); - SetHeadModel ( Vector3f ( 0.0, neckeye[1], -neckeye[0] ) ); - } - - // Find the distance from the center of the screen to the "center eye" - // This center eye is used by systems like rendering & audio to represent the player, - // and they will handle the offsets needed from there to each actual eye. - - // HACK HACK HACK - // We know for DK1 the screen->lens surface distance is roughly 0.049f, and that the faceplate->lens is 0.02357f. - // We're going to assume(!!!!) that all HMDs have the same screen->faceplate distance. - // Crystal Cove was measured to be roughly 0.025 screen->faceplate which agrees with this assumption. - // TODO: do this properly! Update: Measured this at 0.02733 with a CC prototype, CES era (PT7), on 2/19/14 -Steve - float screenCenterToMidplate = 0.02733f; - float centerEyeRelief = hmdRenderInfo.GetEyeCenter().ReliefInMeters; - float centerPupilDepth = screenCenterToMidplate + hmdRenderInfo.LensSurfaceToMidplateInMeters + centerEyeRelief; - SetCenterPupilDepth ( centerPupilDepth ); - - Recording::GetRecorder().RecordUserParams(GetHeadModel(), GetCenterPupilDepth()); -} - -Vector3f SensorFusion::GetHeadModel() const -{ - return (Vector3f)CpfFromNeck.Inverted().Translation; -} - -void SensorFusion::SetHeadModel(const Vector3f &headModel, bool resetNeckPivot /*= true*/ ) -{ - Lock::Locker lockScope(pHandler->GetHandlerLock()); - // The head model should look something like (0, 0.12, -0.12), so - // these asserts are to try to prevent sign problems, as - // they can be subtle but nauseating! - OVR_ASSERT ( headModel.y > 0.0f ); - OVR_ASSERT ( headModel.z < 0.0f ); - CpfFromNeck = Transformd(Quatd(), (Vector3d)headModel).Inverted(); - if ( resetNeckPivot ) - { - setNeckPivotFromPose ( WorldFromImu.Pose ); - } -} - -float SensorFusion::GetCenterPupilDepth() const -{ - return CenterPupilDepth; -} - -void SensorFusion::SetCenterPupilDepth(float centerPupilDepth) -{ - CenterPupilDepth = centerPupilDepth; - - Transformd screenFromCpf(Quatd(), Vector3d(0, 0, centerPupilDepth)); - ImuFromCpf = ImuFromScreen * screenFromCpf; - - setNeckPivotFromPose ( WorldFromImu.Pose ); -} - -//------------------------------------------------------------------------------------- - -// 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 Transform calcPredictedPose(const PoseState& poseState, double predictionDt) -{ - Transform pose = poseState.Pose; - 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; -} - - -Transformf SensorFusion::GetPoseAtTime(double absoluteTime) const -{ - SensorState ss = GetSensorStateAtTime ( absoluteTime ); - return ss.Predicted.Pose; -} - - -SensorState SensorFusion::GetSensorStateAtTime(double absoluteTime) const -{ - const LocklessState lstate = UpdatedState.GetState(); - // Delta time from the last available data - const double pdt = absoluteTime - lstate.State.TimeInSeconds; - - SensorState ss; - ss.Recorded = PoseStatef(lstate.State); - ss.Temperature = lstate.Temperature; - ss.Magnetometer = Vector3f(lstate.Magnetometer); - ss.StatusFlags = lstate.StatusFlags; - - ss.Predicted = ss.Recorded; - ss.Predicted.TimeInSeconds = absoluteTime; - - // Do prediction logic and ImuFromCpf transformation - ss.Recorded.Pose = Transformf(lstate.State.Pose * ImuFromCpf); - ss.Predicted.Pose = Transformf(calcPredictedPose(lstate.State, pdt) * ImuFromCpf); - return ss; -} - -unsigned SensorFusion::GetStatus() const -{ - return UpdatedState.GetState().StatusFlags; -} - -//------------------------------------------------------------------------------------- - -void SensorFusion::OnMessage(const MessageBodyFrame& msg) -{ - OVR_ASSERT(!IsAttachedToSensor()); - handleMessage(msg); -} - -//------------------------------------------------------------------------------------- - -void SensorFusion::BodyFrameHandler::OnMessage(const Message& msg) -{ - Recording::GetRecorder().RecordMessage(msg); - if (msg.Type == Message_BodyFrame) - pFusion->handleMessage(static_cast(msg)); - if (msg.Type == Message_ExposureFrame) - pFusion->handleExposure(static_cast(msg)); -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_SensorFusion.h b/LibOVR/Src/OVR_SensorFusion.h deleted file mode 100644 index 2a17920..0000000 --- a/LibOVR/Src/OVR_SensorFusion.h +++ /dev/null @@ -1,582 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_SensorFusion.h -Content : Methods that determine head orientation from sensor data over time -Created : October 9, 2012 -Authors : Michael Antonov, Steve LaValle, Dov Katz, Max Katsev, Dan Gierl - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorFusion_h -#define OVR_SensorFusion_h - -#include "OVR_Device.h" -#include "OVR_SensorFilter.h" -#include "Kernel/OVR_Timer.h" -#include "Kernel/OVR_Threads.h" -#include "Kernel/OVR_Lockless.h" - -// CAPI forward declarations. -typedef struct ovrPoseStatef_ ovrPoseStatef; -typedef struct ovrSensorState_ ovrSensorState; - -namespace OVR { - -struct HmdRenderInfo; - -//------------------------------------------------------------------------------------- -// ***** Sensor State - -// These values are reported as compatible with C API. - - -// 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) - : Pose(src.Pose), - 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) - : Pose(src.Pose), - 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.Pose = Pose; - result.AngularVelocity = AngularVelocity; - result.LinearVelocity = LinearVelocity; - result.AngularAcceleration = AngularAcceleration; - result.LinearAcceleration = LinearAcceleration; - result.TimeInSeconds = TimeInSeconds; - return result; - } - - - Transform Pose; - 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); -}; - - - -// External API returns pose as float, but uses doubles internally for quaternion precision. -typedef PoseState PoseStatef; -typedef PoseState PoseStated; - - -//------------------------------------------------------------------------------------- -// ***** Sensor State - - -// Bit flags describing the current status of sensor tracking. -enum StatusBits -{ - Status_OrientationTracked = 0x0001, // Orientation is currently tracked (connected and in use). - Status_PositionTracked = 0x0002, // Position is currently tracked (false if out of range). - Status_PositionConnected = 0x0020, // Position tracking HW is conceded. - // Status_HMDConnected = 0x0080 // HMD Display is available & connected. -}; - - -// Full state of of the sensor reported by GetSensorState() at a given absolute time. -class SensorState -{ -public: - SensorState() : Temperature(0), StatusFlags(0) { } - - // C-interop support - SensorState(const ovrSensorState& s); - operator ovrSensorState () const; - - // Pose state at the time that SensorState was requested. - PoseStatef Predicted; - // Actual recorded pose configuration based on sensor sample at a - // moment closest to the requested time. - PoseStatef Recorded; - - // Calibrated magnetometer reading, in Gauss, at sample time. - Vector3f Magnetometer; - // Sensor temperature reading, in degrees Celsius, at sample time. - float Temperature; - // Sensor status described by ovrStatusBits. - unsigned int StatusFlags; -}; - - - -//------------------------------------------------------------------------------------- - -class VisionHandler -{ -public: - virtual void OnVisionSuccess(const Transform& cameraFromImu, UInt32 exposureCounter) = 0; - virtual void OnVisionPreviousFrame(const Transform& cameraFromImu) = 0; - virtual void OnVisionFailure() = 0; - - // Get a configuration that represents the change over a short time interval - virtual Transform GetVisionPrediction(UInt32 exposureCounter) = 0; -}; - -//------------------------------------------------------------------------------------- -// ***** SensorFusion - -// SensorFusion class accumulates Sensor notification messages to keep track of -// orientation, which involves integrating the gyro and doing correction with gravity. -// Magnetometer based yaw drift correction is also supported; it is usually enabled -// automatically based on loaded magnetometer configuration. -// Orientation is reported as a quaternion, from which users can obtain either the -// rotation matrix or Euler angles. -// -// The class can operate in two ways: -// - By user manually passing MessageBodyFrame messages to the OnMessage() function. -// - By attaching SensorFusion to a SensorDevice, in which case it will -// automatically handle notifications from that device. - - -class SensorFusion : public NewOverrideBase, public VisionHandler -{ - friend class SensorFusionDebug; - - enum - { - MagMaxReferences = 1000 - }; - -public: - - // ------------------------------------------------------------------------------- - // Critical components for tiny API - - SensorFusion(SensorDevice* sensor = 0); - ~SensorFusion(); - - // Attaches this SensorFusion to the IMU sensor device, from which it will receive - // notification messages. If a sensor is attached, manual message notification - // is not necessary. Calling this function also resets SensorFusion state. - bool AttachToSensor(SensorDevice* sensor); - - // Returns true if this Sensor fusion object is attached to the IMU. - bool IsAttachedToSensor() const; - - // Sets up head-and-neck model and device-to-pupil dimensions from the user's profile and the HMD stats. - // This copes elegantly if profile is NULL. - void SetUserHeadDimensions(Profile const &profile, HmdRenderInfo const &hmdRenderInfo); - - // Get the predicted pose (orientation, position) of the center pupil frame (CPF) at a specific point in time. - Transformf GetPoseAtTime(double absoluteTime) const; - - // Get the full dynamical system state of the CPF, which includes velocities and accelerations, - // predicted at a specified absolute point in time. - SensorState GetSensorStateAtTime(double absoluteTime) const; - - // Get the sensor status (same as GetSensorStateAtTime(...).Status) - unsigned int GetStatus() const; - - // End tiny API components - // ------------------------------------------------------------------------------- - - // Resets the current orientation. - void Reset (); - - // Configuration - void EnableMotionTracking(bool enable = true) { MotionTrackingEnabled = enable; } - bool IsMotionTrackingEnabled() const { return MotionTrackingEnabled; } - - // Accelerometer/Gravity Correction Control - // Enables/disables gravity correction (on by default). - void SetGravityEnabled (bool enableGravity); - bool IsGravityEnabled () const; - - // Vision Position and Orientation Configuration - // ----------------------------------------------- - bool IsVisionPositionEnabled () const; - void SetVisionPositionEnabled (bool enableVisionPosition); - - // compensates for a tilted camera - void SetCameraTiltCorrectionEnabled(bool enable); - bool IsCameraTiltCorrectionEnabled () const; - - // Message Handling Logic - // ----------------------------------------------- - // Notifies SensorFusion object about a new BodyFrame - // message from a sensor. - // Should be called by user if not attached to sensor. - void OnMessage (const MessageBodyFrame& msg); - - - // Interaction with vision - // ----------------------------------------------- - // Handle observation from vision system (orientation, position, time) - virtual void OnVisionSuccess(const Transform& cameraFromImu, UInt32 exposureCounter); - - virtual void OnVisionPreviousFrame(const Transform& cameraFromImu); - virtual void OnVisionFailure(); - // Get a configuration that represents the change over a short time interval - virtual Transform GetVisionPrediction(UInt32 exposureCounter); - - double GetTime () const; - double GetVisionLatency () const; - - - // Detailed head dimension control - // ----------------------------------------------- - // These are now deprecated in favour of SetUserHeadDimensions() - Vector3f GetHeadModel() const; - void SetHeadModel(const Vector3f &headModel, bool resetNeckPivot = true ); - float GetCenterPupilDepth() const; - void SetCenterPupilDepth(float centerPupilDepth); - - - // Magnetometer and Yaw Drift Section: - // --------------------------------------- - - // Enables/disables magnetometer based yaw drift correction. - // Must also have mag calibration data for this correction to work. - void SetYawCorrectionEnabled(bool enable); - // Determines if yaw correction is enabled. - bool IsYawCorrectionEnabled () const; - - // Clear the reference points associating - // mag readings with orientations - void ClearMagReferences (); - - // Sets the focus filter direction to the current HMD direction - void SetFocusDirection(); - // Sets the focus filter to a direction in the body frame. Once set, a complementary filter - // will very slowly drag the world to keep the direction of the HMD within the FOV of the focus - void SetFocusDirection(Vector3d direction); - // Sets the FOV (in radians) of the focus. When the yaw difference between the HMD's current pose - // and the focus is smaller than the FOV, the complementary filter does not act. - void SetFocusFOV(double rads); - // Turns off the focus filter (equivalent to setting the focus to 0 - void ClearFocus(); - -private: - - // ----------------------------------------------- - - class BodyFrameHandler : public NewOverrideBase, public MessageHandler - { - SensorFusion* pFusion; - public: - BodyFrameHandler(SensorFusion* fusion) - : pFusion(fusion) {} - - ~BodyFrameHandler(); - - virtual void OnMessage(const Message& msg); - virtual bool SupportsMessageType(MessageType type) const; - }; - - - // ----------------------------------------------- - - // State version stored in lockless updater "queue" and used for - // prediction by GetPoseAtTime/GetSensorStateAtTime - struct LocklessState - { - PoseState State; - float Temperature; - Vector3d Magnetometer; - unsigned int StatusFlags; - - LocklessState() : Temperature(0.0), StatusFlags(0) { }; - }; - - - // ----------------------------------------------- - - // Entry describing the state of the headset at the time of an exposure as reported by the DK2 board. - // This is used in combination with the vision data for - // incremental tracking based on IMU change and for drift correction - struct ExposureRecord - { - UInt32 ExposureCounter; - double ExposureTime; - // State of the headset at the time of exposure - PoseState WorldFromImu; - // Change in state since the last exposure based on IMU data only - PoseState ImuOnlyDelta; - // Did we have tracking for the entire interval between exposures - bool VisionTrackingAvailable; - - ExposureRecord() : ExposureCounter(0), ExposureTime(0.0), VisionTrackingAvailable(true) { } - ExposureRecord(UInt32 exposureCounter, double exposureTime, - const PoseState& worldFromImu, const PoseState& imuOnlyDelta) - : ExposureCounter(exposureCounter), ExposureTime(exposureTime), - WorldFromImu(worldFromImu), ImuOnlyDelta(imuOnlyDelta), VisionTrackingAvailable(true) { } - }; - - // ----------------------------------------------- - - // Entry describing the magnetometer reference point - // Used for mag yaw correction - struct MagReferencePoint - { - Vector3d InImuFrame; - Transformd WorldFromImu; - int Score; - - MagReferencePoint() { } - MagReferencePoint(const Vector3d& inImuFrame, const Transformd& worldFromImu, int score) - : InImuFrame(inImuFrame), WorldFromImu(worldFromImu), Score(score) { } - }; - - // ----------------------------------------------- - - // The phase of the head as estimated by sensor fusion - PoseState WorldFromImu; - - // State that can be read without any locks, so that high priority rendering thread - // doesn't have to worry about being blocked by a sensor/vision threads that got preempted. - LocklessUpdater UpdatedState; - - // The pose we got from Vision, augmented with velocity information from numerical derivatives - PoseState CameraFromImu; - // Difference between the vision and sensor fusion poses at the time of last exposure adjusted - // by all the corrections applied since then - // NB: this one is unlike all the other poses/transforms we use, since it's a difference - // between 2 WorldFromImu transforms, but is stored in the world frame, not the IMU frame - // (see computeVisionError() for details) - // For composition purposes it should be considered a WorldFromWorld transform, where the left - // side comes from vision and the right - from sensor fusion - PoseState VisionError; - // Past exposure records between the last update from vision and now - // (should only be one record unless vision latency is high) - CircularBuffer ExposureRecordHistory; - // ExposureRecord that corresponds to the last pose we got from vision - ExposureRecord LastVisionExposureRecord; - // Incomplete ExposureRecord that will go into the history buffer when - // the new MessageExposureFrame is received - ExposureRecord NextExposureRecord; - // Timings of the previous exposure, used to populate ExposureRecordHistory - MessageExposureFrame LastMessageExposureFrame; - // Time of the last vision update - double LastVisionAbsoluteTime; - - unsigned int Stage; - BodyFrameHandler *pHandler; - - Vector3d FocusDirection; - double FocusFOV; - - SensorFilterBodyFrame FAccelInImuFrame, FAccelInCameraFrame; - SensorFilterd FAngV; - - Vector3d AccelOffset; - - bool EnableGravity; - - bool EnableYawCorrection; - bool MagCalibrated; - Array MagRefs; - int MagRefIdx; - Quatd MagCorrectionIntegralTerm; - - bool EnableCameraTiltCorrection; - // Describes the pose of the camera in the world coordinate system - Transformd WorldFromCamera; - double WorldFromCameraConfidence; - - bool MotionTrackingEnabled; - bool VisionPositionEnabled; - - // This is a signed distance, but positive because Z increases looking inward. - // This is expressed relative to the IMU in the HMD and corresponds to the location - // of the cyclopean virtual camera focal point if both the physical and virtual - // worlds are isometrically mapped onto each other. -Steve - float CenterPupilDepth; - // Describes the position of the user eyes relative to the IMU - Transformd ImuFromCpf; - // Position of the center of the screen relative to the IMU (loaded from the headset firmware) - Transformd ImuFromScreen; - // Built-in head model for faking position using orientation only - Transformd CpfFromNeck; - // Last known base of the neck pose used for head model computations - Transformd WorldFromNeck; - - //--------------------------------------------- - - // Internal handler for messages - // bypasses error checking. - void handleMessage(const MessageBodyFrame& msg); - void handleExposure(const MessageExposureFrame& msg); - - // Compute the difference between vision and sensor fusion data - PoseStated computeVisionError(); - // Apply headset yaw correction from magnetometer - // for models without camera or when camera isn't available - void applyMagYawCorrection(Vector3d mag, double deltaT); - // Apply headset tilt correction from the accelerometer - void applyTiltCorrection(double deltaT); - // Apply headset yaw correction from the camera - void applyVisionYawCorrection(double deltaT); - // Apply headset position correction from the camera - void applyPositionCorrection(double deltaT); - // Apply camera tilt correction from the accelerometer - void applyCameraTiltCorrection(Vector3d accel, double deltaT); - // Apply camera focus correction - void applyFocusCorrection(double deltaT); - - // If you have a known-good pose, this sets the neck pivot position. - void setNeckPivotFromPose ( Transformd const &pose ); -}; - - - -//------------------------------------------------------------------------------------- -// ***** SensorFusion - Inlines - -inline bool SensorFusion::IsAttachedToSensor() const -{ - return pHandler->IsHandlerInstalled(); -} - -inline void SensorFusion::SetGravityEnabled(bool enableGravity) -{ - EnableGravity = enableGravity; -} - -inline bool SensorFusion::IsGravityEnabled() const -{ - return EnableGravity; -} - -inline void SensorFusion::SetYawCorrectionEnabled(bool enable) -{ - EnableYawCorrection = enable; -} - -inline bool SensorFusion::IsYawCorrectionEnabled() const -{ - return EnableYawCorrection; -} - -inline bool SensorFusion::IsVisionPositionEnabled() const -{ - return VisionPositionEnabled; -} - -inline void SensorFusion::SetVisionPositionEnabled(bool enableVisionPosition) -{ - VisionPositionEnabled = enableVisionPosition; -} - -inline void SensorFusion::SetCameraTiltCorrectionEnabled(bool enable) -{ - EnableCameraTiltCorrection = enable; -} - -inline bool SensorFusion::IsCameraTiltCorrectionEnabled() const -{ - return EnableCameraTiltCorrection; -} - -inline double SensorFusion::GetVisionLatency() const -{ - return LastVisionAbsoluteTime - CameraFromImu.TimeInSeconds; -} - -inline double SensorFusion::GetTime() const -{ - return Timer::GetSeconds(); -} - -inline SensorFusion::BodyFrameHandler::~BodyFrameHandler() -{ - RemoveHandlerFromDevices(); -} - -inline bool SensorFusion::BodyFrameHandler::SupportsMessageType(MessageType type) const -{ - return (type == Message_BodyFrame || type == Message_ExposureFrame); -} - - -//------------------------------------------------------------------------------------- -// ***** PoseState - Inlines - -// Stores and integrates gyro angular velocity reading for a given time step. -template -void PoseState::StoreAndIntegrateGyro(Vector3d angVel, double dt) -{ - AngularVelocity = angVel; - double angle = angVel.Length() * dt; - if (angle > 0) - Pose.Rotation = Pose.Rotation * Quatd(angVel, angle); -} - -template -void PoseState::StoreAndIntegrateAccelerometer(Vector3d linearAccel, double dt) -{ - LinearAcceleration = linearAccel; - Pose.Translation += LinearVelocity * dt + LinearAcceleration * (dt * dt * 0.5); - LinearVelocity += LinearAcceleration * dt; -} - -// Performs integration of state by adding next state delta to it -// to produce a combined state change -template -void PoseState::AdvanceByDelta(const PoseState& delta) -{ - Pose.Rotation = Pose.Rotation * delta.Pose.Rotation; - Pose.Translation += delta.Pose.Translation + LinearVelocity * delta.TimeInSeconds; - LinearVelocity += delta.LinearVelocity; - TimeInSeconds += delta.TimeInSeconds; -} - -} // namespace OVR -#endif diff --git a/LibOVR/Src/OVR_SensorFusionDebug.h b/LibOVR/Src/OVR_SensorFusionDebug.h deleted file mode 100644 index 0fc7eb5..0000000 --- a/LibOVR/Src/OVR_SensorFusionDebug.h +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_SensorFusionDebug.h -Content : Friend proxy to allow debugging access to SensorFusion -Created : April 16, 2014 -Authors : Dan Gierl - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorFusionDebug_h -#define OVR_SensorFusionDebug_h - -#include "OVR_SensorFusion.h" - -namespace OVR { - -class SensorFusionDebug -{ -private: - - SensorFusion * sf; - -public: - - SensorFusionDebug (SensorFusion * const sf) : - sf(sf) - { - } - - // Returns the number of magnetometer reference points currently gathered - int GetNumMagRefPoints () const; - // Returns the index of the magnetometer reference point being currently used - int GetCurMagRefPointIdx () const; - // Returns a copy of all the data associated with a magnetometer reference point - // This includes it's score, the magnetometer reading as a vector, - // and the HMD's pose at the time it was gathered - void GetMagRefData (int idx, int * score, Vector3d * magBF, Quatd * magPose) const; - -}; - -//------------------------------------------------------------------------------------ -// Magnetometer reference point access functions - -int SensorFusionDebug::GetNumMagRefPoints() const -{ - return (int)sf->MagRefs.GetSize(); -} - -int SensorFusionDebug::GetCurMagRefPointIdx() const -{ - return sf->MagRefIdx; -} - -void SensorFusionDebug::GetMagRefData(int idx, int * score, Vector3d * magBF, Quatd * magPose) const -{ - OVR_ASSERT(idx >= 0 && idx < GetNumMagRefPoints()); - *score = sf->MagRefs[idx].Score; - *magBF = sf->MagRefs[idx].InImuFrame; - *magPose = sf->MagRefs[idx].WorldFromImu.Rotation; -} - -} // OVR - -#endif \ No newline at end of file diff --git a/LibOVR/Src/OVR_SensorImpl.cpp b/LibOVR/Src/OVR_SensorImpl.cpp deleted file mode 100644 index 91ae7e0..0000000 --- a/LibOVR/Src/OVR_SensorImpl.cpp +++ /dev/null @@ -1,1165 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SensorImpl.cpp -Content : Oculus Sensor device implementation. -Created : March 7, 2013 -Authors : Lee Cooper, Dov Katz - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorImpl.h" -#include "OVR_Sensor2Impl.h" -#include "OVR_SensorImpl_Common.h" -#include "OVR_JSON.h" -#include "OVR_Profile.h" -#include "Kernel/OVR_Alg.h" -#include - -// HMDDeviceDesc can be created/updated through Sensor carrying DisplayInfo. - -#include "Kernel/OVR_Timer.h" - -//extern FILE *SF_LOG_fp; - -namespace OVR { - -using namespace Alg; - -//------------------------------------------------------------------------------------- -// ***** Oculus Sensor-specific packet data structures - -enum { - Sensor_VendorId = Oculus_VendorId, - Sensor_Tracker_ProductId = Device_Tracker_ProductId, - Sensor_Tracker2_ProductId = Device_Tracker2_ProductId, - Sensor_KTracker_ProductId = Device_KTracker_ProductId, - - Sensor_BootLoader = 0x1001, - - Sensor_DefaultReportRate = 500, // Hz - Sensor_MaxReportRate = 1000 // Hz -}; - - -// Messages we care for -enum TrackerMessageType -{ - TrackerMessage_None = 0, - TrackerMessage_Sensors = 1, - TrackerMessage_Unknown = 0x100, - TrackerMessage_SizeError = 0x101, -}; - - -struct TrackerSensors -{ - UByte SampleCount; - UInt16 Timestamp; - UInt16 LastCommandID; - SInt16 Temperature; - - TrackerSample Samples[3]; - - SInt16 MagX, MagY, MagZ; - - TrackerMessageType Decode(const UByte* buffer, int size) - { - if (size < 62) - return TrackerMessage_SizeError; - - SampleCount = buffer[1]; - Timestamp = DecodeUInt16(buffer + 2); - LastCommandID = DecodeUInt16(buffer + 4); - Temperature = DecodeSInt16(buffer + 6); - - //if (SampleCount > 2) - // OVR_DEBUG_LOG_TEXT(("TackerSensor::Decode SampleCount=%d\n", SampleCount)); - - // Only unpack as many samples as there actually are - int iterationCount = (SampleCount > 2) ? 3 : SampleCount; - - for (int i = 0; i < iterationCount; i++) - { - UnpackSensor(buffer + 8 + 16 * i, &Samples[i].AccelX, &Samples[i].AccelY, &Samples[i].AccelZ); - UnpackSensor(buffer + 16 + 16 * i, &Samples[i].GyroX, &Samples[i].GyroY, &Samples[i].GyroZ); - } - - MagX = DecodeSInt16(buffer + 56); - MagY = DecodeSInt16(buffer + 58); - MagZ = DecodeSInt16(buffer + 60); - - return TrackerMessage_Sensors; - } -}; - -struct TrackerMessage -{ - TrackerMessageType Type; - TrackerSensors Sensors; -}; - - -//------------------------------------------------------------------------------------- -// ***** SensorDisplayInfoImpl -SensorDisplayInfoImpl::SensorDisplayInfoImpl() - : CommandId(0), DistortionType(Base_None) -{ - memset(Buffer, 0, PacketSize); - Buffer[0] = 9; -} - -void SensorDisplayInfoImpl::Unpack() -{ - CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8); - DistortionType = Buffer[3]; - HResolution = DecodeUInt16(Buffer+4); - VResolution = DecodeUInt16(Buffer+6); - HScreenSize = DecodeUInt32(Buffer+8) * (1/1000000.f); - VScreenSize = DecodeUInt32(Buffer+12) * (1/1000000.f); - VCenter = DecodeUInt32(Buffer+16) * (1/1000000.f); - LensSeparation = DecodeUInt32(Buffer+20) * (1/1000000.f); - -#if 0 - // These are not well-measured on most devices - probably best to ignore them. - OutsideLensSurfaceToScreen[0] = DecodeUInt32(Buffer+24) * (1/1000000.f); - OutsideLensSurfaceToScreen[1] = DecodeUInt32(Buffer+28) * (1/1000000.f); - // TODO: add spline-based distortion. - // TODO: currently these values are all zeros in the HMD itself. - DistortionK[0] = DecodeFloat(Buffer+32); - DistortionK[1] = DecodeFloat(Buffer+36); - DistortionK[2] = DecodeFloat(Buffer+40); - DistortionK[3] = DecodeFloat(Buffer+44); - DistortionK[4] = DecodeFloat(Buffer+48); - DistortionK[5] = DecodeFloat(Buffer+52); -#else - // The above are either measured poorly, or don't have values at all. - // To remove the temptation to use them, set them to junk. - OutsideLensSurfaceToScreen[0] = -1.0f; - OutsideLensSurfaceToScreen[1] = -1.0f; - DistortionK[0] = -1.0f; - DistortionK[1] = -1.0f; - DistortionK[2] = -1.0f; - DistortionK[3] = -1.0f; - DistortionK[4] = -1.0f; - DistortionK[5] = -1.0f; -#endif -} - - -//------------------------------------------------------------------------------------- -// ***** SensorDeviceFactory - -SensorDeviceFactory &SensorDeviceFactory::GetInstance() -{ - static SensorDeviceFactory instance; - return instance; -} - -void SensorDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) -{ - - class SensorEnumerator : public HIDEnumerateVisitor - { - // Assign not supported; suppress MSVC warning. - void operator = (const SensorEnumerator&) { } - - DeviceFactory* pFactory; - EnumerateVisitor& ExternalVisitor; - public: - SensorEnumerator(DeviceFactory* factory, EnumerateVisitor& externalVisitor) - : pFactory(factory), ExternalVisitor(externalVisitor) { } - - virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) - { - return pFactory->MatchVendorProduct(vendorId, productId); - } - - virtual void Visit(HIDDevice& device, const HIDDeviceDesc& desc) - { - - if (desc.ProductId == Sensor_BootLoader) - { // If we find a sensor in boot loader mode then notify the app - // about the existence of the device, but don't allow the app - // to create or access the device - BootLoaderDeviceCreateDesc createDesc(pFactory, desc); - ExternalVisitor.Visit(createDesc); - return; - } - - SensorDeviceCreateDesc createDesc(pFactory, desc); - ExternalVisitor.Visit(createDesc); - - // Check if the sensor returns DisplayInfo. If so, try to use it to override potentially - // mismatching monitor information (in case wrong EDID is reported by splitter), - // or to create a new "virtualized" HMD Device. - - SensorDisplayInfoImpl displayInfo; - - if (device.GetFeatureReport(displayInfo.Buffer, SensorDisplayInfoImpl::PacketSize)) - { - displayInfo.Unpack(); - - // If we got display info, try to match / create HMDDevice as well - // so that sensor settings give preference. - if (displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) - { - SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo(displayInfo, ExternalVisitor); - } - } - } - }; - - //double start = Timer::GetProfileSeconds(); - - SensorEnumerator sensorEnumerator(this, visitor); - GetManagerImpl()->GetHIDDeviceManager()->Enumerate(&sensorEnumerator); - - //double totalSeconds = Timer::GetProfileSeconds() - start; -} - -bool SensorDeviceFactory::MatchVendorProduct(UInt16 vendorId, UInt16 productId) const -{ - return ((vendorId == Sensor_VendorId) && (productId == Sensor_Tracker_ProductId)) || - ((vendorId == Sensor_VendorId) && (productId == Sensor_Tracker2_ProductId)) || - ((vendorId == Sensor_VendorId) && (productId == Sensor_KTracker_ProductId)); -} - -bool SensorDeviceFactory::DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc) -{ - if (MatchVendorProduct(desc.VendorId, desc.ProductId)) - { - if (desc.ProductId == Sensor_BootLoader) - { // If we find a sensor in boot loader mode then notify the app - // about the existence of the device, but don't allow them - // to create or access the device - BootLoaderDeviceCreateDesc createDesc(this, desc); - pdevMgr->AddDevice_NeedsLock(createDesc); - return false; // return false to allow upstream boot loader factories to catch the device - } - else - { - SensorDeviceCreateDesc createDesc(this, desc); - return pdevMgr->AddDevice_NeedsLock(createDesc).GetPtr() != NULL; - } - } - return false; -} - -//------------------------------------------------------------------------------------- -// ***** SensorDeviceCreateDesc - -DeviceBase* SensorDeviceCreateDesc::NewDeviceInstance() -{ - if (HIDDesc.ProductId == Sensor_Tracker2_ProductId) - { - return new Sensor2DeviceImpl(this); - } - - return new SensorDeviceImpl(this); -} - -bool SensorDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const -{ - if ((info->InfoClassType != Device_Sensor) && - (info->InfoClassType != Device_None)) - return false; - - info->Type = Device_Sensor; - info->ProductName = HIDDesc.Product; - info->Manufacturer = HIDDesc.Manufacturer; - info->Version = HIDDesc.VersionNumber; - - if (info->InfoClassType == Device_Sensor) - { - SensorInfo* sinfo = (SensorInfo*)info; - sinfo->VendorId = HIDDesc.VendorId; - sinfo->ProductId = HIDDesc.ProductId; - sinfo->MaxRanges = SensorRangeImpl::GetMaxSensorRange(); - sinfo->SerialNumber = HIDDesc.SerialNumber; - } - return true; -} - -//------------------------------------------------------------------------------------- -// ***** SensorDevice - -SensorDeviceImpl::SensorDeviceImpl(SensorDeviceCreateDesc* createDesc) - : OVR::HIDDeviceImpl(createDesc, 0), - Coordinates(SensorDevice::Coord_Sensor), - HWCoordinates(SensorDevice::Coord_HMD), // HW reports HMD coordinates by default. - NextKeepAliveTickSeconds(0), - FullTimestamp(0), - MaxValidRange(SensorRangeImpl::GetMaxSensorRange()), - magCalibrated(false) -{ - SequenceValid = false; - LastSampleCount = 0; - LastTimestamp = 0; - - OldCommandId = 0; - - PrevAbsoluteTime = 0.0; - -#ifdef OVR_OS_ANDROID - pPhoneSensors = PhoneSensors::Create(); -#endif -} - -SensorDeviceImpl::~SensorDeviceImpl() -{ - // Check that Shutdown() was called. - OVR_ASSERT(!pCreateDesc->pDevice); -} - - -// Internal creation APIs. -bool SensorDeviceImpl::Initialize(DeviceBase* parent) -{ - if (HIDDeviceImpl::Initialize(parent)) - { - openDevice(); - return true; - } - - return false; -} - -void SensorDeviceImpl::openDevice() -{ - - // Read the currently configured range from sensor. - SensorRangeImpl sr(SensorRange(), 0); - - if (GetInternalDevice()->GetFeatureReport(sr.Buffer, SensorRangeImpl::PacketSize)) - { - sr.Unpack(); - sr.GetSensorRange(&CurrentRange); - // Increase the magnetometer range, since the default value is not enough in practice - CurrentRange.MaxMagneticField = 2.5f; - setRange(CurrentRange); - } - - // Read the currently configured calibration from sensor. - SensorFactoryCalibrationImpl sc; - if (GetInternalDevice()->GetFeatureReport(sc.Buffer, SensorFactoryCalibrationImpl::PacketSize)) - { - sc.Unpack(); - AccelCalibrationOffset = sc.AccelOffset; - GyroCalibrationOffset = sc.GyroOffset; - AccelCalibrationMatrix = sc.AccelMatrix; - GyroCalibrationMatrix = sc.GyroMatrix; - CalibrationTemperature = sc.Temperature; - } - - // If the sensor has "DisplayInfo" data, use HMD coordinate frame by default. - SensorDisplayInfoImpl displayInfo; - if (GetInternalDevice()->GetFeatureReport(displayInfo.Buffer, SensorDisplayInfoImpl::PacketSize)) - { - displayInfo.Unpack(); - Coordinates = (displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) ? - Coord_HMD : Coord_Sensor; - } - - // Read/Apply sensor config. - setCoordinateFrame(Coordinates); - setReportRate(Sensor_DefaultReportRate); - - // Set Keep-alive at 10 seconds. - SensorKeepAliveImpl skeepAlive(10 * 1000); - GetInternalDevice()->SetFeatureReport(skeepAlive.Buffer, SensorKeepAliveImpl::PacketSize); - - // Load mag calibration - MagCalibrationReport report; - bool res = GetMagCalibrationReport(&report); - if (res && report.Version > 0) - { - magCalibration = report.Calibration; - magCalibrated = true; - } -} - -void SensorDeviceImpl::closeDeviceOnError() -{ - LogText("OVR::SensorDevice - Lost connection to '%s'\n", getHIDDesc()->Path.ToCStr()); - NextKeepAliveTickSeconds = 0; -} - -void SensorDeviceImpl::Shutdown() -{ - HIDDeviceImpl::Shutdown(); - - LogText("OVR::SensorDevice - Closed '%s'\n", getHIDDesc()->Path.ToCStr()); -} - -void SensorDeviceImpl::OnInputReport(UByte* pData, UInt32 length) -{ - - bool processed = false; - if (!processed) - { - TrackerMessage message; - if (decodeTrackerMessage(&message, pData, length)) - { - processed = true; - onTrackerMessage(&message); - } - } -} - -double SensorDeviceImpl::OnTicks(double tickSeconds) -{ - if (tickSeconds >= NextKeepAliveTickSeconds) - { - // Use 3-seconds keep alive by default. - double keepAliveDelta = 3.0; - - // Set Keep-alive at 10 seconds. - SensorKeepAliveImpl skeepAlive(10 * 1000); - // OnTicks is called from background thread so we don't need to add this to the command queue. - GetInternalDevice()->SetFeatureReport(skeepAlive.Buffer, SensorKeepAliveImpl::PacketSize); - - // Emit keep-alive every few seconds. - NextKeepAliveTickSeconds = tickSeconds + keepAliveDelta; - } - return NextKeepAliveTickSeconds - tickSeconds; -} - -bool SensorDeviceImpl::SetRange(const SensorRange& range, bool waitFlag) -{ - bool result = 0; - ThreadCommandQueue * threadQueue = GetManagerImpl()->GetThreadQueue(); - - if (!waitFlag) - { - return threadQueue->PushCall(this, &SensorDeviceImpl::setRange, range); - } - - if (!threadQueue->PushCallAndWaitResult(this, - &SensorDeviceImpl::setRange, - &result, - range)) - { - return false; - } - - return result; -} - -void SensorDeviceImpl::GetRange(SensorRange* range) const -{ - Lock::Locker lockScope(GetLock()); - *range = CurrentRange; -} - -bool SensorDeviceImpl::setRange(const SensorRange& range) -{ - SensorRangeImpl sr(range); - - if (GetInternalDevice()->SetFeatureReport(sr.Buffer, SensorRangeImpl::PacketSize)) - { - Lock::Locker lockScope(GetLock()); - sr.GetSensorRange(&CurrentRange); - return true; - } - - return false; -} - -void SensorDeviceImpl::SetCoordinateFrame(CoordinateFrame coordframe) -{ - // Push call with wait. - GetManagerImpl()->GetThreadQueue()-> - PushCall(this, &SensorDeviceImpl::setCoordinateFrame, coordframe, true); -} - -SensorDevice::CoordinateFrame SensorDeviceImpl::GetCoordinateFrame() const -{ - return Coordinates; -} - -Void SensorDeviceImpl::setCoordinateFrame(CoordinateFrame coordframe) -{ - - Coordinates = coordframe; - - // Read the original coordinate frame, then try to change it. - SensorConfigImpl scfg; - if (GetInternalDevice()->GetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize)) - { - scfg.Unpack(); - } - - scfg.SetSensorCoordinates(coordframe == Coord_Sensor); - scfg.Pack(); - - GetInternalDevice()->SetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize); - - // Re-read the state, in case of older firmware that doesn't support Sensor coordinates. - if (GetInternalDevice()->GetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize)) - { - scfg.Unpack(); - HWCoordinates = scfg.IsUsingSensorCoordinates() ? Coord_Sensor : Coord_HMD; - } - else - { - HWCoordinates = Coord_HMD; - } - return 0; -} - -void SensorDeviceImpl::SetReportRate(unsigned rateHz) -{ - // Push call with wait. - GetManagerImpl()->GetThreadQueue()-> - PushCall(this, &SensorDeviceImpl::setReportRate, rateHz, true); -} - -unsigned SensorDeviceImpl::GetReportRate() const -{ - // Read the original configuration - SensorConfigImpl scfg; - if (GetInternalDevice()->GetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize)) - { - scfg.Unpack(); - return Sensor_MaxReportRate / (scfg.PacketInterval + 1); - } - return 0; // error -} - -Void SensorDeviceImpl::setReportRate(unsigned rateHz) -{ - // Read the original configuration - SensorConfigImpl scfg; - if (GetInternalDevice()->GetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize)) - { - scfg.Unpack(); - } - - if (rateHz > Sensor_MaxReportRate) - rateHz = Sensor_MaxReportRate; - else if (rateHz == 0) - rateHz = Sensor_DefaultReportRate; - - scfg.PacketInterval = UInt16((Sensor_MaxReportRate / rateHz) - 1); - - scfg.Pack(); - - GetInternalDevice()->SetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize); - return 0; -} - -void SensorDeviceImpl::GetFactoryCalibration(Vector3f* AccelOffset, Vector3f* GyroOffset, - Matrix4f* AccelMatrix, Matrix4f* GyroMatrix, - float* Temperature) -{ - *AccelOffset = AccelCalibrationOffset; - *GyroOffset = GyroCalibrationOffset; - *AccelMatrix = AccelCalibrationMatrix; - *GyroMatrix = GyroCalibrationMatrix; - *Temperature = CalibrationTemperature; -} - -bool SensorDeviceImpl::IsMagCalibrated() -{ - return magCalibrated; -} - -void SensorDeviceImpl::SetOnboardCalibrationEnabled(bool enabled) -{ - // Push call with wait. - GetManagerImpl()->GetThreadQueue()-> - PushCall(this, &SensorDeviceImpl::setOnboardCalibrationEnabled, enabled, true); -} - -Void SensorDeviceImpl::setOnboardCalibrationEnabled(bool enabled) -{ - // Read the original configuration - SensorConfigImpl scfg; - if (GetInternalDevice()->GetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize)) - { - scfg.Unpack(); - } - - if (enabled) - scfg.Flags |= (SensorConfigImpl::Flag_AutoCalibration | SensorConfigImpl::Flag_UseCalibration); - else - scfg.Flags &= ~(SensorConfigImpl::Flag_AutoCalibration | SensorConfigImpl::Flag_UseCalibration); - - scfg.Pack(); - - GetInternalDevice()->SetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize); - return 0; -} - -void SensorDeviceImpl::AddMessageHandler(MessageHandler* handler) -{ - if (handler) - SequenceValid = false; - DeviceBase::AddMessageHandler(handler); -} - -// Sensor reports data in the following coordinate system: -// Accelerometer: 10^-4 m/s^2; X forward, Y right, Z Down. -// Gyro: 10^-4 rad/s; X positive roll right, Y positive pitch up; Z positive yaw right. - - -// We need to convert it to the following RHS coordinate system: -// X right, Y Up, Z Back (out of screen) -// -Vector3f AccelFromBodyFrameUpdate(const TrackerSensors& update, UByte sampleNumber, - bool convertHMDToSensor = false) -{ - const TrackerSample& sample = update.Samples[sampleNumber]; - float ax = (float)sample.AccelX; - float ay = (float)sample.AccelY; - float az = (float)sample.AccelZ; - - Vector3f val = convertHMDToSensor ? Vector3f(ax, az, -ay) : Vector3f(ax, ay, az); - return val * 0.0001f; -} - - -Vector3f MagFromBodyFrameUpdate(const TrackerSensors& update, - Matrix4f magCalibration, - bool convertHMDToSensor = false) -{ - float mx = (float)update.MagX; - float my = (float)update.MagY; - float mz = (float)update.MagZ; - // Note: Y and Z are swapped in comparison to the Accel. - // This accounts for DK1 sensor firmware axis swap, which should be undone in future releases. - Vector3f mag = convertHMDToSensor ? Vector3f(mx, my, -mz) : Vector3f(mx, mz, my); - mag *= 0.0001f; - // Apply calibration - return magCalibration.Transform(mag); -} - -Vector3f EulerFromBodyFrameUpdate(const TrackerSensors& update, UByte sampleNumber, - bool convertHMDToSensor = false) -{ - const TrackerSample& sample = update.Samples[sampleNumber]; - float gx = (float)sample.GyroX; - float gy = (float)sample.GyroY; - float gz = (float)sample.GyroZ; - - Vector3f val = convertHMDToSensor ? Vector3f(gx, gz, -gy) : Vector3f(gx, gy, gz); - return val * 0.0001f; -} - -bool SensorDeviceImpl::decodeTrackerMessage(TrackerMessage* message, UByte* buffer, int size) -{ - memset(message, 0, sizeof(TrackerMessage)); - - if (size < 4) - { - message->Type = TrackerMessage_SizeError; - return false; - } - - switch (buffer[0]) - { - case TrackerMessage_Sensors: - message->Type = message->Sensors.Decode(buffer, size); - break; - - default: - message->Type = TrackerMessage_Unknown; - break; - } - - return (message->Type < TrackerMessage_Unknown) && (message->Type != TrackerMessage_None); -} - -void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message) -{ - if (message->Type != TrackerMessage_Sensors) - return; - - const double timeUnit = (1.0 / 1000.0); - double scaledTimeUnit = timeUnit; - TrackerSensors& s = message->Sensors; - // DK1 timestamps the first sample, so the actual device time will be later - // by the time we get the message if there are multiple samples. - int timestampAdjust = (s.SampleCount > 0) ? s.SampleCount-1 : 0; - - const double now = Timer::GetSeconds(); - double absoluteTimeSeconds = 0.0; - - - if (SequenceValid) - { - unsigned timestampDelta; - - if (s.Timestamp < LastTimestamp) - { - // The timestamp rolled around the 16 bit counter, so FullTimeStamp - // needs a high word increment. - FullTimestamp += 0x10000; - timestampDelta = ((((int)s.Timestamp) + 0x10000) - (int)LastTimestamp); - } - else - { - timestampDelta = (s.Timestamp - LastTimestamp); - } - // Update the low word of FullTimeStamp - FullTimestamp = ( FullTimestamp & ~0xffff ) | s.Timestamp; - - double deviceTime = (FullTimestamp + timestampAdjust) * timeUnit; - absoluteTimeSeconds = TimeFilter.SampleToSystemTime(deviceTime, now, PrevAbsoluteTime); - scaledTimeUnit = TimeFilter.ScaleTimeUnit(timeUnit); - PrevAbsoluteTime = absoluteTimeSeconds; - - // If we missed a small number of samples, generate the sample that would have immediately - // proceeded the current one. Re-use the IMU values from the last processed sample. - if ((timestampDelta > LastSampleCount) && (timestampDelta <= 254)) - { - if (HandlerRef.HasHandlers()) - { - MessageBodyFrame sensors(this); - - sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - s.SampleCount * scaledTimeUnit; - sensors.TimeDelta = (float)((timestampDelta - LastSampleCount) * scaledTimeUnit); - sensors.Acceleration = LastAcceleration; - sensors.RotationRate = LastRotationRate; - sensors.MagneticField = LastMagneticField; - sensors.Temperature = LastTemperature; - - HandlerRef.Call(sensors); - } - } - } - else - { - LastAcceleration = Vector3f(0); - LastRotationRate = Vector3f(0); - LastMagneticField= Vector3f(0); - LastTemperature = 0; - SequenceValid = true; - - // This is our baseline sensor to host time delta, - // it will be adjusted with each new message. - FullTimestamp = s.Timestamp; - - double deviceTime = (FullTimestamp + timestampAdjust) * timeUnit; - absoluteTimeSeconds = TimeFilter.SampleToSystemTime(deviceTime, now, PrevAbsoluteTime); - scaledTimeUnit = TimeFilter.ScaleTimeUnit(timeUnit); - PrevAbsoluteTime = absoluteTimeSeconds; - } - - LastSampleCount = s.SampleCount; - LastTimestamp = s.Timestamp; - - bool convertHMDToSensor = (Coordinates == Coord_Sensor) && (HWCoordinates == Coord_HMD); - -#ifdef OVR_OS_ANDROID - // LDC - Normally we get the coordinate system from the tracker. - // Since KTracker doesn't store it we'll always assume HMD coordinate system. - convertHMDToSensor = false; -#endif - - if (HandlerRef.HasHandlers()) - { - MessageBodyFrame sensors(this); - UByte iterations = s.SampleCount; - - if (s.SampleCount > 3) - { - iterations = 3; - sensors.TimeDelta = (float)((s.SampleCount - 2) * scaledTimeUnit); - } - else - { - sensors.TimeDelta = (float)scaledTimeUnit; - } - - for (UByte i = 0; i < iterations; i++) - { - sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - ( iterations - 1 - i ) * scaledTimeUnit; - sensors.Acceleration = AccelFromBodyFrameUpdate(s, i, convertHMDToSensor); - sensors.RotationRate = EulerFromBodyFrameUpdate(s, i, convertHMDToSensor); - sensors.MagneticField = MagFromBodyFrameUpdate(s, magCalibration, convertHMDToSensor); - -#ifdef OVR_OS_ANDROID - replaceWithPhoneMag(&(sensors.MagneticField)); -#endif - sensors.Temperature = s.Temperature * 0.01f; - HandlerRef.Call(sensors); - // TimeDelta for the last two sample is always fixed. - sensors.TimeDelta = (float)scaledTimeUnit; - } - - LastAcceleration = sensors.Acceleration; - LastRotationRate = sensors.RotationRate; - LastMagneticField= sensors.MagneticField; - LastTemperature = sensors.Temperature; - } - else - { - UByte i = (s.SampleCount > 3) ? 2 : (s.SampleCount - 1); - LastAcceleration = AccelFromBodyFrameUpdate(s, i, convertHMDToSensor); - LastRotationRate = EulerFromBodyFrameUpdate(s, i, convertHMDToSensor); - LastMagneticField = MagFromBodyFrameUpdate(s, magCalibration, convertHMDToSensor); - -#ifdef OVR_OS_ANDROID - replaceWithPhoneMag(&LastMagneticField); -#endif - LastTemperature = s.Temperature * 0.01f; - } -} - - -#ifdef OVR_OS_ANDROID - -void SensorDeviceImpl::replaceWithPhoneMag(Vector3f* val) -{ - - // Native calibrated. - pPhoneSensors->SetMagSource(PhoneSensors::MagnetometerSource_Native); - - Vector3f magPhone; - pPhoneSensors->GetLatestMagValue(&magPhone); - - // Phone value is in micro-Tesla. Convert it to Gauss and flip axes. - magPhone *= 10000.0f/1000000.0f; - - Vector3f res; - res.x = -magPhone.y; - res.y = magPhone.x; - res.z = magPhone.z; - - *val = res; -} -#endif - -const int MAX_DEVICE_PROFILE_MAJOR_VERSION = 1; - -// Writes the current calibration for a particular device to a device profile file -bool SensorDeviceImpl::SetMagCalibrationReport(const MagCalibrationReport &data) -{ - // Get device info - SensorInfo sinfo; - GetDeviceInfo(&sinfo); - - // A named calibration may be specified for calibration in different - // environments, otherwise the default calibration is used - const char* calibrationName = "default"; - - // Generate a mag calibration event - JSON* calibration = JSON::CreateObject(); - // (hardcoded for now) the measurement and representation method - calibration->AddStringItem("Version", "2.0"); - calibration->AddStringItem("Name", "default"); - - // time stamp the calibration - char time_str[64]; - -#ifdef OVR_OS_WIN32 - struct tm caltime; - time_t now = time(0); - localtime_s(&caltime, &now); - strftime(time_str, 64, "%Y-%m-%d %H:%M:%S", &caltime); -#else - struct tm* caltime; - time_t now = time(0); - caltime = localtime(&now); - strftime(time_str, 64, "%Y-%m-%d %H:%M:%S", caltime); -#endif - - calibration->AddStringItem("Time", time_str); - - // write the full calibration matrix - char matrix[256]; - data.Calibration.ToString(matrix, 256); - calibration->AddStringItem("CalibrationMatrix", matrix); - // save just the offset, for backwards compatibility - // this can be removed when we don't want to support 0.2.4 anymore - Vector3f center(data.Calibration.M[0][3], data.Calibration.M[1][3], data.Calibration.M[2][3]); - Matrix4f tmp = data.Calibration; tmp.M[0][3] = tmp.M[1][3] = tmp.M[2][3] = 0; tmp.M[3][3] = 1; - center = tmp.Inverted().Transform(center); - Matrix4f oldcalmat; oldcalmat.M[0][3] = center.x; oldcalmat.M[1][3] = center.y; oldcalmat.M[2][3] = center.z; - oldcalmat.ToString(matrix, 256); - calibration->AddStringItem("Calibration", matrix); - - String path = GetBaseOVRPath(true); - path += "/Devices.json"; - - // Look for a preexisting device file to edit - Ptr root = *JSON::Load(path); - if (root) - { // Quick sanity check of the file type and format before we parse it - JSON* version = root->GetFirstItem(); - if (version && version->Name == "Oculus Device Profile Version") - { - int major = atoi(version->Value.ToCStr()); - if (major > MAX_DEVICE_PROFILE_MAJOR_VERSION) - { - // don't use the file on unsupported major version number - root->Release(); - root = NULL; - } - } - else - { - root->Release(); - root = NULL; - } - } - - JSON* device = NULL; - if (root) - { - device = root->GetFirstItem(); // skip the header - device = root->GetNextItem(device); - while (device) - { // Search for a previous calibration with the same name for this device - // and remove it before adding the new one - if (device->Name == "Device") - { - JSON* item = device->GetItemByName("Serial"); - if (item && item->Value == sinfo.SerialNumber) - { // found an entry for this device - item = device->GetNextItem(item); - while (item) - { - if (item->Name == "MagCalibration") - { - JSON* name = item->GetItemByName("Name"); - if (name && name->Value == calibrationName) - { // found a calibration of the same name - item->RemoveNode(); - item->Release(); - break; - } - } - item = device->GetNextItem(item); - } - - - /* - this is removed temporarily, since this is a sensor fusion setting, not sensor itself - should be moved to the correct place when Brant has finished the user profile implementation - // update the auto-mag flag - item = device->GetItemByName("EnableYawCorrection"); - if (item) - item->dValue = (double)EnableYawCorrection; - else - device->AddBoolItem("EnableYawCorrection", EnableYawCorrection);*/ - - break; - } - } - - device = root->GetNextItem(device); - } - } - else - { // Create a new device root - root = *JSON::CreateObject(); - root->AddStringItem("Oculus Device Profile Version", "1.0"); - } - - if (device == NULL) - { - device = JSON::CreateObject(); - device->AddStringItem("Product", sinfo.ProductName); - device->AddNumberItem("ProductID", sinfo.ProductId); - device->AddStringItem("Serial", sinfo.SerialNumber); - // removed temporarily, see above - //device->AddBoolItem("EnableYawCorrection", EnableYawCorrection); - - root->AddItem("Device", device); - } - - // Create and the add the new calibration event to the device - device->AddItem("MagCalibration", calibration); - return root->Save(path); -} - -// Loads a saved calibration for the specified device from the device profile file -bool SensorDeviceImpl::GetMagCalibrationReport(MagCalibrationReport* data) -{ - data->Version = 0; - data->Calibration.SetIdentity(); - - // Get device info - SensorInfo sinfo; - GetDeviceInfo(&sinfo); - - // A named calibration may be specified for calibration in different - // environments, otherwise the default calibration is used - const char* calibrationName = "default"; - - String path = GetBaseOVRPath(true); - path += "/Devices.json"; - - // Load the device profiles - Ptr root = *JSON::Load(path); - if (root == NULL) - return false; - - // Quick sanity check of the file type and format before we parse it - JSON* version = root->GetFirstItem(); - if (version && version->Name == "Oculus Device Profile Version") - { - int major = atoi(version->Value.ToCStr()); - if (major > MAX_DEVICE_PROFILE_MAJOR_VERSION) - return false; // don't parse the file on unsupported major version number - } - else - { - return false; - } - - JSON* device = root->GetNextItem(version); - while (device) - { // Search for a previous calibration with the same name for this device - // and remove it before adding the new one - if (device->Name == "Device") - { - JSON* item = device->GetItemByName("Serial"); - if (item && item->Value == sinfo.SerialNumber) - { // found an entry for this device - - JSON* autoyaw = device->GetItemByName("EnableYawCorrection"); - // as a temporary HACK, return no calibration if EnableYawCorrection is off - // this will force disable yaw correction in SensorFusion - // proper solution would load the value in the Profile, which SensorFusion can access - if (autoyaw && autoyaw->dValue == 0) - return true; - - item = device->GetNextItem(item); - while (item) - { - if (item->Name == "MagCalibration") - { - JSON* calibration = item; - JSON* name = calibration->GetItemByName("Name"); - if (name && name->Value == calibrationName) - { // found a calibration with this name - - int major = 0; - JSON* version = calibration->GetItemByName("Version"); - if (version) - major = atoi(version->Value.ToCStr()); - - if (major > data->Version && major <= 2) - { - time_t now; - time(&now); - - // parse the calibration time - //time_t calibration_time = now; - JSON* caltime = calibration->GetItemByName("Time"); - if (caltime) - { - const char* caltime_str = caltime->Value.ToCStr(); - - tm ct; - memset(&ct, 0, sizeof(tm)); - -#ifdef OVR_OS_WIN32 - struct tm nowtime; - localtime_s(&nowtime, &now); - ct.tm_isdst = nowtime.tm_isdst; - sscanf_s(caltime_str, "%d-%d-%d %d:%d:%d", - &ct.tm_year, &ct.tm_mon, &ct.tm_mday, - &ct.tm_hour, &ct.tm_min, &ct.tm_sec); -#else - struct tm* nowtime = localtime(&now); - ct.tm_isdst = nowtime->tm_isdst; - sscanf(caltime_str, "%d-%d-%d %d:%d:%d", - &ct.tm_year, &ct.tm_mon, &ct.tm_mday, - &ct.tm_hour, &ct.tm_min, &ct.tm_sec); -#endif - ct.tm_year -= 1900; - ct.tm_mon--; - //calibration_time = mktime(&ct); - } - - // parse the calibration matrix - JSON* cal = calibration->GetItemByName("CalibrationMatrix"); - if (!cal) - cal = calibration->GetItemByName("Calibration"); - if (cal) - { - data->Calibration = Matrix4f::FromString(cal->Value.ToCStr()); - data->Version = (UByte)major; - } - } - } - } - item = device->GetNextItem(item); - } - - return true; - } - } - - device = root->GetNextItem(device); - } - - return true; -} - - -bool SensorDeviceImpl::SetSerialReport(const SerialReport& data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::setSerialReport, &result, data)) - { - return false; - } - - return result; -} - -bool SensorDeviceImpl::setSerialReport(const SerialReport& data) -{ - SerialImpl di(data); - return GetInternalDevice()->SetFeatureReport(di.Buffer, SerialImpl::PacketSize); -} - -bool SensorDeviceImpl::GetSerialReport(SerialReport* data) -{ - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getSerialReport, &result, data)) - { - return false; - } - - return result; -} - -bool SensorDeviceImpl::getSerialReport(SerialReport* data) -{ - SerialImpl di; - if (GetInternalDevice()->GetFeatureReport(di.Buffer, SerialImpl::PacketSize)) - { - di.Unpack(); - *data = di.Settings; - return true; - } - - return false; -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_SensorImpl.h b/LibOVR/Src/OVR_SensorImpl.h deleted file mode 100644 index f53b831..0000000 --- a/LibOVR/Src/OVR_SensorImpl.h +++ /dev/null @@ -1,316 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SensorImpl.h -Content : Sensor device specific implementation. -Created : March 7, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorImpl_h -#define OVR_SensorImpl_h - -#include "OVR_HIDDeviceImpl.h" -#include "OVR_SensorTimeFilter.h" -#include "OVR_Device.h" - -#ifdef OVR_OS_ANDROID -#include "OVR_PhoneSensors.h" -#endif - -namespace OVR { - -struct TrackerMessage; -class ExternalVisitor; - -//------------------------------------------------------------------------------------- -// SensorDeviceFactory enumerates Oculus Sensor devices. -class SensorDeviceFactory : public DeviceFactory -{ -public: - static SensorDeviceFactory &GetInstance(); - - // Enumerates devices, creating and destroying relevant objects in manager. - virtual void EnumerateDevices(EnumerateVisitor& visitor); - - virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const; - virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc); -protected: - DeviceManager* getManager() const { return (DeviceManager*) pManager; } -}; - - -// Describes a single a Oculus Sensor device and supports creating its instance. -class SensorDeviceCreateDesc : public HIDDeviceCreateDesc -{ -public: - SensorDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc) - : HIDDeviceCreateDesc(factory, Device_Sensor, hidDesc) { } - - virtual DeviceCreateDesc* Clone() const - { - return new SensorDeviceCreateDesc(*this); - } - - virtual DeviceBase* NewDeviceInstance(); - - virtual MatchResult MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc**) const - { - if ((other.Type == Device_Sensor) && (pFactory == other.pFactory)) - { - const SensorDeviceCreateDesc& s2 = (const SensorDeviceCreateDesc&) other; - if (MatchHIDDevice(s2.HIDDesc)) - return Match_Found; - } - return Match_None; - } - - virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const - { - // should paths comparison be case insensitive? - return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) && - (HIDDesc.SerialNumber == hidDesc.SerialNumber) && - (HIDDesc.VersionNumber == hidDesc.VersionNumber)); - } - - virtual bool GetDeviceInfo(DeviceInfo* info) const; -}; - -// A simple stub for notification of a sensor in Boot Loader mode -// This descriptor does not support the creation of a device, only the detection -// of its existence to warn apps that the sensor device needs firmware. -// The Boot Loader descriptor reuses and is created by the Sensor device factory -// but in the future may use a dedicated factory -class BootLoaderDeviceCreateDesc : public HIDDeviceCreateDesc -{ -public: - BootLoaderDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc) - : HIDDeviceCreateDesc(factory, Device_BootLoader, hidDesc) { } - - virtual DeviceCreateDesc* Clone() const - { - return new BootLoaderDeviceCreateDesc(*this); - } - - // Boot Loader device creation is not allowed - virtual DeviceBase* NewDeviceInstance() { return NULL; }; - - virtual MatchResult MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc**) const - { - if ((other.Type == Device_BootLoader) && (pFactory == other.pFactory)) - { - const BootLoaderDeviceCreateDesc& s2 = (const BootLoaderDeviceCreateDesc&) other; - if (MatchHIDDevice(s2.HIDDesc)) - return Match_Found; - } - return Match_None; - } - - virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const - { - // should paths comparison be case insensitive? - return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) && - (HIDDesc.SerialNumber == hidDesc.SerialNumber)); - } - - virtual bool GetDeviceInfo(DeviceInfo* info) const - { - OVR_UNUSED(info); - return false; - } -}; - - -//------------------------------------------------------------------------------------- -// ***** OVR::SensorDisplayInfoImpl - -// DisplayInfo obtained from sensor; these values are used to report distortion -// settings and other coefficients. -// Older SensorDisplayInfo will have all zeros, causing the library to apply hard-coded defaults. -// Currently, only resolutions and sizes are used. -struct SensorDisplayInfoImpl -{ - enum { PacketSize = 56 }; - UByte Buffer[PacketSize]; - - enum - { - Mask_BaseFmt = 0x0f, - Mask_OptionFmts = 0xf0, - Base_None = 0, - Base_ScreenOnly = 1, - Base_Distortion = 2, - }; - - UInt16 CommandId; - - UByte DistortionType; - UInt16 HResolution, VResolution; - float HScreenSize, VScreenSize; - float VCenter; - float LensSeparation; - // Currently these values are not well-measured. - float OutsideLensSurfaceToScreen[2]; - // TODO: add DistortionEqn - // TODO: currently these values are all zeros and the - // distortion is hard-coded in HMDDeviceCreateDesc::GetDeviceInfo() - float DistortionK[6]; - - SensorDisplayInfoImpl(); - - void Unpack(); -}; - -//------------------------------------------------------------------------------------- -// ***** OVR::SensorDeviceImpl - -// Oculus Sensor interface. - -class SensorDeviceImpl : public HIDDeviceImpl -{ -public: - SensorDeviceImpl(SensorDeviceCreateDesc* createDesc); - ~SensorDeviceImpl(); - - - // DeviceCommaon interface - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - virtual void AddMessageHandler(MessageHandler* handler); - - // HIDDevice::Notifier interface. - virtual void OnInputReport(UByte* pData, UInt32 length); - virtual double OnTicks(double tickSeconds); - - // HMD-Mounted sensor has a different coordinate frame. - virtual void SetCoordinateFrame(CoordinateFrame coordframe); - virtual CoordinateFrame GetCoordinateFrame() const; - - // SensorDevice interface - virtual bool SetRange(const SensorRange& range, bool waitFlag); - virtual void GetRange(SensorRange* range) const; - - virtual void GetFactoryCalibration(Vector3f* AccelOffset, Vector3f* GyroOffset, - Matrix4f* AccelMatrix, Matrix4f* GyroMatrix, - float* Temperature); - virtual void SetOnboardCalibrationEnabled(bool enabled); - virtual bool IsMagCalibrated(); - - // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call). - // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be - // called twice or thrice at the same 'tick'. - // If the rate is < 333 then the OnMessage / MessageBodyFrame will be called three - // times for each 'tick': the first call will contain averaged values, the second - // and third calls will provide with most recent two recorded samples. - virtual void SetReportRate(unsigned rateHz); - // Returns currently set report rate, in Hz. If 0 - error occurred. - // Note, this value may be different from the one provided for SetReportRate. The return - // value will contain the actual rate. - virtual unsigned GetReportRate() const; - - bool SetSerialReport(const SerialReport& data); - bool GetSerialReport(SerialReport* data); - - // Hack to create HMD device from sensor display info. - static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo, - DeviceFactory::EnumerateVisitor& visitor); - - // These methods actually store data in a JSON file - virtual bool SetMagCalibrationReport(const MagCalibrationReport& data); - virtual bool GetMagCalibrationReport(MagCalibrationReport* data); - -protected: - - virtual void openDevice(); - void closeDeviceOnError(); - - Void setCoordinateFrame(CoordinateFrame coordframe); - bool setRange(const SensorRange& range); - - Void setReportRate(unsigned rateHz); - - Void setOnboardCalibrationEnabled(bool enabled); - - bool setSerialReport(const SerialReport& data); - bool getSerialReport(SerialReport* data); - - // Called for decoded messages - void onTrackerMessage(TrackerMessage* message); - bool decodeTrackerMessage(TrackerMessage* message, UByte* buffer, int size); - - // Helpers to reduce casting. -/* - SensorDeviceCreateDesc* getCreateDesc() const - { return (SensorDeviceCreateDesc*)pCreateDesc.GetPtr(); } - - HIDDeviceDesc* getHIDDesc() const - { return &getCreateDesc()->HIDDesc; } -*/ - - // Set if the sensor is located on the HMD. - // Older prototype firmware doesn't support changing HW coordinates, - // so we track its state. - CoordinateFrame Coordinates; - CoordinateFrame HWCoordinates; - double NextKeepAliveTickSeconds; - - bool SequenceValid; - UInt16 LastTimestamp; - UByte LastSampleCount; - float LastTemperature; - Vector3f LastAcceleration; - Vector3f LastRotationRate; - Vector3f LastMagneticField; - - // This tracks wrap around, and should be monotonically increasing. - UInt32 FullTimestamp; - - // Current sensor range obtained from device. - SensorRange MaxValidRange; - SensorRange CurrentRange; - - // IMU calibration obtained from device. - Vector3f AccelCalibrationOffset; - Vector3f GyroCalibrationOffset; - Matrix4f AccelCalibrationMatrix; - Matrix4f GyroCalibrationMatrix; - float CalibrationTemperature; - - UInt16 OldCommandId; - - SensorTimeFilter TimeFilter; - double PrevAbsoluteTime; - -#ifdef OVR_OS_ANDROID - void replaceWithPhoneMag(Vector3f* val); - PhoneSensors* pPhoneSensors; -#endif - -private: - Matrix4f magCalibration; - bool magCalibrated; -}; - -} // namespace OVR - -#endif // OVR_SensorImpl_h diff --git a/LibOVR/Src/OVR_SensorImpl_Common.cpp b/LibOVR/Src/OVR_SensorImpl_Common.cpp deleted file mode 100644 index 99febe8..0000000 --- a/LibOVR/Src/OVR_SensorImpl_Common.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SensorImpl_Common.cpp -Content : Source common to SensorImpl and Sensor2Impl. -Created : January 21, 2014 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorImpl_Common.h" -#include "Kernel/OVR_Alg.h" - -namespace OVR -{ - -void UnpackSensor(const UByte* buffer, SInt32* x, SInt32* y, SInt32* z) -{ - // Sign extending trick - // from http://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend - struct {SInt32 x:21;} s; - - *x = s.x = (buffer[0] << 13) | (buffer[1] << 5) | ((buffer[2] & 0xF8) >> 3); - *y = s.x = ((buffer[2] & 0x07) << 18) | (buffer[3] << 10) | (buffer[4] << 2) | - ((buffer[5] & 0xC0) >> 6); - *z = s.x = ((buffer[5] & 0x3F) << 15) | (buffer[6] << 7) | (buffer[7] >> 1); -} - -void PackSensor(UByte* buffer, SInt32 x, SInt32 y, SInt32 z) -{ - // Pack 3 32 bit integers into 8 bytes - buffer[0] = UByte(x >> 13); - buffer[1] = UByte(x >> 5); - buffer[2] = UByte((x << 3) | ((y >> 18) & 0x07)); - buffer[3] = UByte(y >> 10); - buffer[4] = UByte(y >> 2); - buffer[5] = UByte((y << 6) | ((z >> 15) & 0x3F)); - buffer[6] = UByte(z >> 7); - buffer[7] = UByte(z << 1); -} - -UInt16 SelectSensorRampValue(const UInt16* ramp, unsigned count, - float val, float factor, const char* label) -{ - UInt16 threshold = (UInt16)(val * factor); - - for (unsigned i = 0; i= threshold) - return ramp[i]; - } - OVR_DEBUG_LOG(("SensorDevice::SetRange - %s clamped to %0.4f", - label, float(ramp[count-1]) / factor)); - OVR_UNUSED2(factor, label); - return ramp[count-1]; -} - -SensorRangeImpl::SensorRangeImpl(const SensorRange& r, UInt16 commandId) -{ - SetSensorRange(r, commandId); -} - -void SensorRangeImpl::SetSensorRange(const SensorRange& r, UInt16 commandId) -{ - CommandId = commandId; - AccelScale = SelectSensorRampValue(AccelRangeRamp, sizeof(AccelRangeRamp)/sizeof(AccelRangeRamp[0]), - r.MaxAcceleration, (1.0f / 9.81f), "MaxAcceleration"); - GyroScale = SelectSensorRampValue(GyroRangeRamp, sizeof(GyroRangeRamp)/sizeof(GyroRangeRamp[0]), - r.MaxRotationRate, Math::RadToDegreeFactor, "MaxRotationRate"); - MagScale = SelectSensorRampValue(MagRangeRamp, sizeof(MagRangeRamp)/sizeof(MagRangeRamp[0]), - r.MaxMagneticField, 1000.0f, "MaxMagneticField"); - Pack(); -} - -void SensorRangeImpl::GetSensorRange(SensorRange* r) -{ - r->MaxAcceleration = AccelScale * 9.81f; - r->MaxRotationRate = DegreeToRad((float)GyroScale); - r->MaxMagneticField= MagScale * 0.001f; -} - -SensorRange SensorRangeImpl::GetMaxSensorRange() -{ - return SensorRange(AccelRangeRamp[sizeof(AccelRangeRamp)/sizeof(AccelRangeRamp[0]) - 1] * 9.81f, - GyroRangeRamp[sizeof(GyroRangeRamp)/sizeof(GyroRangeRamp[0]) - 1] * - Math::DegreeToRadFactor, - MagRangeRamp[sizeof(MagRangeRamp)/sizeof(MagRangeRamp[0]) - 1] * 0.001f); -} - -void SensorRangeImpl::Pack() -{ - Buffer[0] = 4; - Buffer[1] = UByte(CommandId & 0xFF); - Buffer[2] = UByte(CommandId >> 8); - Buffer[3] = UByte(AccelScale); - Buffer[4] = UByte(GyroScale & 0xFF); - Buffer[5] = UByte(GyroScale >> 8); - Buffer[6] = UByte(MagScale & 0xFF); - Buffer[7] = UByte(MagScale >> 8); -} - -void SensorRangeImpl::Unpack() -{ - CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8); - AccelScale= Buffer[3]; - GyroScale = Buffer[4] | (UInt16(Buffer[5]) << 8); - MagScale = Buffer[6] | (UInt16(Buffer[7]) << 8); -} - -SensorConfigImpl::SensorConfigImpl() - : CommandId(0), Flags(0), PacketInterval(0), SampleRate(0) -{ - memset(Buffer, 0, PacketSize); - Buffer[0] = 2; -} - -void SensorConfigImpl::SetSensorCoordinates(bool sensorCoordinates) -{ - Flags = (Flags & ~Flag_SensorCoordinates) | (sensorCoordinates ? Flag_SensorCoordinates : 0); -} - -bool SensorConfigImpl::IsUsingSensorCoordinates() const -{ - return (Flags & Flag_SensorCoordinates) != 0; -} - -void SensorConfigImpl::Pack() -{ - Buffer[0] = 2; - Buffer[1] = UByte(CommandId & 0xFF); - Buffer[2] = UByte(CommandId >> 8); - Buffer[3] = Flags; - Buffer[4] = UByte(PacketInterval); - Buffer[5] = UByte(SampleRate & 0xFF); - Buffer[6] = UByte(SampleRate >> 8); -} - -void SensorConfigImpl::Unpack() -{ - CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8); - Flags = Buffer[3]; - PacketInterval = Buffer[4]; - SampleRate = Buffer[5] | (UInt16(Buffer[6]) << 8); -} - -SensorFactoryCalibrationImpl::SensorFactoryCalibrationImpl() - : AccelOffset(), GyroOffset(), AccelMatrix(), GyroMatrix(), Temperature(0) -{ - memset(Buffer, 0, PacketSize); - Buffer[0] = 3; -} - -void SensorFactoryCalibrationImpl::Pack() -{ - SInt32 x, y, z; - - Buffer[0] = 3; - - x = SInt32(AccelOffset.x * 1e4f); - y = SInt32(AccelOffset.y * 1e4f); - z = SInt32(AccelOffset.z * 1e4f); - PackSensor(Buffer + 3, x, y, z); - - x = SInt32(GyroOffset.x * 1e4f); - y = SInt32(GyroOffset.y * 1e4f); - z = SInt32(GyroOffset.z * 1e4f); - PackSensor(Buffer + 11, x, y, z); - - // ignore the scale matrices for now -} - -void SensorFactoryCalibrationImpl::Unpack() -{ - static const float sensorMax = (1 << 20) - 1; - SInt32 x, y, z; - - UnpackSensor(Buffer + 3, &x, &y, &z); - AccelOffset.y = (float) y * 1e-4f; - AccelOffset.z = (float) z * 1e-4f; - AccelOffset.x = (float) x * 1e-4f; - - UnpackSensor(Buffer + 11, &x, &y, &z); - GyroOffset.x = (float) x * 1e-4f; - GyroOffset.y = (float) y * 1e-4f; - GyroOffset.z = (float) z * 1e-4f; - - for (int i = 0; i < 3; i++) - { - UnpackSensor(Buffer + 19 + 8 * i, &x, &y, &z); - AccelMatrix.M[i][0] = (float) x / sensorMax; - AccelMatrix.M[i][1] = (float) y / sensorMax; - AccelMatrix.M[i][2] = (float) z / sensorMax; - AccelMatrix.M[i][i] += 1.0f; - } - - for (int i = 0; i < 3; i++) - { - UnpackSensor(Buffer + 43 + 8 * i, &x, &y, &z); - GyroMatrix.M[i][0] = (float) x / sensorMax; - GyroMatrix.M[i][1] = (float) y / sensorMax; - GyroMatrix.M[i][2] = (float) z / sensorMax; - GyroMatrix.M[i][i] += 1.0f; - } - - Temperature = (float) Alg::DecodeSInt16(Buffer + 67) / 100.0f; -} - -SensorKeepAliveImpl::SensorKeepAliveImpl(UInt16 interval, UInt16 commandId) - : CommandId(commandId), KeepAliveIntervalMs(interval) -{ - Pack(); -} - -void SensorKeepAliveImpl::Pack() -{ - Buffer[0] = 8; - Buffer[1] = UByte(CommandId & 0xFF); - Buffer[2] = UByte(CommandId >> 8); - Buffer[3] = UByte(KeepAliveIntervalMs & 0xFF); - Buffer[4] = UByte(KeepAliveIntervalMs >> 8); -} - -void SensorKeepAliveImpl::Unpack() -{ - CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8); - KeepAliveIntervalMs= Buffer[3] | (UInt16(Buffer[4]) << 8); -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_SensorImpl_Common.h b/LibOVR/Src/OVR_SensorImpl_Common.h deleted file mode 100644 index a7091ba..0000000 --- a/LibOVR/Src/OVR_SensorImpl_Common.h +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SensorImpl_Common.h -Content : Source common to SensorImpl and Sensor2Impl. -Created : January 21, 2014 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorImpl_Common_h -#define OVR_SensorImpl_Common_h - -#include "Kernel/OVR_System.h" -#include "OVR_Device.h" - -namespace OVR -{ - -void UnpackSensor(const UByte* buffer, SInt32* x, SInt32* y, SInt32* z); -void PackSensor(UByte* buffer, SInt32 x, SInt32 y, SInt32 z); - -// Sensor HW only accepts specific maximum range values, used to maximize -// the 16-bit sensor outputs. Use these ramps to specify and report appropriate values. -const UInt16 AccelRangeRamp[] = { 2, 4, 8, 16 }; -const UInt16 GyroRangeRamp[] = { 250, 500, 1000, 2000 }; -const UInt16 MagRangeRamp[] = { 880, 1300, 1900, 2500 }; - -UInt16 SelectSensorRampValue(const UInt16* ramp, unsigned count, - float val, float factor, const char* label); - -// SensorScaleImpl provides buffer packing logic for the Sensor Range -// record that can be applied to DK1 sensor through Get/SetFeature. We expose this -// through SensorRange class, which has different units. -struct SensorRangeImpl -{ - enum { PacketSize = 8 }; - UByte Buffer[PacketSize]; - - UInt16 CommandId; - UInt16 AccelScale; - UInt16 GyroScale; - UInt16 MagScale; - - SensorRangeImpl(const SensorRange& r, UInt16 commandId = 0); - - void SetSensorRange(const SensorRange& r, UInt16 commandId = 0); - void GetSensorRange(SensorRange* r); - - static SensorRange GetMaxSensorRange(); - - void Pack(); - void Unpack(); -}; - -struct SensorConfigImpl -{ - enum { PacketSize = 7 }; - UByte Buffer[PacketSize]; - - // Flag values for Flags. - enum { - Flag_RawMode = 0x01, - Flag_CalibrationTest = 0x02, // Internal test mode - Flag_UseCalibration = 0x04, - Flag_AutoCalibration = 0x08, - Flag_MotionKeepAlive = 0x10, - Flag_CommandKeepAlive = 0x20, - Flag_SensorCoordinates = 0x40 - }; - - UInt16 CommandId; - UByte Flags; - UInt16 PacketInterval; // LDC - This should be a UByte. Fix when you have time to test it. - UInt16 SampleRate; - - SensorConfigImpl(); - - void SetSensorCoordinates(bool sensorCoordinates); - bool IsUsingSensorCoordinates() const; - - void Pack(); - void Unpack(); -}; - -struct SensorFactoryCalibrationImpl -{ - enum { PacketSize = 69 }; - UByte Buffer[PacketSize]; - - Vector3f AccelOffset; - Vector3f GyroOffset; - Matrix4f AccelMatrix; - Matrix4f GyroMatrix; - float Temperature; - - SensorFactoryCalibrationImpl(); - - void Pack(); // Not yet implemented. - void Unpack(); -}; - - -// SensorKeepAlive - feature report that needs to be sent at regular intervals for sensor -// to receive commands. -struct SensorKeepAliveImpl -{ - enum { PacketSize = 5 }; - UByte Buffer[PacketSize]; - - UInt16 CommandId; - UInt16 KeepAliveIntervalMs; - - SensorKeepAliveImpl(UInt16 interval = 0, UInt16 commandId = 0); - - void Pack(); - void Unpack(); -}; - -struct TrackerSample -{ - SInt32 AccelX, AccelY, AccelZ; - SInt32 GyroX, GyroY, GyroZ; -}; - -enum LastCommandIdFlags -{ - LastCommandId_Shutter = 1, - LastCommandId_LEDs = 2 -}; - -} // namespace OVR - -#endif // OVR_SensorImpl_Common_h diff --git a/LibOVR/Src/OVR_SensorTimeFilter.cpp b/LibOVR/Src/OVR_SensorTimeFilter.cpp deleted file mode 100644 index ee0c385..0000000 --- a/LibOVR/Src/OVR_SensorTimeFilter.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_SensorTimeFilter.cpp -Content : Class to filter HMD time and convert it to system time -Created : December 20, 2013 -Author : Michael Antonov -Notes : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorTimeFilter.h" -#include "Kernel/OVR_Log.h" - - -#include -#include - -namespace OVR { - -// Comment out for debug logging to file -//#define OVR_TIMEFILTER_LOG_CODE( code ) code -#define OVR_TIMEFILTER_LOG_CODE( code ) - -#if defined(OVR_OS_ANDROID) - #define OVR_TIMEFILTER_LOG_FILENAME "/sdcard/TimeFilterLog.txt" -#elif defined(OVR_OS_WIN32) - #define OVR_TIMEFILTER_LOG_FILENAME "C:\\TimeFilterLog.txt" -#else - #define OVR_TIMEFILTER_LOG_FILENAME "TimeFilterLog.txt" -#endif - -OVR_TIMEFILTER_LOG_CODE( FILE* pTFLogFile = 0; ) - - -// Ideally, the following would always be true: -// - NewSampleTime > PrevSample -// - NewSampleTime < now systemTime -// - (NewSampleTime - PrevSampleTime) == integration delta, matching -// HW sample time difference + drift -// -// In practice, these issues affect us: -// - System thread can be suspended for a while -// - System de-buffering of recorded samples cause deviceTime to advance up -// much faster then system time for ~100+ samples -// - Device (DK1) and system clock granularities are high; this can -// lead to potentially having estimations in the future -// - - -// ***** TimerFilter - -SensorTimeFilter::SensorTimeFilter(const Settings& settings) -{ - FilterSettings = settings; - - ClockInitialized = false; - ClockDelta = 0; - ClockDeltaDriftPerSecond = 0; - ClockDeltaCorrectPerSecond = 0; - ClockDeltaCorrectSecondsLeft = 0; - OldClockDeltaDriftExpire = 0; - - LastLargestDeviceTime = 0; - PrevSystemTime = 0; - PastSampleResetTime = 0; - - MinWindowsCollected = 0; - MinWindowDuration = 0; // assigned later - MinWindowLastTime = 0; - MinWindowSamples = settings.MinSamples; // Force initialization - - OVR_TIMEFILTER_LOG_CODE( pTFLogFile = fopen(OVR_TIMEFILTER_LOG_FILENAME, "w+"); ) -} - - -double SensorTimeFilter::SampleToSystemTime(double sampleDeviceTime, double systemTime, - double prevResult, const char* debugTag) -{ - double clockDelta = systemTime - sampleDeviceTime + FilterSettings.ClockDeltaAdjust; - double deviceTimeDelta = sampleDeviceTime - LastLargestDeviceTime; - double result; - - // Collect a sample ClockDelta for a "MinimumWindow" or process - // the window by adjusting drift rates if it's full of samples. - // - (deviceTimeDelta < 1.0f) is a corner cases, as it would imply timestamp skip/wrap. - - if (ClockInitialized) - { - // Samples in the past commonly occur if they come from separately incrementing - // data channels. Just adjust them with ClockDelta. - - if (deviceTimeDelta < 0.0) - { - result = sampleDeviceTime + ClockDelta; - - if (result > (prevResult - 0.00001)) - goto clamp_and_log_result; - - // Consistent samples less then prevResult for indicate a back-jump or bad input. - // In this case we return prevResult for a while, then reset filter if it keeps going. - if (PastSampleResetTime < 0.0001) - { - PastSampleResetTime = systemTime + FilterSettings.PastSampleResetSeconds; - goto clamp_and_log_result; - } - else if (systemTime > PastSampleResetTime) - { - OVR_DEBUG_LOG(("SensorTimeFilter - Filtering reset due to samples in the past!\n")); - initClockSampling(sampleDeviceTime, clockDelta); - // Fall through to below, to ' PastSampleResetTime = 0.0; ' - } - else - { - goto clamp_and_log_result; - } - } - - // Most common case: Record window sample. - else if ( (deviceTimeDelta < 1.0f) && - ( (sampleDeviceTime < MinWindowLastTime) || - (MinWindowSamples < FilterSettings.MinSamples) ) ) - { - // Pick minimum ClockDelta sample. - if (clockDelta < MinWindowClockDelta) - MinWindowClockDelta = clockDelta; - MinWindowSamples++; - } - else - { - processFinishedMinWindow(sampleDeviceTime, clockDelta); - } - - PastSampleResetTime = 0.0; - } - else - { - initClockSampling(sampleDeviceTime, clockDelta); - } - - - // Clock adjustment for drift. - ClockDelta += ClockDeltaDriftPerSecond * deviceTimeDelta; - - // ClockDelta "nudging" towards last known MinWindowClockDelta. - if (ClockDeltaCorrectSecondsLeft > 0.000001) - { - double correctTimeDelta = deviceTimeDelta; - if (deviceTimeDelta > ClockDeltaCorrectSecondsLeft) - correctTimeDelta = ClockDeltaCorrectSecondsLeft; - ClockDeltaCorrectSecondsLeft -= correctTimeDelta; - - ClockDelta += ClockDeltaCorrectPerSecond * correctTimeDelta; - } - - // Record largest device time, so we know what samples to use in accumulation - // of min-window in the future. - LastLargestDeviceTime = sampleDeviceTime; - - // Compute our resulting sample time after ClockDelta adjustment. - result = sampleDeviceTime + ClockDelta; - - -clamp_and_log_result: - - OVR_TIMEFILTER_LOG_CODE( double savedResult = result; ) - - // Clamp to ensure that result >= PrevResult, or not to far in the future. - // Future clamp primarily happens in the very beginning if we are de-queuing - // system buffer full of samples. - if (result < prevResult) - { - result = prevResult; - } - if (result > (systemTime + FilterSettings.FutureClamp)) - { - result = (systemTime + FilterSettings.FutureClamp); - } - - OVR_TIMEFILTER_LOG_CODE( - - // Tag lines that were outside desired range, with '<' or '>'. - char rangeClamp = ' '; - char resultDeltaFar = ' '; - - if (savedResult > (systemTime + 0.0000001)) - rangeClamp = '>'; - if (savedResult < prevResult) - rangeClamp = '<'; - - // Tag any result delta outside desired threshold with a '*'. - if (fabs(deviceTimeDelta - (result - prevResult)) >= 0.00002) - resultDeltaFar = '*'; - - fprintf(pTFLogFile, "Res%s = %13.7f, dt = % 8.7f, ClkD = %13.6f " - "sysT = %13.6f, sysDt = %f, " - "sysDiff = % f, devT = %11.6f, ddevT = %9.6f %c%c\n", - debugTag, result, result - prevResult, ClockDelta, - systemTime, systemTime - PrevSystemTime, - -(systemTime - result), // Negatives in the past, positive > now. - sampleDeviceTime, deviceTimeDelta, rangeClamp, resultDeltaFar); - - ) // OVR_TIMEFILTER_LOG_CODE() - OVR_UNUSED(debugTag); - - // Record prior values. Useful or logging and clamping. - PrevSystemTime = systemTime; - - return result; -} - - -void SensorTimeFilter::initClockSampling(double sampleDeviceTime, double clockDelta) -{ - ClockInitialized = true; - ClockDelta = clockDelta; - ClockDeltaDriftPerSecond = 0; - OldClockDeltaDriftExpire = 0; - ClockDeltaCorrectSecondsLeft = 0; - ClockDeltaCorrectPerSecond = 0; - - MinWindowsCollected = 0; - MinWindowDuration = 0.25; - MinWindowClockDelta = clockDelta; - MinWindowLastTime = sampleDeviceTime + MinWindowDuration; - MinWindowSamples = 0; -} - - -void SensorTimeFilter::processFinishedMinWindow(double sampleDeviceTime, double clockDelta) -{ - MinRecord newRec = { MinWindowClockDelta, sampleDeviceTime }; - - double clockDeltaDiff = MinWindowClockDelta - ClockDelta; - double absClockDeltaDiff = fabs(clockDeltaDiff); - - - // Abrupt change causes Reset of minClockDelta collection. - // > 8 ms would a Large jump in a minimum sample, as those are usually stable. - // > 1 second intantaneous jump would land us here as well, as that would imply - // device being suspended, clock wrap or some other unexpected issue. - if ((absClockDeltaDiff > 0.008) || - ((sampleDeviceTime - LastLargestDeviceTime) >= 1.0)) - { - OVR_TIMEFILTER_LOG_CODE( - fprintf(pTFLogFile, - "\nMinWindow Finished: %d Samples, MinWindowClockDelta=%f, MW-CD=%f," - " ** ClockDelta Reset **\n\n", - MinWindowSamples, MinWindowClockDelta, MinWindowClockDelta-ClockDelta); - ) - - // Use old collected ClockDeltaDriftPerSecond drift value - // up to 1 minute until we collect better samples. - if (!MinRecords.IsEmpty()) - { - OldClockDeltaDriftExpire = MinRecords.GetNewest().LastSampleDeviceTime - - MinRecords.GetOldest().LastSampleDeviceTime; - if (OldClockDeltaDriftExpire > 60.0) - OldClockDeltaDriftExpire = 60.0; - OldClockDeltaDriftExpire += sampleDeviceTime; - } - - // Jump to new ClockDelta value. - if ((sampleDeviceTime - LastLargestDeviceTime) > 1.0) - ClockDelta = clockDelta; - else - ClockDelta = MinWindowClockDelta; - - ClockDeltaCorrectSecondsLeft = 0; - ClockDeltaCorrectPerSecond = 0; - - // Reset buffers, we'll be collecting a new MinWindow. - MinRecords.Reset(); - MinWindowsCollected = 0; - MinWindowDuration = 0.25; - MinWindowSamples = 0; - } - else - { - OVR_ASSERT(MinWindowSamples >= FilterSettings.MinSamples); - - double timeElapsed = 0; - - // If we have older values, use them to update clock drift in - // ClockDeltaDriftPerSecond - if (!MinRecords.IsEmpty() && (sampleDeviceTime > OldClockDeltaDriftExpire)) - { - MinRecord rec = MinRecords.GetOldest(); - - // Compute clock rate of drift. - timeElapsed = sampleDeviceTime - rec.LastSampleDeviceTime; - - // Check for divide by zero shouldn't be necessary here, but just be be safe... - if (timeElapsed > 0.000001) - { - ClockDeltaDriftPerSecond = (MinWindowClockDelta - rec.MinClockDelta) / timeElapsed; - ClockDeltaDriftPerSecond = clampRate(ClockDeltaDriftPerSecond, - FilterSettings.MaxChangeRate); - } - else - { - ClockDeltaDriftPerSecond = 0.0; - } - } - - MinRecords.AddRecord(newRec); - - - // Catchup correction nudges ClockDelta towards MinWindowClockDelta. - // These are needed because clock drift correction alone is not enough - // for past accumulated error/high-granularity clock delta changes. - // The further away we are, the stronger correction we apply. - // Correction has timeout, as we don't want it to overshoot in case - // of a large delay between samples. - - if (absClockDeltaDiff >= 0.00125) - { - // Correct large discrepancy immediately. - if (absClockDeltaDiff > 0.00175) - { - if (clockDeltaDiff > 0) - ClockDelta += (clockDeltaDiff - 0.00175); - else - ClockDelta += (clockDeltaDiff + 0.00175); - - clockDeltaDiff = MinWindowClockDelta - ClockDelta; - } - - ClockDeltaCorrectPerSecond = clockDeltaDiff; - ClockDeltaCorrectSecondsLeft = 1.0; - } - else if (absClockDeltaDiff > 0.0005) - { - ClockDeltaCorrectPerSecond = clockDeltaDiff / 8.0; - ClockDeltaCorrectSecondsLeft = 8.0; - } - else - { - ClockDeltaCorrectPerSecond = clockDeltaDiff / 15.0; - ClockDeltaCorrectSecondsLeft = 15.0; - } - - ClockDeltaCorrectPerSecond = clampRate(ClockDeltaCorrectPerSecond, - FilterSettings.MaxCorrectRate); - - OVR_TIMEFILTER_LOG_CODE( - fprintf(pTFLogFile, - "\nMinWindow Finished: %d Samples, MinWindowClockDelta=%f, MW-CD=%f," - " tileElapsed=%f, ClockChange=%f, ClockCorrect=%f\n\n", - MinWindowSamples, MinWindowClockDelta, MinWindowClockDelta-ClockDelta, - timeElapsed, ClockDeltaDriftPerSecond, ClockDeltaCorrectPerSecond); - ) - } - - // New MinClockDelta collection window. - // Switch to longer duration after first few windows. - MinWindowsCollected ++; - if (MinWindowsCollected > 5) - MinWindowDuration = 0.5; - - MinWindowClockDelta = clockDelta; - MinWindowLastTime = sampleDeviceTime + MinWindowDuration; - MinWindowSamples = 0; -} - - -} // namespace OVR - diff --git a/LibOVR/Src/OVR_SensorTimeFilter.h b/LibOVR/Src/OVR_SensorTimeFilter.h deleted file mode 100644 index 409fe66..0000000 --- a/LibOVR/Src/OVR_SensorTimeFilter.h +++ /dev/null @@ -1,226 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_SensorTimeFilter.h -Content : Class to filter HMD time and convert it to system time -Created : December 20, 2013 -Author : Michael Antonov -Notes : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorTimeFilter_h -#define OVR_SensorTimeFilter_h - -#include "Kernel/OVR_Types.h" - -namespace OVR { - - -//----------------------------------------------------------------------------------- -// ***** SensorTimeFilter - -// SensorTimeFilter converts sample device time, in seconds, to absolute system -// time. It filter maintains internal state to estimate the following: -// -// - Difference between system and device time values (ClockDelta). -// ~= (systemTime - deviceTime) -// - Drift rate between system and device clocks (ClockDeltaDriftPerSecond). -// -// Additionally, the following criteria are enforced: -// - Resulting samples must be increasing, compared to prevSample. -// - Returned sample time should not exceed 'now' system time by more then a fixed -// value. -// * Ideally this should be 0, however, enforcing this is hard when clocks -// have high discrete values. -// - Returned sample AbsoluteTime values deltas are very close to HW samples, -// adjusted by drift rate. Note that this is not always possible due to clamping, -// in which case it is better to use ScaleTimeUnit(deviceTimeDelta) -// for integration. -// -// Algorithm: We collect minimum ClockDelta on windows of -// consecutive samples (500 ms each set). Long term difference between sample -// set minimums is drift. ClockDelta is also continually nudged towards most recent -// minimum. - -class SensorTimeFilter -{ -public: - - // It may be desirable to configure these per device/platform. - // For example, rates can be tighter for DK2 because of microsecond clock. - struct Settings - { - Settings(int minSamples = 50, - double clockDeltaAdjust = -0.0002, // 200 mks in the past. - double futureClamp = 0.0008) - : MinSamples(minSamples), - ClockDeltaAdjust(clockDeltaAdjust), - // PastClamp(-0.032), - FutureClamp(futureClamp), - PastSampleResetSeconds(0.2), - MaxChangeRate(0.004), - MaxCorrectRate(0.004) - { } - - // Minimum number of samples in a window. Different number may be desirable - // based on how often samples come in. - int MinSamples; - - // Factor always added to ClockDelta, used to skew all values into the past by fixed - // value and reduce the chances we report a sample "in the future". - double ClockDeltaAdjust; - // How much away in a past can a sample be before being shifted closer to system time. - //double PastClamp; - // How much larger then systemTime can a value be? Set to 0 to clamp to null, - // put small positive value is better. - double FutureClamp; - - // How long (in system time) do we take to reset the system if a device sample. - // comes in the past. Generally, this should never happened, but exists as a way to - // address bad timing coming form firmware (temp CCove issue, presumably fixed) - // or buggy input. - double PastSampleResetSeconds; - - // Maximum drift change and near-term correction rates, in seconds. - double MaxChangeRate; - double MaxCorrectRate; - }; - - - SensorTimeFilter(const Settings& settings = Settings()); - - - // Convert device sample time to system time, driving clock drift estimation. - // Input: SampleTime, System Time - // Return: Absolute system time for sample - double SampleToSystemTime(double sampleDeviceTime, double systemTime, - double prevResult, const char* debugTag = ""); - - - // Scales device time to account for drift. - double ScaleTimeUnit(double deviceClockDelta) - { - return deviceClockDelta * (1.0 + ClockDeltaDriftPerSecond); - } - - // Return currently estimated difference between the clocks. - double GetClockDelta() const { return ClockDelta; } - - -private: - - void initClockSampling(double sampleDeviceTime, double clockDelta); - void processFinishedMinWindow(double sampleDeviceTime, double systemTime); - - static double clampRate(double rate, double limit) - { - if (rate > limit) - rate = limit; - else if (rate < -limit) - rate = -limit; - return rate; - } - - - // Describes minimum observed ClockDelta for sample set seen in the past. - struct MinRecord - { - double MinClockDelta; - double LastSampleDeviceTime; - }; - - // Circular buffer storing MinRecord(s) several minutes into the past. - // Oldest value here is used to help estimate drift. - class MinRecordBuffer - { - enum { BufferSize = 60*6 }; // 3 min - public: - - MinRecordBuffer() : Head(0), Tail(0) { } - - void Reset() { Head = Tail = 0; } - bool IsEmpty() const { return Head == Tail; } - - const MinRecord& GetOldest() const - { - OVR_ASSERT(!IsEmpty()); - return Records[Tail]; - } - const MinRecord& GetNewest() const - { - OVR_ASSERT(!IsEmpty()); - return Records[(BufferSize + Head - 1) % BufferSize]; - } - - void AddRecord(const MinRecord& rec) - { - Records[Head] = rec; - Head = advanceIndex(Head); - if (Head == Tail) - Tail = advanceIndex(Tail); - } - - private: - - static int advanceIndex(int index) - { - index++; - if (index >= BufferSize) - index = 0; - return index; - } - - MinRecord Records[BufferSize]; - int Head; // Location we will most recent entry, unused. - int Tail; // Oldest entry. - }; - - - Settings FilterSettings; - - // Clock correction state. - bool ClockInitialized; - double ClockDelta; - double ClockDeltaDriftPerSecond; - double ClockDeltaCorrectPerSecond; - double ClockDeltaCorrectSecondsLeft; - double OldClockDeltaDriftExpire; - - double LastLargestDeviceTime; - double PrevSystemTime; - // Used to reset timing if we get multiple "samples in the past" - double PastSampleResetTime; - - // "MinWindow" is a block of time during which minimum ClockDelta values - // are collected into MinWindowClockDelta. - int MinWindowsCollected; - double MinWindowDuration; // Device sample seconds - double MinWindowLastTime; - double MinWindowClockDelta; - int MinWindowSamples; - - // Historic buffer used to determine rate of clock change over time. - MinRecordBuffer MinRecords; -}; - -} // namespace OVR - -#endif // OVR_SensorTimeFilter_h diff --git a/LibOVR/Src/OVR_SerialFormat.cpp b/LibOVR/Src/OVR_SerialFormat.cpp new file mode 100644 index 0000000..0b9a95b --- /dev/null +++ b/LibOVR/Src/OVR_SerialFormat.cpp @@ -0,0 +1,451 @@ +/************************************************************************************ + +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_SerialFormat.h" + +#ifdef SERIAL_FORMAT_UNIT_TEST +#include "Kernel/OVR_Log.h" +#endif + +namespace OVR { + + +//// Serial Format Detection + +SerialFormatType DetectBufferFormat(uint8_t firstByte, int sizeInBytes) +{ + switch (firstByte) + { + case SerialFormatType_DK2: + if (sizeInBytes == 12) + { + return SerialFormatType_DK2; + } + break; + default: + break; + } + + return SerialFormatType_Invalid; +} + + +//// DK2 Helpers + +static bool ValidDK2ProductId(int x) +{ + switch (x) + { + case DK2ProductId_DK1: + case DK2ProductId_DK2: + case DK2ProductId_Refurb: + return true; + default: + break; + } + + return false; +} + +static bool ValidDK2PartId(int x) +{ + switch (x) + { + case DK2PartId_HMD: + case DK2PartId_PTC: + case DK2PartId_Carton: + return true; + default: + break; + } + + return false; +} + + +//// DK2BinarySerialFormat + +bool DK2BinarySerialFormat::FromBuffer(const uint8_t buffer[12], bool allowUnknownTypes) +{ + // Format Type must be 0 + + int formatType = buffer[0]; + + if (formatType != SerialFormatType_DK2) + { + return false; + } + + // Product Id + + int productId = buffer[1] >> 4; + + if (!allowUnknownTypes && !ValidDK2ProductId(productId)) + { + return false; + } + + ProductId = (DK2ProductId)productId; + + // Part Id + + int partId = buffer[1] & 15; + + if (!allowUnknownTypes && !ValidDK2PartId(partId)) + { + return false; + } + + PartId = (DK2PartId)partId; + + // Minutes Since Epoch (May 1, 2014) + + MinutesSinceEpoch = buffer[4] | ((uint32_t)buffer[3] << 8) | ((uint32_t)buffer[2] << 16); + + // Unit number on that day + + UnitNumber = buffer[6] | ((uint32_t)buffer[5] << 8); + + // Hash of MAC address + + MacHash[0] = buffer[7]; + MacHash[1] = buffer[8]; + MacHash[2] = buffer[9]; + MacHash[3] = buffer[10]; + MacHash[4] = buffer[11]; + + return true; +} + +void DK2BinarySerialFormat::ToBuffer(uint8_t buffer[12]) +{ + // Serialize to buffer + buffer[0] = SerialFormatType_DK2; + buffer[1] = (uint8_t)((ProductId << 4) | (PartId)); + buffer[2] = (uint8_t)(MinutesSinceEpoch >> 16); + buffer[3] = (uint8_t)(MinutesSinceEpoch >> 8); + buffer[4] = (uint8_t)MinutesSinceEpoch; + buffer[5] = (uint8_t)(UnitNumber >> 8); + buffer[6] = (uint8_t)UnitNumber; + + buffer[7] = MacHash[0]; + buffer[8] = MacHash[1]; + buffer[9] = MacHash[2]; + buffer[10] = MacHash[3]; + buffer[11] = MacHash[4]; +} + +bool DK2BinarySerialFormat::operator==(const DK2BinarySerialFormat& rhs) +{ + if (ProductId != rhs.ProductId) + return false; + if (PartId != rhs.PartId) + return false; + if (MinutesSinceEpoch != rhs.MinutesSinceEpoch) + return false; + if (UnitNumber != rhs.UnitNumber) + return false; + for (int ii = 0; ii < 5; ++ii) + { + if (MacHash[ii] != rhs.MacHash[ii]) + return false; + } + return true; +} + + +//// DK2PrintedSerialFormat + +// Base-32 Crockford decoding rules: +// 0 o O => 0 +// 1 i | I L l => 1 +// 2, 3, 4, 5, 6, 7, 8, 9 => 2 - 9 +// a, b, c, d, e, f, g, h => 10 - 17 +// j, k => 18, 19 +// m, n => 20, 21 +// p, q, r, s, t => 22, 23, 24, 25, 26 +// 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, + // (sp)!"#$%&'()*+,-./ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + // 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, + + // Extended ASCII: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +// Base-32 Crockford encoding rules: +// 0-9 => 0-9 +// 10 - 17 => a, b, c, d, e, f, g, h +// 18, 19 => j, k +// 20, 21 => m, n +// 22, 23, 24, 25, 26 => p, q, r, s, t +// 27, 28, 29, 30, 31 => v, w, x, y, z +static const char* CharFromBase32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; + +bool DK2PrintedSerialFormat::FromBase32(const char* str, bool allowUnknownTypes) +{ + // Note: Truncated strings get caught by returning negative values from the table like other invalid characters + + // Product Id + + int productId = Base32FromChar[(unsigned char)str[0]]; + if (productId < 0 || (!allowUnknownTypes && !ValidDK2ProductId(productId))) + { + return false; + } + + ProductId = (DK2ProductId)productId; + + // Label Type + + int labelType = Base32FromChar[(unsigned char)str[1]]; + if (labelType < 0 || (!allowUnknownTypes && !ValidDK2PartId(labelType))) + { + return false; + } + + LabelType = (DK2LabelType)labelType; + + uint8_t dataBytes[7]; + for (int ii = 0; ii < 7; ++ii) + { + int c = Base32FromChar[(unsigned char)str[2 + ii]]; + if (c < 0) return false; + dataBytes[ii] = (uint8_t)c; + } + + // Minutes Since Epoch + + MinutesSinceEpoch = dataBytes[3] | ((uint32_t)dataBytes[2] << 5) | ((uint32_t)dataBytes[1] << 10) | ((uint32_t)dataBytes[0] << 15); + + // Unit Number + + UnitNumber = dataBytes[6] | ((uint32_t)dataBytes[5] << 5) | ((uint32_t)dataBytes[4] << 10); + + // MAC Hash + + for (int ii = 0; ii < 3; ++ii) + { + int c = Base32FromChar[(unsigned char)str[9 + ii]]; + if (c < 0) + { + return false; + } + + MacHashLow[ii] = (uint8_t)c; + } + + // String must be exactly 12 characters + if (str[12] != '\0') + { + return false; + } + + return true; +} + +String DK2PrintedSerialFormat::ToBase32() +{ + String s; + + s += CharFromBase32[ProductId]; + s += CharFromBase32[LabelType]; + s += CharFromBase32[(MinutesSinceEpoch >> 15) & 31]; + s += CharFromBase32[(MinutesSinceEpoch >> 10) & 31]; + s += CharFromBase32[(MinutesSinceEpoch >> 5) & 31]; + s += CharFromBase32[MinutesSinceEpoch & 31]; + s += CharFromBase32[(UnitNumber >> 10) & 31]; + s += CharFromBase32[(UnitNumber >> 5) & 31]; + s += CharFromBase32[UnitNumber & 31]; + s += CharFromBase32[MacHashLow[0] & 31]; + s += CharFromBase32[MacHashLow[1] & 31]; + s += CharFromBase32[MacHashLow[2] & 31]; + + return s; +} + +bool DK2PrintedSerialFormat::operator==(const DK2PrintedSerialFormat& rhs) +{ + if (ProductId != rhs.ProductId) + return false; + if (LabelType != rhs.LabelType) + return false; + if (MinutesSinceEpoch != rhs.MinutesSinceEpoch) + return false; + if (UnitNumber != rhs.UnitNumber) + return false; + for (int ii = 0; ii < 3; ++ii) + { + if (MacHashLow[ii] != rhs.MacHashLow[ii]) + return false; + } + return true; +} + +bool DK2PrintedSerialFormat::operator==(const DK2BinarySerialFormat& rhs) +{ + if (ProductId != rhs.ProductId) + return false; + if (LabelType != rhs.PartId) + return false; + if (MinutesSinceEpoch != rhs.MinutesSinceEpoch) + return false; + if (UnitNumber != rhs.UnitNumber) + return false; + for (int ii = 0; ii < 3; ++ii) + { + if (MacHashLow[ii] != (rhs.MacHash[ii] & 31)) + return false; + } + return true; +} + +void DK2PrintedSerialFormat::FromBinary(const DK2BinarySerialFormat& bin) +{ + ProductId = bin.ProductId; + LabelType = bin.PartId; + MinutesSinceEpoch = bin.MinutesSinceEpoch; + UnitNumber = bin.UnitNumber; + MacHashLow[0] = bin.MacHash[0] & 31; + MacHashLow[1] = bin.MacHash[1] & 31; + MacHashLow[2] = bin.MacHash[2] & 31; +} + + +//// 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 new file mode 100644 index 0000000..9d9fbb7 --- /dev/null +++ b/LibOVR/Src/OVR_SerialFormat.h @@ -0,0 +1,128 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_SerialFormat.h +Content : Serial Number format tools +Created : June 12, 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_SerialFormat_h +#define OVR_SerialFormat_h + +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_String.h" + +namespace OVR { + + +//----------------------------------------------------------------------------- +// SerialFormatType enumeration + +enum SerialFormatType +{ + SerialFormatType_Invalid = -1, // Invalid format + SerialFormatType_DK2 = 0, // Format used for DK2 +}; + +// Returns the expected serial format based on the first byte of the buffer +SerialFormatType DetectBufferFormat(uint8_t firstByte, int sizeInBytes); + + +//----------------------------------------------------------------------------- +// DK2 Serial Format + +enum DK2ProductId +{ + DK2ProductId_DK1 = 1, // DK1 + DK2ProductId_DK2 = 2, // Product Id used for initial DK2 launch + DK2ProductId_Refurb = 3, // Refurbished DK2 +}; + +enum DK2PartId +{ + DK2PartId_HMD = 0, // HMD + DK2PartId_PTC = 1, // PTC(camera) + DK2PartId_Carton = 2, // Carton: An HMD + PTC combo (should not be stamped on a component) AKA Overpack +}; + +typedef DK2PartId DK2LabelType; // Printed Serial Number version + + +// DK2 tool for reading/writing the binary serial format +class DK2BinarySerialFormat +{ +public: + static const SerialFormatType FormatType = SerialFormatType_DK2; // first byte + + DK2ProductId ProductId; // [4 bits] 2 = DK2 + DK2PartId PartId; // [4 bits] 0 means HMD, 1 means PTC(camera) + int MinutesSinceEpoch; // [3 bytes] Number of minutes that have elapsed since the epoch: May 1st, 2014 + // [0] = high byte, [1] = middle byte, [2] = low byte + int UnitNumber; // [2 bytes] Value that increments each time a new serial number is created. Resets to zero each day + // [0] = high byte, [1] = low byte + uint8_t MacHash[5]; // [5 bytes] 5 most significant bytes of MD5 hash from first ethernet adapter mac address + + bool operator==(const DK2BinarySerialFormat& rhs); + +public: + // Returns false if the input is invalid in some way + bool FromBuffer(const uint8_t buffer[12], bool allowUnknownTypes = false); + + // Fills the provided buffer with 12 bytes + void ToBuffer(uint8_t buffer[12]); +}; + + +// DK2 tool for reading/writing the printed serial format +class DK2PrintedSerialFormat +{ +public: + DK2ProductId ProductId; // [1 char] 2 = DK2, 3 = Reconditioned bundle + DK2LabelType LabelType; // [1 char] 0 means HMD, 1 means PTC(camera), 2 means Overpack(bundle) + int MinutesSinceEpoch; // [4 char] Number of minutes that have elapsed since the epoch: May 1st, 2014 + int UnitNumber; // [3 char] Value that increments each time a new serial number is created. Resets to zero each day + uint8_t MacHashLow[3]; // [3 char] 3 least significant bytes of mac hash + + bool operator==(const DK2PrintedSerialFormat& rhs); + bool operator==(const DK2BinarySerialFormat& rhs); + +public: + // Convert from binary to printed + void FromBinary(const DK2BinarySerialFormat& bin); + + // Returns false if the input is invalid in some way + // Convert from a 12 character printed serial number + bool FromBase32(const char* str, bool allowUnknownTypes = false); + + // Returns a long human-readable base32 string (20 characters), NOT a printed serial number + String ToBase32(); +}; + + +//#define SERIAL_FORMAT_UNIT_TEST +#ifdef SERIAL_FORMAT_UNIT_TEST +void TestSerialFormatStuff(); +#endif + + +} // OVR + +#endif // OVR_SerialFormat_h diff --git a/LibOVR/Src/OVR_Stereo.cpp b/LibOVR/Src/OVR_Stereo.cpp index 936a02a..1b0723f 100644 --- a/LibOVR/Src/OVR_Stereo.cpp +++ b/LibOVR/Src/OVR_Stereo.cpp @@ -5,16 +5,16 @@ Content : Stereo rendering functions Created : November 30, 2013 Authors : Tom Fosyth -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -81,12 +81,43 @@ bool FitCubicPolynomial ( float *pResult, const float *pFitX, const float *pFitY return true; } - +#define TPH_SPLINE_STATISTICS 0 +#if TPH_SPLINE_STATISTICS +static float max_scaledVal = 0; +static float average_total_out_of_range = 0; +static float average_out_of_range; +static int num_total = 0; +static int num_out_of_range = 0; +static int num_out_of_range_over_1 = 0; +static int num_out_of_range_over_2 = 0; +static int num_out_of_range_over_3 = 0; +static float percent_out_of_range; +#endif float EvalCatmullRom10Spline ( float const *K, float scaledVal ) { int const NumSegments = LensConfig::NumCoefficients; + #if TPH_SPLINE_STATISTICS + //Value should be in range of 0 to (NumSegments-1) (typically 10) if spline is valid. Right? + if (scaledVal > (NumSegments-1)) + { + num_out_of_range++; + average_total_out_of_range+=scaledVal; + average_out_of_range = average_total_out_of_range / ((float) num_out_of_range); + percent_out_of_range = 100.0f*(num_out_of_range)/num_total; + } + if (scaledVal > (NumSegments-1+1)) num_out_of_range_over_1++; + if (scaledVal > (NumSegments-1+2)) num_out_of_range_over_2++; + if (scaledVal > (NumSegments-1+3)) num_out_of_range_over_3++; + num_total++; + if (scaledVal > max_scaledVal) + { + max_scaledVal = scaledVal; + max_scaledVal = scaledVal; + } + #endif + float scaledValFloor = floorf ( scaledVal ); scaledValFloor = Alg::Max ( 0.0f, Alg::Min ( (float)(NumSegments-1), scaledValFloor ) ); float t = scaledVal - scaledValFloor; @@ -401,26 +432,26 @@ enum LensConfigStoredVersion struct LensConfigStored_CatmullRom10Version1 { // All these items must be fixed-length integers - no "float", no "int", etc. - UInt16 VersionNumber; // Must be LCSV_CatmullRom10Version1 + uint16_t VersionNumber; // Must be LCSV_CatmullRom10Version1 - UInt16 K[11]; - UInt16 MaxR; - UInt16 MetersPerTanAngleAtCenter; - UInt16 ChromaticAberration[4]; + uint16_t K[11]; + uint16_t MaxR; + uint16_t MetersPerTanAngleAtCenter; + uint16_t ChromaticAberration[4]; // InvK and MaxInvR are calculated on load. }; -UInt16 EncodeFixedPointUInt16 ( float val, UInt16 zeroVal, int fractionalBits ) +uint16_t EncodeFixedPointUInt16 ( float val, uint16_t zeroVal, int fractionalBits ) { OVR_ASSERT ( ( fractionalBits >= 0 ) && ( fractionalBits < 31 ) ); float valWhole = val * (float)( 1 << fractionalBits ); valWhole += (float)zeroVal + 0.5f; valWhole = floorf ( valWhole ); OVR_ASSERT ( ( valWhole >= 0.0f ) && ( valWhole < (float)( 1 << 16 ) ) ); - return (UInt16)valWhole; + return (uint16_t)valWhole; } -float DecodeFixedPointUInt16 ( UInt16 val, UInt16 zeroVal, int fractionalBits ) +float DecodeFixedPointUInt16 ( uint16_t val, uint16_t zeroVal, int fractionalBits ) { OVR_ASSERT ( ( fractionalBits >= 0 ) && ( fractionalBits < 31 ) ); float valFloat = (float)val; @@ -431,14 +462,14 @@ float DecodeFixedPointUInt16 ( UInt16 val, UInt16 zeroVal, int fractionalBits ) // Returns true on success. -bool LoadLensConfig ( LensConfig *presult, UByte const *pbuffer, int bufferSizeInBytes ) +bool LoadLensConfig ( LensConfig *presult, uint8_t const *pbuffer, int bufferSizeInBytes ) { if ( bufferSizeInBytes < 2 ) { // Can't even tell the version number! return false; } - UInt16 version = DecodeUInt16 ( pbuffer + 0 ); + uint16_t version = DecodeUInt16 ( pbuffer + 0 ); switch ( version ) { case LCSV_CatmullRom10Version1: @@ -504,7 +535,7 @@ int SaveLensConfigSizeInBytes ( LensConfig const &config ) } // Returns true on success. -bool SaveLensConfig ( UByte *pbuffer, int bufferSizeInBytes, LensConfig const &config ) +bool SaveLensConfig ( uint8_t *pbuffer, int bufferSizeInBytes, LensConfig const &config ) { if ( bufferSizeInBytes < (int)sizeof ( LensConfigStored_CatmullRom10Version1 ) ) { @@ -532,7 +563,7 @@ bool SaveLensConfig ( UByte *pbuffer, int bufferSizeInBytes, LensConfig const &c } - // Now store them out, sensitive to endinness. + // Now store them out, sensitive to endianness. EncodeUInt16 ( pbuffer + 0, lcs.VersionNumber ); for ( int i = 0; i < 11; i++ ) { @@ -555,7 +586,7 @@ void TestSaveLoadLensConfig ( LensConfig const &config ) OVR_ASSERT ( config.Eqn == Distortion_CatmullRom10 ); // As a test, make sure this can be encoded and decoded correctly. const int bufferSize = 256; - UByte buffer[bufferSize]; + uint8_t buffer[bufferSize]; OVR_ASSERT ( SaveLensConfigSizeInBytes ( config ) < bufferSize ); bool success; success = SaveLensConfig ( buffer, bufferSize, config ); @@ -590,7 +621,8 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) HMDInfo info; if ((hmdType != HmdType_DK1) && - (hmdType != HmdType_CrystalCoveProto)) + (hmdType != HmdType_CrystalCoveProto) && + (hmdType != HmdType_DK2)) { LogText("Debug HMDInfo - HmdType not supported. Defaulting to DK1.\n"); hmdType = HmdType_DK1; @@ -611,6 +643,8 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) info.ScreenGapSizeInMeters = 0.0f; info.CenterFromTopInMeters = 0.0468f; info.LensSeparationInMeters = 0.0635f; + info.PelOffsetR = Vector2f ( 0.0f, 0.0f ); + info.PelOffsetB = Vector2f ( 0.0f, 0.0f ); info.Shutter.Type = HmdShutter_RollingTopToBottom; info.Shutter.VsyncToNextVsync = ( 1.0f / 60.0f ); info.Shutter.VsyncToFirstScanline = 0.000052f; @@ -626,6 +660,8 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) info.ScreenGapSizeInMeters = 0.0f; info.CenterFromTopInMeters = info.ScreenSizeInMeters.h * 0.5f; info.LensSeparationInMeters = 0.0635f; + info.PelOffsetR = Vector2f ( 0.0f, 0.0f ); + info.PelOffsetB = Vector2f ( 0.0f, 0.0f ); info.Shutter.Type = HmdShutter_RollingRightToLeft; info.Shutter.VsyncToNextVsync = ( 1.0f / 76.0f ); info.Shutter.VsyncToFirstScanline = 0.0000273f; @@ -641,6 +677,8 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) info.ScreenGapSizeInMeters = 0.0f; info.CenterFromTopInMeters = info.ScreenSizeInMeters.h * 0.5f; info.LensSeparationInMeters = 0.0635f; + info.PelOffsetR = Vector2f ( 0.5f, 0.5f ); + info.PelOffsetB = Vector2f ( 0.5f, 0.5f ); info.Shutter.Type = HmdShutter_RollingRightToLeft; info.Shutter.VsyncToNextVsync = ( 1.0f / 76.0f ); info.Shutter.VsyncToFirstScanline = 0.0000273f; @@ -657,14 +695,16 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) } - -// profile may be NULL, in which case it uses the hard-coded defaults. -HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, - Profile const *profile /*=NULL*/, +HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, + Profile const *profile, 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; @@ -672,6 +712,8 @@ HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, renderInfo.CenterFromTopInMeters = hmdInfo.CenterFromTopInMeters; renderInfo.ScreenGapSizeInMeters = hmdInfo.ScreenGapSizeInMeters; renderInfo.LensSeparationInMeters = hmdInfo.LensSeparationInMeters; + renderInfo.PelOffsetR = hmdInfo.PelOffsetR; + renderInfo.PelOffsetB = hmdInfo.PelOffsetB; OVR_ASSERT ( sizeof(renderInfo.Shutter) == sizeof(hmdInfo.Shutter) ); // Try to keep the files in sync! renderInfo.Shutter.Type = hmdInfo.Shutter.Type; @@ -718,15 +760,13 @@ HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, renderInfo.EyeRight = renderInfo.EyeLeft; - // Obtain data from profile. - if ( profile != NULL ) + char eyecup[16]; + if (profile->GetValue(OVR_KEY_EYE_CUP, eyecup, 16)) { - char eyecup[16]; - if (profile->GetValue(OVR_KEY_EYE_CUP, eyecup, 16)) - SetEyeCup(&renderInfo, eyecup); + SetEyeCup(&renderInfo, eyecup); } - + switch ( hmdInfo.HmdType ) { case HmdType_None: @@ -791,55 +831,61 @@ HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, default: OVR_ASSERT ( false ); break; } - if ( profile != NULL ) - { - // Set the customized user eye position - // TBD: Maybe we should separate custom camera positioning from custom distortion rendering ?? - if (profile->GetBoolValue(OVR_KEY_CUSTOM_EYE_RENDER, true)) - { - float eye2nose[2]; - if (profile->GetFloatValues(OVR_KEY_EYE_TO_NOSE_DISTANCE, eye2nose, 2) == 2) - { // Load per-eye half-IPD - renderInfo.EyeLeft.NoseToPupilInMeters = eye2nose[0]; - renderInfo.EyeRight.NoseToPupilInMeters = eye2nose[1]; - } - else - { // Use a centered IPD instead - float ipd = profile->GetFloatValue(OVR_KEY_IPD, OVR_DEFAULT_IPD); - renderInfo.EyeLeft.NoseToPupilInMeters = 0.5f * ipd; - renderInfo.EyeRight.NoseToPupilInMeters = 0.5f * ipd; - } + Profile* 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 + + 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) - { // 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, -1); - if (dial >= 0) - { - renderInfo.EyeLeft.ReliefInMeters -= ((10 - dial) * 0.001f); - renderInfo.EyeRight.ReliefInMeters -= ((10 - dial) * 0.001f); - } - } - else - { - // Set the eye relief with the user configured dial setting - int dial = profile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, -1); - if (dial >= 0) - { // 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); - } - } - } + 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(); + + // Now we know where the eyes are relative to the lenses, we can compute a distortion for each. // TODO: incorporate lateral offset in distortion generation. // TODO: we used a distortion to calculate eye-relief, and now we're making a distortion from that eye-relief. Close the loop! @@ -873,12 +919,14 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI LensConfig Config; }; - DistortionDescriptor distortions[10]; - for ( unsigned int i = 0; i < sizeof(distortions)/sizeof(distortions[0]); i++ ) + static const int MaxDistortions = 10; + DistortionDescriptor distortions[MaxDistortions]; + for (int i = 0; i < MaxDistortions; i++) { - distortions[i].Config.SetToIdentity(); distortions[i].EyeRelief = 0.0f; + memset(distortions[i].SampleRadius, 0, sizeof(distortions[i].SampleRadius)); distortions[i].MaxRadius = 1.0f; + distortions[i].Config.SetToIdentity(); // Note: This line causes a false Microsoft static analysis error -cat } int numDistortions = 0; int defaultDistortion = 0; // index of the default distortion curve to use if zero eye relief supplied @@ -889,7 +937,7 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI { numDistortions = 0; - + // Tuned at minimum dial setting - extended to r^2 == 1.8 distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10; distortions[numDistortions].EyeRelief = 0.012760465f - 0.005f; @@ -905,9 +953,6 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI distortions[numDistortions].Config.K[8] = 5.1f; distortions[numDistortions].Config.K[9] = 7.4f; distortions[numDistortions].Config.K[10] = 11.0f; - distortions[numDistortions].SampleRadius[0] = 0.222717149f; - distortions[numDistortions].SampleRadius[1] = 0.512249443f; - distortions[numDistortions].SampleRadius[2] = 0.712694878f; distortions[numDistortions].MaxRadius = sqrt(1.8f); defaultDistortion = numDistortions; // this is the default numDistortions++; @@ -927,9 +972,6 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI distortions[numDistortions].Config.K[8] = 1.6986004f; distortions[numDistortions].Config.K[9] = 1.9940577f; distortions[numDistortions].Config.K[10] = 2.4783147f; - distortions[numDistortions].SampleRadius[0] = 0.222717149f; - distortions[numDistortions].SampleRadius[1] = 0.512249443f; - distortions[numDistortions].SampleRadius[2] = 0.712694878f; distortions[numDistortions].MaxRadius = 1.0f; numDistortions++; @@ -948,12 +990,11 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI distortions[numDistortions].Config.K[8] = 1.8f; distortions[numDistortions].Config.K[9] = 2.25f; distortions[numDistortions].Config.K[10] = 3.0f; - distortions[numDistortions].SampleRadius[0] = 0.222717149f; - distortions[numDistortions].SampleRadius[1] = 0.512249443f; - distortions[numDistortions].SampleRadius[2] = 0.712694878f; distortions[numDistortions].MaxRadius = 1.0f; numDistortions++; + + // Chromatic aberration doesn't seem to change with eye relief. for ( int i = 0; i < numDistortions; i++ ) { @@ -982,14 +1023,8 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI distortions[numDistortions].Config.K[8] = 1.620f; distortions[numDistortions].Config.K[9] = 1.840f; distortions[numDistortions].Config.K[10] = 2.200f; - distortions[numDistortions].SampleRadius[0] = 0.222717149f; - distortions[numDistortions].SampleRadius[1] = 0.512249443f; - distortions[numDistortions].SampleRadius[2] = 0.712694878f; distortions[numDistortions].MaxRadius = 1.0f; - distortions[numDistortions].SampleRadius[0] = 0.405405405f; - distortions[numDistortions].SampleRadius[1] = 0.675675676f; - distortions[numDistortions].SampleRadius[2] = 0.945945946f; defaultDistortion = numDistortions; // this is the default numDistortions++; @@ -1011,42 +1046,79 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI // Tuned Crystal Cove & DK2 Lens (CES & GDC) numDistortions = 0; - distortions[numDistortions].EyeRelief = 0.010f; + + distortions[numDistortions].EyeRelief = 0.008f; distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.036f; - + // TODO: Need to retune this distortion for minimum eye relief distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10; distortions[numDistortions].Config.K[0] = 1.003f; distortions[numDistortions].Config.K[1] = 1.02f; distortions[numDistortions].Config.K[2] = 1.042f; distortions[numDistortions].Config.K[3] = 1.066f; - distortions[numDistortions].Config.K[4] = 1.094f; //1.0945f; - distortions[numDistortions].Config.K[5] = 1.126f; //1.127f; - distortions[numDistortions].Config.K[6] = 1.162f; //1.167f; - distortions[numDistortions].Config.K[7] = 1.203f; //1.218f; - distortions[numDistortions].Config.K[8] = 1.25f; //1.283f; - distortions[numDistortions].Config.K[9] = 1.31f; //1.37f; - distortions[numDistortions].Config.K[10] = 1.38f; //1.48f; + distortions[numDistortions].Config.K[4] = 1.094f; + distortions[numDistortions].Config.K[5] = 1.126f; + distortions[numDistortions].Config.K[6] = 1.162f; + distortions[numDistortions].Config.K[7] = 1.203f; + distortions[numDistortions].Config.K[8] = 1.25f; + distortions[numDistortions].Config.K[9] = 1.31f; + distortions[numDistortions].Config.K[10] = 1.38f; distortions[numDistortions].MaxRadius = 1.0f; + distortions[numDistortions].Config.ChromaticAberration[0] = -0.0112f; + distortions[numDistortions].Config.ChromaticAberration[1] = -0.015f; + distortions[numDistortions].Config.ChromaticAberration[2] = 0.0187f; + distortions[numDistortions].Config.ChromaticAberration[3] = 0.015f; - distortions[numDistortions].SampleRadius[0] = 0.405405405f; - distortions[numDistortions].SampleRadius[1] = 0.675675676f; - distortions[numDistortions].SampleRadius[2] = 0.945945946f; - defaultDistortion = numDistortions; // this is the default numDistortions++; - distortions[numDistortions] = distortions[0]; - distortions[numDistortions].EyeRelief = 0.020f; + + + + + distortions[numDistortions].EyeRelief = 0.018f; + distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.036f; + + distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10; + distortions[numDistortions].Config.K[0] = 1.003f; + distortions[numDistortions].Config.K[1] = 1.02f; + distortions[numDistortions].Config.K[2] = 1.042f; + distortions[numDistortions].Config.K[3] = 1.066f; + distortions[numDistortions].Config.K[4] = 1.094f; + distortions[numDistortions].Config.K[5] = 1.126f; + distortions[numDistortions].Config.K[6] = 1.162f; + distortions[numDistortions].Config.K[7] = 1.203f; + distortions[numDistortions].Config.K[8] = 1.25f; + distortions[numDistortions].Config.K[9] = 1.31f; + distortions[numDistortions].Config.K[10] = 1.38f; + distortions[numDistortions].MaxRadius = 1.0f; + + distortions[numDistortions].Config.ChromaticAberration[0] = -0.015f; + distortions[numDistortions].Config.ChromaticAberration[1] = -0.02f; + distortions[numDistortions].Config.ChromaticAberration[2] = 0.025f; + distortions[numDistortions].Config.ChromaticAberration[3] = 0.02f; + + defaultDistortion = numDistortions; // this is the default numDistortions++; + + /* + // Orange Lens on DK2 + distortions[numDistortions].EyeRelief = 0.010f; + distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.031f; - // Chromatic aberration doesn't seem to change with eye relief. - for ( int i = 0; i < numDistortions; i++ ) - { - distortions[i].Config.ChromaticAberration[0] = -0.015f; - distortions[i].Config.ChromaticAberration[1] = -0.02f; - distortions[i].Config.ChromaticAberration[2] = 0.025f; - distortions[i].Config.ChromaticAberration[3] = 0.02f; - } + 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 { @@ -1078,8 +1150,7 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI } } - OVR_ASSERT ( numDistortions < (sizeof(distortions)/sizeof(distortions[0])) ); - + OVR_ASSERT(numDistortions < MaxDistortions); DistortionDescriptor *pUpper = NULL; DistortionDescriptor *pLower = NULL; @@ -1161,7 +1232,8 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI fitY[0] = 1.0f; for ( int ctrlPt = 1; ctrlPt < 4; ctrlPt ++ ) { - float radiusLerp = invLerpVal * pLower->SampleRadius[ctrlPt-1] + lerpVal * pUpper->SampleRadius[ctrlPt-1]; + // SampleRadius is not valid for Distortion_RecipPoly4 types. + float radiusLerp = ( invLerpVal * pLower->MaxRadius + lerpVal * pUpper->MaxRadius ) * ( (float)ctrlPt / 4.0f ); float radiusLerpSq = radiusLerp * radiusLerp; float fitYLower = pLower->Config.DistortionFnScaleRadiusSquared ( radiusLerpSq ); float fitYUpper = pUpper->Config.DistortionFnScaleRadiusSquared ( radiusLerpSq ); @@ -1242,9 +1314,6 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI } - - - DistortionRenderDesc CalculateDistortionRenderDesc ( StereoEye eyeType, HmdRenderInfo const &hmd, const LensConfig *pLensOverride /*= NULL */ ) { @@ -1420,7 +1489,7 @@ FovPort GetPhysicalScreenFov ( StereoEye eyeType, DistortionRenderDesc const &di struct FunctionHider { static FovPort FindRange ( Vector2f from, Vector2f to, int numSteps, - DistortionRenderDesc const &distortion ) + DistortionRenderDesc const &distortionL ) { FovPort result; result.UpTan = 0.0f; @@ -1433,7 +1502,7 @@ FovPort GetPhysicalScreenFov ( StereoEye eyeType, DistortionRenderDesc const &di { float lerpFactor = stepScale * (float)step; Vector2f sample = from + (to - from) * lerpFactor; - Vector2f tanEyeAngle = TransformScreenNDCToTanFovSpace ( distortion, sample ); + Vector2f tanEyeAngle = TransformScreenNDCToTanFovSpace ( distortionL, sample ); result.LeftTan = Alg::Max ( result.LeftTan, -tanEyeAngle.x ); result.RightTan = Alg::Max ( result.RightTan, tanEyeAngle.x ); @@ -1706,21 +1775,21 @@ void TransformScreenNDCToTanFovSpaceChroma ( Vector2f *resultR, Vector2f *result } // This mimics the second half of the distortion shader's function. -Vector2f TransformTanFovSpaceToRendertargetTexUV( StereoEyeParams const &eyeParams, +Vector2f TransformTanFovSpaceToRendertargetTexUV( ScaleAndOffset2D const &eyeToSourceUV, Vector2f const &tanEyeAngle ) { Vector2f textureUV; - textureUV.x = tanEyeAngle.x * eyeParams.EyeToSourceUV.Scale.x + eyeParams.EyeToSourceUV.Offset.x; - textureUV.y = tanEyeAngle.y * eyeParams.EyeToSourceUV.Scale.y + eyeParams.EyeToSourceUV.Offset.y; + textureUV.x = tanEyeAngle.x * eyeToSourceUV.Scale.x + eyeToSourceUV.Offset.x; + textureUV.y = tanEyeAngle.y * eyeToSourceUV.Scale.y + eyeToSourceUV.Offset.y; return textureUV; } -Vector2f TransformTanFovSpaceToRendertargetNDC( StereoEyeParams const &eyeParams, +Vector2f TransformTanFovSpaceToRendertargetNDC( ScaleAndOffset2D const &eyeToSourceNDC, Vector2f const &tanEyeAngle ) { Vector2f textureNDC; - textureNDC.x = tanEyeAngle.x * eyeParams.EyeToSourceNDC.Scale.x + eyeParams.EyeToSourceNDC.Offset.x; - textureNDC.y = tanEyeAngle.y * eyeParams.EyeToSourceNDC.Scale.y + eyeParams.EyeToSourceNDC.Offset.y; + textureNDC.x = tanEyeAngle.x * eyeToSourceNDC.Scale.x + eyeToSourceNDC.Offset.x; + textureNDC.y = tanEyeAngle.y * eyeToSourceNDC.Scale.y + eyeToSourceNDC.Offset.y; return textureNDC; } diff --git a/LibOVR/Src/OVR_Stereo.h b/LibOVR/Src/OVR_Stereo.h index dd5499c..f002d14 100644 --- a/LibOVR/Src/OVR_Stereo.h +++ b/LibOVR/Src/OVR_Stereo.h @@ -1,21 +1,20 @@ /************************************************************************************ -PublicHeader: OVR.h Filename : OVR_Stereo.h Content : Stereo rendering functions Created : November 30, 2013 Authors : Tom Fosyth -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -28,7 +27,9 @@ limitations under the License. #ifndef OVR_Stereo_h #define OVR_Stereo_h -#include "OVR_Device.h" +#include "Sensors/OVR_DeviceConstants.h" +#include "Displays/OVR_Display.h" +#include "OVR_Profile.h" // CAPI Forward declaration. typedef struct ovrFovPort_ ovrFovPort; @@ -36,6 +37,9 @@ typedef struct ovrRecti_ ovrRecti; namespace OVR { +class SensorDevice; // Opaque forward declaration + + //----------------------------------------------------------------------------------- // ***** Stereo Enumerations @@ -78,7 +82,6 @@ struct FovPort FovPort(const ovrFovPort& src); operator ovrFovPort () const; - static FovPort CreateFromRadians(float horizontalFov, float verticalFov) { FovPort result; @@ -134,7 +137,6 @@ struct FovPort }; - //----------------------------------------------------------------------------------- // ***** ScaleAndOffset @@ -173,6 +175,20 @@ bool FitCubicPolynomial ( float *pResult, const float *pFitX, const float *pFitY // caused by the Rift lenses. struct LensConfig { + LensConfig() + : Eqn(Distortion_CatmullRom10) + //K() + , MaxR(0.0f) + , MetersPerTanAngleAtCenter(0.0f) + //ChromaticAberration() + //InvK() + , MaxInvR(0.0f) + { + memset(&K, 0, sizeof(K)); + memset(&ChromaticAberration, 0, sizeof(ChromaticAberration)); + memset(&InvK, 0, sizeof(InvK)); + } + // The result is a scaling applied to the distance from the center of the lens. float DistortionFnScaleRadiusSquared (float rsq) const; // x,y,z components map to r,g,b scales. @@ -222,12 +238,12 @@ struct LensConfig // For internal use - storing and loading lens config data // Returns true on success. -bool LoadLensConfig ( LensConfig *presult, UByte const *pbuffer, int bufferSizeInBytes ); +bool LoadLensConfig ( LensConfig *presult, uint8_t const *pbuffer, int bufferSizeInBytes ); // Returns number of bytes needed. int SaveLensConfigSizeInBytes ( LensConfig const &config ); // Returns true on success. -bool SaveLensConfig ( UByte *pbuffer, int bufferSizeInBytes, LensConfig const &config ); +bool SaveLensConfig ( uint8_t *pbuffer, int bufferSizeInBytes, LensConfig const &config ); //----------------------------------------------------------------------------------- @@ -248,6 +264,197 @@ struct DistortionRenderDesc }; +//------------------------------------------------------------------------------------- +// ***** HMDInfo + +// This structure describes various aspects of the HMD allowing us to configure rendering. +// +// Currently included data: +// - Physical screen dimensions, resolution, and eye distances. +// (some of these will be configurable with a tool in the future). +// These arguments allow us to properly setup projection across HMDs. +// - DisplayDeviceName for identifying HMD screen; system-specific interpretation. +// +// TBD: +// - Power on/ off? +// - Sensor rates and capabilities +// - Distortion radius/variables +// - Screen update frequency +// - Distortion needed flag +// - Update modes: +// 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 +{ + int DeviceNumber; + int NativeWidth; + int NativeHeight; + int Rotation; + int UseMirroring; + + Win32ShimInfo() : + DeviceNumber(-1), + NativeWidth(-1), + NativeHeight(-1), + Rotation(-1), + UseMirroring(1) + { + } +}; + +class HMDInfo +{ +public: + // Name string describing the product: "Oculus Rift DK1", etc. + String ProductName; + String Manufacturer; + + unsigned Version; + + // Characteristics of the HMD screen and enclosure + HmdTypeEnum HmdType; + Size ResolutionInPixels; + Size ScreenSizeInMeters; + float ScreenGapSizeInMeters; + float CenterFromTopInMeters; + float LensSeparationInMeters; + 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 + { + HmdShutterTypeEnum Type; + float VsyncToNextVsync; // 1/framerate + float VsyncToFirstScanline; // for global shutter, vsync->shutter open. + float FirstScanlineToLastScanline; // for global shutter, will be zero. + float PixelSettleTime; // estimated. + float PixelPersistence; // Full persistence = 1/framerate. + } Shutter; + + // Desktop coordinate position of the screen (can be negative; may not be present on all platforms) + int DesktopX; + int DesktopY; + + // Windows: + // "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC. + String DisplayDeviceName; + Win32ShimInfo ShimInfo; + + // MacOS: + int DisplayId; + + bool InCompatibilityMode; + + // Printed serial number for the HMD; should match external sticker + String PrintedSerial; + + // Tracker descriptor information: + int VendorId; + int ProductId; + int FirmwareMajor; + int FirmwareMinor; + + float CameraFrustumHFovInRadians; + float CameraFrustumVFovInRadians; + float CameraFrustumNearZInMeters; + float CameraFrustumFarZInMeters; + + // Constructor initializes all values to 0s. + // To create a "virtualized" HMDInfo, use CreateDebugHMDInfo instead. + HMDInfo() : + ProductName(), + Manufacturer(), + Version(0), + HmdType(HmdType_None), + ResolutionInPixels(0), + ScreenSizeInMeters(0.0f), + ScreenGapSizeInMeters(0.0f), + CenterFromTopInMeters(0), + LensSeparationInMeters(0), + PelOffsetR(0.0f,0.0f), + PelOffsetB(0.0f,0.0f), + //Shutter (initialized below) + DesktopX(0), + DesktopY(0), + DisplayDeviceName(), + ShimInfo(), + DisplayId(-1), + InCompatibilityMode(false), + PrintedSerial(), + VendorId(-1), + ProductId(-1), + FirmwareMajor(-1), + FirmwareMinor(-1), + CameraFrustumHFovInRadians(0.0f), + CameraFrustumVFovInRadians(0.0f), + CameraFrustumNearZInMeters(0.0f), + CameraFrustumFarZInMeters(0.0f) + { + Shutter.Type = HmdShutter_LAST; + Shutter.VsyncToNextVsync = 0.0f; + Shutter.VsyncToFirstScanline = 0.0f; + Shutter.FirstScanlineToLastScanline = 0.0f; + Shutter.PixelSettleTime = 0.0f; + Shutter.PixelPersistence = 0.0f; + } + + // Operator = copies local fields only (base class must be correct already) + void operator=(const HMDInfo& src) + { + ProductName = src.ProductName; + Manufacturer = src.Manufacturer; + Version = src.Version; + HmdType = src.HmdType; + ResolutionInPixels = src.ResolutionInPixels; + ScreenSizeInMeters = src.ScreenSizeInMeters; + ScreenGapSizeInMeters = src.ScreenGapSizeInMeters; + CenterFromTopInMeters = src.CenterFromTopInMeters; + LensSeparationInMeters = src.LensSeparationInMeters; + PelOffsetR = src.PelOffsetR; + PelOffsetB = src.PelOffsetB; + DesktopX = src.DesktopX; + DesktopY = src.DesktopY; + Shutter = src.Shutter; + DisplayDeviceName = src.DisplayDeviceName; + ShimInfo = src.ShimInfo; + DisplayId = src.DisplayId; + InCompatibilityMode = src.InCompatibilityMode; + VendorId = src.VendorId; + ProductId = src.ProductId; + FirmwareMajor = src.FirmwareMajor; + FirmwareMinor = src.FirmwareMinor; + PrintedSerial = src.PrintedSerial; + CameraFrustumHFovInRadians = src.CameraFrustumHFovInRadians; + CameraFrustumVFovInRadians = src.CameraFrustumVFovInRadians; + CameraFrustumNearZInMeters = src.CameraFrustumNearZInMeters; + CameraFrustumFarZInMeters = src.CameraFrustumFarZInMeters; + } + + void SetScreenParameters(int hres, int vres, + float hsize, float vsize, + float vCenterFromTopInMeters, float lensSeparationInMeters, + bool compatibilityMode) + { + ResolutionInPixels = Sizei(hres, vres); + ScreenSizeInMeters = Sizef(hsize, vsize); + CenterFromTopInMeters = vCenterFromTopInMeters; + LensSeparationInMeters = lensSeparationInMeters; + InCompatibilityMode = compatibilityMode; + } + + bool IsSameDisplay(const HMDInfo& o) const + { + return DisplayId == o.DisplayId && + DisplayDeviceName.CompareNoCase(o.DisplayDeviceName) == 0; + } + + static bool CreateFromSensorAndDisplay(SensorDevice* sensor, Display* display, HMDInfo* hmdi); +}; + //----------------------------------------------------------------------------------- // ***** HmdRenderInfo @@ -256,7 +463,7 @@ struct DistortionRenderDesc struct HmdRenderInfo { - // The start of this sturucture is intentionally very similar to HMDInfo in OVER_Device.h + // The start of this structure is intentionally very similar to HMDInfo in OVER_Device.h // However to reduce interdependencies, one does not simply #include the other. HmdTypeEnum HmdType; @@ -265,6 +472,8 @@ struct HmdRenderInfo Size ResolutionInPixels; Size ScreenSizeInMeters; float ScreenGapSizeInMeters; + Vector2f PelOffsetR; // Offsets from the green pel in pixels (i.e. usual values are 0.5 or 0.333) + Vector2f PelOffsetB; // Characteristics of the lenses. float CenterFromTopInMeters; @@ -309,6 +518,8 @@ struct HmdRenderInfo LensSeparationInMeters = 0.0f; LensDiameterInMeters = 0.0f; LensSurfaceToMidplateInMeters = 0.0f; + PelOffsetR = Vector2f ( 0.0f, 0.0f ); + PelOffsetB = Vector2f ( 0.0f, 0.0f ); Shutter.Type = HmdShutter_LAST; Shutter.VsyncToNextVsync = 0.0f; Shutter.VsyncToFirstScanline = 0.0f; @@ -336,14 +547,12 @@ struct HmdRenderInfo }; - - //----------------------------------------------------------------------------------- // Stateless computation functions, in somewhat recommended execution order. // For examples on how to use many of them, see the StereoConfig::UpdateComputedState function. -const float OVR_DEFAULT_EXTRA_EYE_ROTATION = 30.0f * Math::DegreeToRadFactor; +const float OVR_DEFAULT_EXTRA_EYE_ROTATION = 30.0f * MATH_FLOAT_DEGREETORADFACTOR; // Creates a dummy debug HMDInfo matching a particular HMD model. // Useful for development without an actual HMD attached. @@ -409,7 +618,7 @@ ScaleAndOffset2D CreateUVScaleAndOffsetfromNDCScaleandOffset ( ScaleAndOffset struct StereoEyeParams { StereoEye Eye; - Matrix4f ViewAdjust; // Translation to be applied to view matrix. + Matrix4f HmdToEyeViewOffset; // Translation to be applied to view matrix. // Distortion and the VP on the physical display - the thing to run the distortion shader on. DistortionRenderDesc Distortion; @@ -431,9 +640,9 @@ Vector2f TransformScreenNDCToTanFovSpace ( DistortionRenderDesc const &distortio void TransformScreenNDCToTanFovSpaceChroma ( Vector2f *resultR, Vector2f *resultG, Vector2f *resultB, DistortionRenderDesc const &distortion, const Vector2f &framebufferNDC ); -Vector2f TransformTanFovSpaceToRendertargetTexUV ( StereoEyeParams const &eyeParams, +Vector2f TransformTanFovSpaceToRendertargetTexUV ( ScaleAndOffset2D const &eyeToSourceUV, Vector2f const &tanEyeAngle ); -Vector2f TransformTanFovSpaceToRendertargetNDC ( StereoEyeParams const &eyeParams, +Vector2f TransformTanFovSpaceToRendertargetNDC ( ScaleAndOffset2D const &eyeToSourceNDC, Vector2f const &tanEyeAngle ); Vector2f TransformScreenPixelToScreenNDC( Recti const &distortionViewport, Vector2f const &pixel ); @@ -455,6 +664,18 @@ Vector2f TransformTanFovSpaceToScreenNDC( DistortionRenderDesc const &distortion Vector2f TransformRendertargetNDCToTanFovSpace( const ScaleAndOffset2D &eyeToSourceNDC, const Vector2f &textureNDC ); +// Handy wrappers. +inline Vector2f TransformTanFovSpaceToRendertargetTexUV ( StereoEyeParams const &eyeParams, + Vector2f const &tanEyeAngle ) +{ + return TransformTanFovSpaceToRendertargetTexUV ( eyeParams.EyeToSourceUV, tanEyeAngle ); +} +inline Vector2f TransformTanFovSpaceToRendertargetNDC ( StereoEyeParams const &eyeParams, + Vector2f const &tanEyeAngle ) +{ + return TransformTanFovSpaceToRendertargetNDC ( eyeParams.EyeToSourceNDC, tanEyeAngle ); +} + } //namespace OVR -#endif // OVR_Stereo_h \ No newline at end of file +#endif // OVR_Stereo_h diff --git a/LibOVR/Src/OVR_ThreadCommandQueue.cpp b/LibOVR/Src/OVR_ThreadCommandQueue.cpp deleted file mode 100644 index bc0d7dc..0000000 --- a/LibOVR/Src/OVR_ThreadCommandQueue.cpp +++ /dev/null @@ -1,380 +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, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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 - }; - - UByte* pBuffer; - UPInt Size; - UPInt Tail; // Byte offset of next item to be popped. - UPInt Head; // Byte offset of where next push will take place. - UPInt End; // When Head < Tail, this is used instead of Size. - - inline UPInt roundUpSize(UPInt size) - { return (size + AlignMask) & ~(UPInt)AlignMask; } - -public: - - CircularBuffer(UPInt size) - : Size(size), Tail(0), Head(0), End(0) - { - pBuffer = (UByte*)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. - UByte* Write(UPInt size); - - // Returns a pointer to next available data block; 0 if none available. - UByte* ReadBegin() - { return (Head != Tail) ? (pBuffer + Tail) : 0; } - // Consumes data of specified size; this must match size passed to Write. - void ReadEnd(UPInt size); -}; - - -// Allocates a state block of specified size and advances pointers, -// returning 0 if buffer is full. -UByte* CircularBuffer::Write(UPInt size) -{ - UByte* 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(UPInt 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) - { - } - ~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; -}; - - - -ThreadCommandQueueImpl::~ThreadCommandQueueImpl() -{ - Lock::Locker lock(&QueueLock); - OVR_ASSERT(BlockedProducers.IsEmpty()); - FreeNotifyEvents_NTS(); -} - -bool ThreadCommandQueueImpl::PushCommand(const ThreadCommand& command) -{ - ThreadCommand::NotifyEvent* completeEvent = 0; - ThreadCommand::NotifyEvent* queueAvailableEvent = 0; - - // Repeat writing command into buffer until it is available. - do { - - { // 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(); - UByte* 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(); - - } while(1); - - // 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) -{ - Lock::Locker lock(&QueueLock); - - UByte* 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/OVR_ThreadCommandQueue.h b/LibOVR/Src/OVR_ThreadCommandQueue.h deleted file mode 100644 index 9774212..0000000 --- a/LibOVR/Src/OVR_ThreadCommandQueue.h +++ /dev/null @@ -1,319 +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, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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 }; - - UPInt Size; - union { - UByte Buffer[MaxSize]; - UPInt Align; - }; - - ThreadCommand* toCommand() const { return (ThreadCommand*)Buffer; } - - public: - PopBuffer() : Size(0) { } - ~PopBuffer(); - - void InitFromBuffer(void* data); - - bool HasCommand() const { return Size != 0; } - UPInt 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 Size; - bool WaitFlag; - bool ExitFlag; // Marks the last exit command. - NotifyEvent* pEvent; - - ThreadCommand(UPInt size, bool waitFlag, bool exitFlag = false) - : Size((UInt16)size), WaitFlag(waitFlag), ExitFlag(exitFlag), pEvent(0) { } - virtual ~ThreadCommand() { } - - bool NeedsWait() const { return WaitFlag; } - UPInt 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; -}; - - -} - -#endif // OVR_ThreadCommandQueue_h diff --git a/LibOVR/Src/OVR_Win32_DeviceManager.cpp b/LibOVR/Src/OVR_Win32_DeviceManager.cpp deleted file mode 100644 index 1c14bbf..0000000 --- a/LibOVR/Src/OVR_Win32_DeviceManager.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_DeviceManager.cpp -Content : Win32 implementation of DeviceManager. -Created : September 21, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceManager.h" - -// Sensor & HMD Factories -#include "OVR_SensorImpl.h" -#include "OVR_LatencyTestImpl.h" -#include "OVR_Win32_HMDDevice.h" -#include "OVR_Win32_DeviceStatus.h" -#include "OVR_Win32_HIDDevice.h" - -#include "Kernel/OVR_Timer.h" -#include "Kernel/OVR_Std.h" -#include "Kernel/OVR_Log.h" - -DWORD Debug_WaitedObjectCount = 0; - -namespace OVR { namespace Win32 { - - -//------------------------------------------------------------------------------------- -// **** Win32::DeviceManager - -DeviceManager::DeviceManager() -{ - HidDeviceManager = *HIDDeviceManager::CreateInternal(this); -} - -DeviceManager::~DeviceManager() -{ - // make sure Shutdown was called. - OVR_ASSERT(!pThread); -} - -bool DeviceManager::Initialize(DeviceBase*) -{ - if (!DeviceManagerImpl::Initialize(0)) - return false; - - pThread = *new DeviceManagerThread(this); - if (!pThread || !pThread->Start()) - return false; - - pCreateDesc->pDevice = this; - LogText("OVR::DeviceManager - initialized.\n"); - return true; -} - -void DeviceManager::Shutdown() -{ - LogText("OVR::DeviceManager - shutting down.\n"); - - // Set Manager shutdown marker variable; this prevents - // any existing DeviceHandle objects from accessing device. - pCreateDesc->pLock->pManager = 0; - - // Push for thread shutdown *WITH NO WAIT*. - // This will have the following effect: - // - Exit command will get enqueued, which will be executed later on the thread itself. - // - Beyond this point, this DeviceManager object may be deleted by our caller. - // - Other commands, such as CreateDevice, may execute before ExitCommand, but they will - // fail gracefully due to pLock->pManager == 0. Future commands can't be enqued - // after pManager is null. - // - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last - // reference to the thread object. - pThread->PushExitCommand(false); - pThread->DetachDeviceManager(); - pThread.Clear(); - - DeviceManagerImpl::Shutdown(); -} - -ThreadCommandQueue* DeviceManager::GetThreadQueue() -{ - return pThread; -} - -bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const -{ - if ((info->InfoClassType != Device_Manager) && - (info->InfoClassType != Device_None)) - return false; - - info->Type = Device_Manager; - info->Version = 0; - info->ProductName = "DeviceManager"; - info->Manufacturer = "Oculus VR, Inc."; - return true; -} - -DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args) -{ - // TBD: Can this be avoided in the future, once proper device notification is in place? - if (GetThreadId() != OVR::GetCurrentThreadId()) - { - pThread->PushCall((DeviceManagerImpl*)this, - &DeviceManager::EnumerateAllFactoryDevices, true); - } - else - DeviceManager::EnumerateAllFactoryDevices(); - - return DeviceManagerImpl::EnumerateDevicesEx(args); -} - -ThreadId DeviceManager::GetThreadId() const -{ - return pThread->GetThreadId(); -} - -bool DeviceManager::GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const -{ - if (GetHIDDeviceManager()) - return static_cast(GetHIDDeviceManager())->GetHIDDeviceDesc(path, pdevDesc); - return false; -} - - -//------------------------------------------------------------------------------------- -// ***** DeviceManager Thread - -DeviceManagerThread::DeviceManagerThread(DeviceManager* pdevMgr) - : Thread(ThreadStackSize), hCommandEvent(0), pDeviceMgr(pdevMgr) -{ - // Create a non-signaled manual-reset event. - hCommandEvent = ::CreateEvent(0, TRUE, FALSE, 0); - if (!hCommandEvent) - return; - - // Must add event before starting. - AddOverlappedEvent(0, hCommandEvent); - - // Create device messages object. - pStatusObject = *new DeviceStatus(this); -} - -DeviceManagerThread::~DeviceManagerThread() -{ - // Remove overlapped event [0], after thread service exit. - if (hCommandEvent) - { - RemoveOverlappedEvent(0, hCommandEvent); - ::CloseHandle(hCommandEvent); - hCommandEvent = 0; - } -} - -int DeviceManagerThread::Run() -{ - ThreadCommand::PopBuffer command; - - SetThreadName("OVR::DeviceManagerThread"); - LogText("OVR::DeviceManagerThread - running (ThreadId=0x%X).\n", GetThreadId()); - - if (!pStatusObject->Initialize()) - { - LogText("OVR::DeviceManagerThread - failed to initialize MessageObject.\n"); - } - - while(!IsExiting()) - { - // PopCommand will reset event on empty queue. - if (PopCommand(&command)) - { - command.Execute(); - } - else - { - DWORD eventIndex = 0; - do { - UPInt numberOfWaitHandles = WaitHandles.GetSize(); - Debug_WaitedObjectCount = (DWORD)numberOfWaitHandles; - - DWORD waitMs = INFINITE; - - // If devices have time-dependent logic registered, get the longest wait - // allowed based on current ticks. - if (!TicksNotifiers.IsEmpty()) - { - double timeSeconds = Timer::GetSeconds(); - DWORD waitAllowed; - - for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++) - { - waitAllowed = (DWORD)(TicksNotifiers[j]->OnTicks(timeSeconds) * Timer::MsPerSecond); - if (waitAllowed < waitMs) - waitMs = waitAllowed; - } - } - - // Wait for event signals or window messages. - eventIndex = MsgWaitForMultipleObjects((DWORD)numberOfWaitHandles, &WaitHandles[0], FALSE, waitMs, QS_ALLINPUT); - - if (eventIndex != WAIT_FAILED) - { - if (eventIndex == WAIT_TIMEOUT) - continue; - - // TBD: Does this ever apply? - OVR_ASSERT(eventIndex < WAIT_ABANDONED_0); - - if (eventIndex == WAIT_OBJECT_0) - { - // Handle [0] services commands. - break; - } - else if (eventIndex == WAIT_OBJECT_0 + numberOfWaitHandles) - { - // Handle Windows messages. - pStatusObject->ProcessMessages(); - } - else - { - // Notify waiting device that its event is signaled. - unsigned i = eventIndex - WAIT_OBJECT_0; - OVR_ASSERT(i < numberOfWaitHandles); - if (WaitNotifiers[i]) - WaitNotifiers[i]->OnOverlappedEvent(WaitHandles[i]); - } - } - - } while(eventIndex != WAIT_FAILED); - - } - } - - pStatusObject->ShutDown(); - - LogText("OVR::DeviceManagerThread - exiting (ThreadId=0x%X).\n", GetThreadId()); - return 0; -} - -bool DeviceManagerThread::AddOverlappedEvent(Notifier* notify, HANDLE hevent) -{ - WaitNotifiers.PushBack(notify); - WaitHandles.PushBack(hevent); - - OVR_ASSERT(WaitNotifiers.GetSize() <= MAXIMUM_WAIT_OBJECTS); - return true; -} - -bool DeviceManagerThread::RemoveOverlappedEvent(Notifier* notify, HANDLE hevent) -{ - // [0] is reserved for thread commands with notify of null, but we still - // can use this function to remove it. - for (UPInt i = 0; i < WaitNotifiers.GetSize(); i++) - { - if ((WaitNotifiers[i] == notify) && (WaitHandles[i] == hevent)) - { - WaitNotifiers.RemoveAt(i); - WaitHandles.RemoveAt(i); - return true; - } - } - return false; -} - -bool DeviceManagerThread::AddTicksNotifier(Notifier* notify) -{ - TicksNotifiers.PushBack(notify); - return true; -} - -bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify) -{ - for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++) - { - if (TicksNotifiers[i] == notify) - { - TicksNotifiers.RemoveAt(i); - return true; - } - } - return false; -} - -bool DeviceManagerThread::AddMessageNotifier(Notifier* notify) -{ - MessageNotifiers.PushBack(notify); - return true; -} - -bool DeviceManagerThread::RemoveMessageNotifier(Notifier* notify) -{ - for (UPInt i = 0; i < MessageNotifiers.GetSize(); i++) - { - if (MessageNotifiers[i] == notify) - { - MessageNotifiers.RemoveAt(i); - return true; - } - } - return false; -} - -bool DeviceManagerThread::OnMessage(MessageType type, const String& devicePath) -{ - Notifier::DeviceMessageType notifierMessageType = Notifier::DeviceMessage_DeviceAdded; - if (type == DeviceAdded) - { - } - else if (type == DeviceRemoved) - { - notifierMessageType = Notifier::DeviceMessage_DeviceRemoved; - } - else - { - OVR_ASSERT(false); - } - - bool error = false; - bool deviceFound = false; - for (UPInt i = 0; i < MessageNotifiers.GetSize(); i++) - { - if (MessageNotifiers[i] && - MessageNotifiers[i]->OnDeviceMessage(notifierMessageType, devicePath, &error)) - { - // The notifier belonged to a device with the specified device name so we're done. - deviceFound = true; - break; - } - } - if (type == DeviceAdded && !deviceFound) - { - Lock::Locker devMgrLock(&DevMgrLock); - // a new device was connected. Go through all device factories and - // try to detect the device using HIDDeviceDesc. - HIDDeviceDesc devDesc; - if (pDeviceMgr->GetHIDDeviceDesc(devicePath, &devDesc)) - { - Lock::Locker deviceLock(pDeviceMgr->GetLock()); - DeviceFactory* factory = pDeviceMgr->Factories.GetFirst(); - while(!pDeviceMgr->Factories.IsNull(factory)) - { - if (factory->DetectHIDDevice(pDeviceMgr, devDesc)) - { - deviceFound = true; - break; - } - factory = factory->pNext; - } - } - } - - if (!deviceFound && strstr(devicePath.ToCStr(), "#OVR00")) - { - Ptr pmgr; - { - Lock::Locker devMgrLock(&DevMgrLock); - pmgr = pDeviceMgr; - } - // HMD plugged/unplugged - // This is not a final solution to enumerate HMD devices and get - // a first available handle. This won't work with multiple rifts. - // @TODO (!AB) - pmgr->EnumerateDevices(); - } - - return !error; -} - -void DeviceManagerThread::DetachDeviceManager() -{ - Lock::Locker devMgrLock(&DevMgrLock); - pDeviceMgr = NULL; -} - -} // namespace Win32 - - -//------------------------------------------------------------------------------------- -// ***** Creation - - -// Creates a new DeviceManager and initializes OVR. -DeviceManager* DeviceManager::Create() -{ - - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr manager = *new Win32::DeviceManager; - - if (manager) - { - if (manager->Initialize(0)) - { - manager->AddFactory(&SensorDeviceFactory::GetInstance()); - manager->AddFactory(&LatencyTestDeviceFactory::GetInstance()); - manager->AddFactory(&Win32::HMDDeviceFactory::GetInstance()); - - manager->AddRef(); - } - else - { - manager.Clear(); - } - - } - - return manager.GetPtr(); -} - - -} // namespace OVR - diff --git a/LibOVR/Src/OVR_Win32_DeviceManager.h b/LibOVR/Src/OVR_Win32_DeviceManager.h deleted file mode 100644 index 36901eb..0000000 --- a/LibOVR/Src/OVR_Win32_DeviceManager.h +++ /dev/null @@ -1,157 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_DeviceManager.h -Content : Win32-specific DeviceManager header. -Created : September 21, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceManager_h -#define OVR_Win32_DeviceManager_h - -#include "OVR_DeviceImpl.h" -#include "OVR_Win32_DeviceStatus.h" - -#include "Kernel/OVR_Timer.h" - - -namespace OVR { namespace Win32 { - -class DeviceManagerThread; - -//------------------------------------------------------------------------------------- -// ***** Win32 DeviceManager - -class DeviceManager : public DeviceManagerImpl -{ -public: - DeviceManager(); - ~DeviceManager(); - - // Initialize/Shutdowncreate and shutdown manger thread. - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - virtual ThreadCommandQueue* GetThreadQueue(); - virtual ThreadId GetThreadId() const; - - virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args); - - virtual bool GetDeviceInfo(DeviceInfo* info) const; - - // Fills HIDDeviceDesc by using the path. - // Returns 'true' if successful, 'false' otherwise. - bool GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const; - - Ptr pThread; -}; - -//------------------------------------------------------------------------------------- -// ***** Device Manager Background Thread - -class DeviceManagerThread : public Thread, public ThreadCommandQueue, public DeviceStatus::Notifier -{ - friend class DeviceManager; - enum { ThreadStackSize = 32 * 1024 }; -public: - DeviceManagerThread(DeviceManager* pdevMgr); - ~DeviceManagerThread(); - - virtual int Run(); - - // ThreadCommandQueue notifications for CommandEvent handling. - virtual void OnPushNonEmpty_Locked() { ::SetEvent(hCommandEvent); } - virtual void OnPopEmpty_Locked() { ::ResetEvent(hCommandEvent); } - - - // Notifier used for different updates (EVENT or regular timing or messages). - class Notifier - { - public: - // Called when overlapped I/O handle is signaled. - virtual void OnOverlappedEvent(HANDLE hevent) { OVR_UNUSED1(hevent); } - - // Called when timing ticks are updated. - // Returns the largest number of seconds this function can - // wait till next call. - virtual double OnTicks(double tickSeconds) - { OVR_UNUSED1(tickSeconds); return 1000.0; } - - enum DeviceMessageType - { - DeviceMessage_DeviceAdded = 0, - DeviceMessage_DeviceRemoved = 1, - }; - - // Called to notify device object. - virtual bool OnDeviceMessage(DeviceMessageType messageType, - const String& devicePath, - bool* error) - { OVR_UNUSED3(messageType, devicePath, error); return false; } - }; - - - // Adds device's OVERLAPPED structure for I/O. - // After it's added, Overlapped object will be signaled if a message arrives. - bool AddOverlappedEvent(Notifier* notify, HANDLE hevent); - bool RemoveOverlappedEvent(Notifier* notify, HANDLE hevent); - - // Add notifier that will be called at regular intervals. - bool AddTicksNotifier(Notifier* notify); - bool RemoveTicksNotifier(Notifier* notify); - - bool AddMessageNotifier(Notifier* notify); - bool RemoveMessageNotifier(Notifier* notify); - - // DeviceStatus::Notifier interface. - bool OnMessage(MessageType type, const String& devicePath); - - void DetachDeviceManager(); - -private: - bool threadInitialized() { return hCommandEvent != 0; } - - // Event used to wake us up thread commands are enqueued. - HANDLE hCommandEvent; - - // Event notifications for devices whose OVERLAPPED I/O we service. - // This list is modified through AddDeviceOverlappedEvent. - // WaitHandles[0] always == hCommandEvent, with null device. - ArrayPOD WaitHandles; - ArrayPOD WaitNotifiers; - - // Ticks notifiers - used for time-dependent events such as keep-alive. - ArrayPOD TicksNotifiers; - - // Message notifiers. - ArrayPOD MessageNotifiers; - - // Object that manages notifications originating from Windows messages. - Ptr pStatusObject; - - Lock DevMgrLock; - // pDeviceMgr should be accessed under DevMgrLock - DeviceManager* pDeviceMgr; // back ptr, no addref. -}; - -}} // namespace Win32::OVR - -#endif // OVR_Win32_DeviceManager_h diff --git a/LibOVR/Src/OVR_Win32_DeviceStatus.cpp b/LibOVR/Src/OVR_Win32_DeviceStatus.cpp deleted file mode 100644 index 1dfcd6a..0000000 --- a/LibOVR/Src/OVR_Win32_DeviceStatus.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_DeviceStatus.cpp -Content : Win32 implementation of DeviceStatus. -Created : January 24, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceStatus.h" - -#include "OVR_Win32_HIDDevice.h" - -#include "Kernel/OVR_Log.h" - -#include - -namespace OVR { namespace Win32 { - -static TCHAR windowClassName[] = TEXT("LibOVR_DeviceStatus_WindowClass"); - -#define STATIC_KSCATEGORY_VIDEO_CAMERA \ - 0xe5323777, 0xf976, 0x4f5b, { 0x9b, 0x55, 0xb9, 0x46, 0x99, 0xc4, 0x6e, 0x44 } - - -//------------------------------------------------------------------------------------- -DeviceStatus::DeviceStatus(Notifier* const pClient) - : pNotificationClient(pClient), LastTimerId(0) -{ -} - -bool DeviceStatus::Initialize() -{ - - WNDCLASS wndClass; - wndClass.style = CS_HREDRAW | CS_VREDRAW; - wndClass.lpfnWndProc = WindowsMessageCallback; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = 0; - wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); - wndClass.lpszMenuName = NULL; - wndClass.lpszClassName = windowClassName; - - if (!RegisterClass(&wndClass)) - { - OVR_ASSERT_LOG(false, ("Failed to register window class.")); - return false; - } - - // We're going to create a 'message-only' window. This will be hidden, can't be enumerated etc. - // To do this we supply 'HWND_MESSAGE' as the hWndParent. - // http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only - hMessageWindow = CreateWindow( windowClassName, - windowClassName, - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - HWND_MESSAGE, - NULL, - 0, - this); // Pass this object via the CREATESTRUCT mechanism - // so that we can attach it to the window user data. - - if (hMessageWindow == NULL) - { - OVR_ASSERT_LOG(false, ("Failed to create window.")); - return false; - } - - // According to MS, topmost windows receive WM_DEVICECHANGE faster. - ::SetWindowPos(hMessageWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - UpdateWindow(hMessageWindow); - - - // Register notification for additional HID messages. - HIDDeviceManager* hidDeviceManager = new HIDDeviceManager(NULL); - HidGuid = hidDeviceManager->GetHIDGuid(); - hidDeviceManager->Release(); - - DEV_BROADCAST_DEVICEINTERFACE notificationFilter; - - ZeroMemory(¬ificationFilter, sizeof(notificationFilter)); - notificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); - notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - //notificationFilter.dbcc_classguid = hidguid; - - // We need DEVICE_NOTIFY_ALL_INTERFACE_CLASSES to detect - // HDMI plug/unplug events. - hDeviceNotify = RegisterDeviceNotification( - hMessageWindow, - ¬ificationFilter, - DEVICE_NOTIFY_ALL_INTERFACE_CLASSES|DEVICE_NOTIFY_WINDOW_HANDLE); - - if (hDeviceNotify == NULL) - { - OVR_ASSERT_LOG(false, ("Failed to register for device notifications.")); - return false; - } - - return true; -} - -void DeviceStatus::ShutDown() -{ - OVR_ASSERT(hMessageWindow); - - if (!UnregisterDeviceNotification(hDeviceNotify)) - { - OVR_ASSERT_LOG(false, ("Failed to unregister device notification.")); - } - - PostMessage(hMessageWindow, WM_CLOSE, 0, 0); - - while (hMessageWindow != NULL) - { - ProcessMessages(); - Sleep(1); - } - - if (!UnregisterClass(windowClassName, NULL)) - { - OVR_ASSERT_LOG(false, ("Failed to unregister window class.")); - } -} - -DeviceStatus::~DeviceStatus() -{ - OVR_ASSERT_LOG(hMessageWindow == NULL, ("Need to call 'ShutDown' from DeviceManagerThread.")); -} - -void DeviceStatus::ProcessMessages() -{ - OVR_ASSERT_LOG(hMessageWindow != NULL, ("Need to call 'Initialize' before first use.")); - - MSG msg; - - // Note WM_DEVICECHANGED messages are dispatched but not retrieved by PeekMessage. - // I think this is because they are pending, non-queued messages. - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -bool DeviceStatus::MessageCallback(WORD messageType, const String& devicePath) -{ - bool rv = true; - if (messageType == DBT_DEVICEARRIVAL) - { - rv = pNotificationClient->OnMessage(Notifier::DeviceAdded, devicePath); - } - else if (messageType == DBT_DEVICEREMOVECOMPLETE) - { - pNotificationClient->OnMessage(Notifier::DeviceRemoved, devicePath); - } - else - { - OVR_ASSERT(0); - } - return rv; -} - -void DeviceStatus::CleanupRecoveryTimer(UPInt index) -{ - ::KillTimer(hMessageWindow, RecoveryTimers[index].TimerId); - RecoveryTimers.RemoveAt(index); -} - -DeviceStatus::RecoveryTimerDesc* -DeviceStatus::FindRecoveryTimer(UINT_PTR timerId, UPInt* pindex) -{ - for (UPInt i = 0, n = RecoveryTimers.GetSize(); i < n; ++i) - { - RecoveryTimerDesc* pdesc = &RecoveryTimers[i]; - if (pdesc->TimerId == timerId) - { - *pindex = i; - return pdesc; - } - } - return NULL; -} - -void DeviceStatus::FindAndCleanupRecoveryTimer(const String& devicePath) -{ - for (UPInt i = 0, n = RecoveryTimers.GetSize(); i < n; ++i) - { - RecoveryTimerDesc* pdesc = &RecoveryTimers[i]; - if (pdesc->DevicePath.CompareNoCase(devicePath)) - { - CleanupRecoveryTimer(i); - break; - } - } -} - -LRESULT CALLBACK DeviceStatus::WindowsMessageCallback( HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - switch (message) - { - case WM_CREATE: - { - // Setup window user data with device status object pointer. - LPCREATESTRUCT create_struct = reinterpret_cast(lParam); - void *lpCreateParam = create_struct->lpCreateParams; - DeviceStatus *pDeviceStatus = reinterpret_cast(lpCreateParam); - - SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(pDeviceStatus)); - } - return 0; // Return 0 for successfully handled WM_CREATE. - - case WM_DEVICECHANGE: - { - WORD loword = LOWORD(wParam); - - if (loword != DBT_DEVICEARRIVAL && - loword != DBT_DEVICEREMOVECOMPLETE) - { - // Ignore messages other than device arrive and remove complete - // (we're not handling intermediate ones). - return TRUE; // Grant WM_DEVICECHANGE request. - } - - DEV_BROADCAST_DEVICEINTERFACE* hdr; - hdr = (DEV_BROADCAST_DEVICEINTERFACE*) lParam; - - if (hdr->dbcc_devicetype != DBT_DEVTYP_DEVICEINTERFACE) - { - // Ignore non interface device messages. - return TRUE; // Grant WM_DEVICECHANGE request. - } - - LONG_PTR userData = GetWindowLongPtr(hwnd, GWLP_USERDATA); - OVR_ASSERT(userData != NULL); - - // Call callback on device messages object with the device path. - DeviceStatus* pDeviceStatus = (DeviceStatus*) userData; - String devicePath(hdr->dbcc_name); - - static const GUID videoCamGuid = { STATIC_KSCATEGORY_VIDEO_CAMERA }; - // check if HID device caused the event... - if (pDeviceStatus->HidGuid == hdr->dbcc_classguid || - videoCamGuid == hdr->dbcc_classguid) - { - // check if recovery timer is already running; stop it and - // remove it, if so. - pDeviceStatus->FindAndCleanupRecoveryTimer(devicePath); - - if (!pDeviceStatus->MessageCallback(loword, devicePath)) - { - // hmmm.... unsuccessful - if (loword == DBT_DEVICEARRIVAL) - { - // Windows sometimes may return errors ERROR_SHARING_VIOLATION and - // ERROR_FILE_NOT_FOUND when trying to open an USB device via - // CreateFile. Need to start a recovery timer that will try to - // re-open the device again. - OVR_DEBUG_LOG(("Adding failed, recovering through a timer...")); - UINT_PTR tid = ::SetTimer(hwnd, ++pDeviceStatus->LastTimerId, - USBRecoveryTimeInterval, NULL); - RecoveryTimerDesc rtDesc; - rtDesc.TimerId = tid; - rtDesc.DevicePath = devicePath; - rtDesc.NumAttempts= 0; - pDeviceStatus->RecoveryTimers.PushBack(rtDesc); - // wrap around the timer counter, avoid timerId == 0... - if (pDeviceStatus->LastTimerId + 1 == 0) - pDeviceStatus->LastTimerId = 0; - } - } - } - // Check if Oculus HDMI device was plugged/unplugged, preliminary - // filtering. (is there any way to get GUID? !AB) - //else if (strstr(devicePath.ToCStr(), "DISPLAY#")) - else if (strstr(devicePath.ToCStr(), "#OVR00")) - { - pDeviceStatus->MessageCallback(loword, devicePath); - } - } - return TRUE; // Grant WM_DEVICECHANGE request. - - case WM_TIMER: - { - if (wParam != 0) - { - LONG_PTR userData = GetWindowLongPtr(hwnd, GWLP_USERDATA); - OVR_ASSERT(userData != NULL); - - // Call callback on device messages object with the device path. - DeviceStatus* pDeviceStatus = (DeviceStatus*) userData; - - // Check if we have recovery timer running (actually, we must be!) - UPInt rtIndex; - RecoveryTimerDesc* prtDesc = pDeviceStatus->FindRecoveryTimer(wParam, &rtIndex); - if (prtDesc) - { - if (pDeviceStatus->MessageCallback(DBT_DEVICEARRIVAL, prtDesc->DevicePath)) - { - OVR_DEBUG_LOG(("Recovered, adding is successful, cleaning up the timer...")); - // now it is successful, kill the timer and cleanup - pDeviceStatus->CleanupRecoveryTimer(rtIndex); - } - else - { - if (++prtDesc->NumAttempts >= MaxUSBRecoveryAttempts) - { - OVR_DEBUG_LOG(("Failed to recover USB after %d attempts, path = '%s', aborting...", - prtDesc->NumAttempts, prtDesc->DevicePath.ToCStr())); - pDeviceStatus->CleanupRecoveryTimer(rtIndex); - } - else - { - OVR_DEBUG_LOG(("Failed to recover USB, %d attempts, path = '%s'", - prtDesc->NumAttempts, prtDesc->DevicePath.ToCStr())); - } - } - } - } - } - return 0; - - case WM_CLOSE: - { - LONG_PTR userData = GetWindowLongPtr(hwnd, GWLP_USERDATA); - OVR_ASSERT(userData != NULL); - DeviceStatus* pDeviceStatus = (DeviceStatus*) userData; - pDeviceStatus->hMessageWindow = NULL; - - DestroyWindow(hwnd); - } - return 0; // We processed the WM_CLOSE message. - - case WM_DESTROY: - PostQuitMessage(0); - return 0; // We processed the WM_DESTROY message. - } - - return DefWindowProc(hwnd, message, wParam, lParam); -} - -}} // namespace OVR::Win32 diff --git a/LibOVR/Src/OVR_Win32_DeviceStatus.h b/LibOVR/Src/OVR_Win32_DeviceStatus.h deleted file mode 100644 index 862addb..0000000 --- a/LibOVR/Src/OVR_Win32_DeviceStatus.h +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_DeviceStatus.h -Content : Win32-specific DeviceStatus header. -Created : January 24, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_DeviceStatus_h -#define OVR_Win32_DeviceStatus_h - -#include -#include "Kernel/OVR_String.h" -#include "Kernel/OVR_RefCount.h" -#include "Kernel/OVR_Array.h" - -namespace OVR { namespace Win32 { - -//------------------------------------------------------------------------------------- -// ***** DeviceStatus -// -// DeviceStatus abstracts the handling of windows messages of interest for -// example the WM_DEVICECHANGED message which occurs when a device is plugged/unplugged. -// The device manager thread creates an instance of this class and passes its pointer -// in the constructor. That thread is also responsible for periodically calling 'ProcessMessages' -// to process queued windows messages. The client is notified via the 'OnMessage' method -// declared in the 'DeviceMessages::Notifier' interface. -class DeviceStatus : public RefCountBase -{ -public: - - // Notifier used for device messages. - class Notifier - { - public: - enum MessageType - { - DeviceAdded = 0, - DeviceRemoved = 1, - }; - - virtual bool OnMessage(MessageType type, const String& devicePath) - { OVR_UNUSED2(type, devicePath); return true; } - }; - - DeviceStatus(Notifier* const pClient); - ~DeviceStatus(); - - void operator = (const DeviceStatus&); // No assignment implementation. - - bool Initialize(); - void ShutDown(); - - void ProcessMessages(); - -private: - enum - { - MaxUSBRecoveryAttempts = 20, - USBRecoveryTimeInterval = 500 // ms - }; - struct RecoveryTimerDesc - { - UINT_PTR TimerId; - String DevicePath; - unsigned NumAttempts; - }; - - static LRESULT CALLBACK WindowsMessageCallback( HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - - bool MessageCallback(WORD messageType, const String& devicePath); - - void CleanupRecoveryTimer(UPInt index); - RecoveryTimerDesc* FindRecoveryTimer(UINT_PTR timerId, UPInt* pindex); - void FindAndCleanupRecoveryTimer(const String& devicePath); - -private: // data - Notifier* const pNotificationClient; // Don't reference count a back-pointer. - - HWND hMessageWindow; - HDEVNOTIFY hDeviceNotify; - - UINT_PTR LastTimerId; - Array RecoveryTimers; - - GUID HidGuid; -}; - -}} // namespace OVR::Win32 - -#endif // OVR_Win32_DeviceStatus_h diff --git a/LibOVR/Src/OVR_Win32_HIDDevice.cpp b/LibOVR/Src/OVR_Win32_HIDDevice.cpp deleted file mode 100644 index 75d71f4..0000000 --- a/LibOVR/Src/OVR_Win32_HIDDevice.cpp +++ /dev/null @@ -1,649 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_HIDDevice.cpp -Content : Win32 HID device implementation. -Created : February 22, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HIDDevice.h" -#include "OVR_Win32_DeviceManager.h" - -#include "Kernel/OVR_System.h" -#include "Kernel/OVR_Log.h" - -namespace OVR { namespace Win32 { - -//------------------------------------------------------------------------------------- -// HIDDevicePathWrapper is a simple class used to extract HID device file path -// through SetupDiGetDeviceInterfaceDetail. We use a class since this is a bit messy. -class HIDDevicePathWrapper -{ - SP_INTERFACE_DEVICE_DETAIL_DATA_A* pData; -public: - HIDDevicePathWrapper() : pData(0) { } - ~HIDDevicePathWrapper() { if (pData) OVR_FREE(pData); } - - const char* GetPath() const { return pData ? pData->DevicePath : 0; } - - bool InitPathFromInterfaceData(HDEVINFO hdevInfoSet, SP_DEVICE_INTERFACE_DATA* pidata); -}; - -bool HIDDevicePathWrapper::InitPathFromInterfaceData(HDEVINFO hdevInfoSet, SP_DEVICE_INTERFACE_DATA* pidata) -{ - DWORD detailSize = 0; - // SetupDiGetDeviceInterfaceDetailA returns "not enough buffer error code" - // doe size request. Just check valid size. - SetupDiGetDeviceInterfaceDetailA(hdevInfoSet, pidata, NULL, 0, &detailSize, NULL); - if (!detailSize || - ((pData = (SP_INTERFACE_DEVICE_DETAIL_DATA_A*)OVR_ALLOC(detailSize)) == 0)) - return false; - pData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA_A); - - if (!SetupDiGetDeviceInterfaceDetailA(hdevInfoSet, pidata, pData, detailSize, NULL, NULL)) - return false; - return true; -} - - -//------------------------------------------------------------------------------------- -// **** Win32::DeviceManager - -HIDDeviceManager::HIDDeviceManager(DeviceManager* manager) - : Manager(manager) -{ - hHidLib = ::LoadLibraryA("hid.dll"); - OVR_ASSERT_LOG(hHidLib, ("Couldn't load Win32 'hid.dll'.")); - - OVR_RESOLVE_HIDFUNC(HidD_GetHidGuid); - OVR_RESOLVE_HIDFUNC(HidD_SetNumInputBuffers); - OVR_RESOLVE_HIDFUNC(HidD_GetFeature); - OVR_RESOLVE_HIDFUNC(HidD_SetFeature); - OVR_RESOLVE_HIDFUNC(HidD_GetAttributes); - OVR_RESOLVE_HIDFUNC(HidD_GetManufacturerString); - OVR_RESOLVE_HIDFUNC(HidD_GetProductString); - OVR_RESOLVE_HIDFUNC(HidD_GetSerialNumberString); - OVR_RESOLVE_HIDFUNC(HidD_GetPreparsedData); - OVR_RESOLVE_HIDFUNC(HidD_FreePreparsedData); - OVR_RESOLVE_HIDFUNC(HidP_GetCaps); - - if (HidD_GetHidGuid) - HidD_GetHidGuid(&HidGuid); -} - -HIDDeviceManager::~HIDDeviceManager() -{ - ::FreeLibrary(hHidLib); -} - -bool HIDDeviceManager::Initialize() -{ - return true; -} - -void HIDDeviceManager::Shutdown() -{ - LogText("OVR::Win32::HIDDeviceManager - shutting down.\n"); -} - -bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) -{ - HDEVINFO hdevInfoSet; - SP_DEVICE_INTERFACE_DATA interfaceData; - interfaceData.cbSize = sizeof(interfaceData); - - // Get handle to info data set describing all available HIDs. - hdevInfoSet = SetupDiGetClassDevsA(&HidGuid, NULL, NULL, DIGCF_INTERFACEDEVICE | DIGCF_PRESENT); - if (hdevInfoSet == INVALID_HANDLE_VALUE) - return false; - - for(int deviceIndex = 0; - SetupDiEnumDeviceInterfaces(hdevInfoSet, NULL, &HidGuid, deviceIndex, &interfaceData); - deviceIndex++) - { - // For each device, we extract its file path and open it to get attributes, - // such as vendor and product id. If anything goes wrong, we move onto next device. - HIDDevicePathWrapper pathWrapper; - if (!pathWrapper.InitPathFromInterfaceData(hdevInfoSet, &interfaceData)) - continue; - - // Look for the device to check if it is already opened. - Ptr existingDevice = Manager->FindDevice(pathWrapper.GetPath()); - // if device exists and it is opened then most likely the CreateHIDFile - // will fail; therefore, we just set Enumerated to 'true' and continue. - if (existingDevice && existingDevice->pDevice) - { - existingDevice->Enumerated = true; - continue; - } - - // open device in non-exclusive mode for detection... - HANDLE hidDev = CreateHIDFile(pathWrapper.GetPath(), false); - if (hidDev == INVALID_HANDLE_VALUE) - continue; - - HIDDeviceDesc devDesc; - devDesc.Path = pathWrapper.GetPath(); - if (initVendorProductVersion(hidDev, &devDesc) && - enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) && - initUsage(hidDev, &devDesc)) - { - initStrings(hidDev, &devDesc); - - // Construct minimal device that the visitor callback can get feature reports from. - Win32::HIDDevice device(this, hidDev); - enumVisitor->Visit(device, devDesc); - } - - ::CloseHandle(hidDev); - } - - SetupDiDestroyDeviceInfoList(hdevInfoSet); - return true; -} - -bool HIDDeviceManager::GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const -{ - // open device in non-exclusive mode for detection... - HANDLE hidDev = CreateHIDFile(path, false); - if (hidDev == INVALID_HANDLE_VALUE) - return false; - - pdevDesc->Path = path; - bool succ = getFullDesc(hidDev, pdevDesc); - - ::CloseHandle(hidDev); - return succ; -} - -OVR::HIDDevice* HIDDeviceManager::Open(const String& path) -{ - - Ptr device = *new Win32::HIDDevice(this); - - if (device->HIDInitialize(path)) - { - device->AddRef(); - return device; - } - - return NULL; -} - -bool HIDDeviceManager::getFullDesc(HANDLE hidDev, HIDDeviceDesc* desc) const -{ - - if (!initVendorProductVersion(hidDev, desc)) - { - return false; - } - - if (!initUsage(hidDev, desc)) - { - return false; - } - - initStrings(hidDev, desc); - - return true; -} - -bool HIDDeviceManager::initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc) const -{ - HIDD_ATTRIBUTES attr; - attr.Size = sizeof(attr); - if (!HidD_GetAttributes(hidDev, &attr)) - return false; - desc->VendorId = attr.VendorID; - desc->ProductId = attr.ProductID; - desc->VersionNumber = attr.VersionNumber; - return true; -} - -bool HIDDeviceManager::initUsage(HANDLE hidDev, HIDDeviceDesc* desc) const -{ - bool result = false; - HIDP_CAPS caps; - HIDP_PREPARSED_DATA* preparsedData = 0; - - if (!HidD_GetPreparsedData(hidDev, &preparsedData)) - return false; - - if (HidP_GetCaps(preparsedData, &caps) == HIDP_STATUS_SUCCESS) - { - desc->Usage = caps.Usage; - desc->UsagePage = caps.UsagePage; - result = true; - } - HidD_FreePreparsedData(preparsedData); - return result; -} - -void HIDDeviceManager::initStrings(HANDLE hidDev, HIDDeviceDesc* desc) const -{ - // Documentation mentions 126 as being the max for USB. - wchar_t strBuffer[196]; - - // HidD_Get*String functions return nothing in buffer on failure, - // so it's ok to do this without further error checking. - strBuffer[0] = 0; - HidD_GetManufacturerString(hidDev, strBuffer, sizeof(strBuffer)); - desc->Manufacturer = strBuffer; - - strBuffer[0] = 0; - HidD_GetProductString(hidDev, strBuffer, sizeof(strBuffer)); - desc->Product = strBuffer; - - strBuffer[0] = 0; - HidD_GetSerialNumberString(hidDev, strBuffer, sizeof(strBuffer)); - desc->SerialNumber = strBuffer; -} - -//------------------------------------------------------------------------------------- -// **** Win32::HIDDevice - -HIDDevice::HIDDevice(HIDDeviceManager* manager) - : HIDManager(manager), inMinimalMode(false), Device(0), ReadRequested(false) -{ - memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); -} - -// This is a minimal constructor used during enumeration for us to pass -// a HIDDevice to the visit function (so that it can query feature reports). -HIDDevice::HIDDevice(HIDDeviceManager* manager, HANDLE device) - : HIDManager(manager), inMinimalMode(true), Device(device), ReadRequested(true) -{ - memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); -} - -HIDDevice::~HIDDevice() -{ - if (!inMinimalMode) - { - HIDShutdown(); - } -} - -bool HIDDevice::HIDInitialize(const String& path) -{ - - DevDesc.Path = path; - - if (!openDevice()) - { - LogText("OVR::Win32::HIDDevice - Failed to open HIDDevice: ", path); - return false; - } - - - HIDManager->Manager->pThread->AddTicksNotifier(this); - HIDManager->Manager->pThread->AddMessageNotifier(this); - - LogText("OVR::Win32::HIDDevice - Opened '%s'\n" - " Manufacturer:'%s' Product:'%s' Serial#:'%s' Version:'%x'\n", - DevDesc.Path.ToCStr(), - DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(), - DevDesc.SerialNumber.ToCStr(), - DevDesc.VersionNumber); - - return true; -} - -bool HIDDevice::initInfo() -{ - // Device must have been successfully opened. - OVR_ASSERT(Device); - - // Get report lengths. - HIDP_PREPARSED_DATA* preparsedData = 0; - if (!HIDManager->HidD_GetPreparsedData(Device, &preparsedData)) - { - return false; - } - - HIDP_CAPS caps; - if (HIDManager->HidP_GetCaps(preparsedData, &caps) != HIDP_STATUS_SUCCESS) - { - HIDManager->HidD_FreePreparsedData(preparsedData); - return false; - } - - InputReportBufferLength = caps.InputReportByteLength; - OutputReportBufferLength = caps.OutputReportByteLength; - FeatureReportBufferLength= caps.FeatureReportByteLength; - HIDManager->HidD_FreePreparsedData(preparsedData); - - if (ReadBufferSize < InputReportBufferLength) - { - OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer.")); - return false; - } - - // Get device desc. - if (!HIDManager->getFullDesc(Device, &DevDesc)) - { - OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device.")); - return false; - } - - return true; -} - -bool HIDDevice::openDevice() -{ - memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); - - Device = HIDManager->CreateHIDFile(DevDesc.Path.ToCStr()); - if (Device == INVALID_HANDLE_VALUE) - { - OVR_DEBUG_LOG(("Failed 'CreateHIDFile' while opening device, error = 0x%X.", - ::GetLastError())); - Device = 0; - return false; - } - - if (!HIDManager->HidD_SetNumInputBuffers(Device, 128)) - { - OVR_ASSERT_LOG(false, ("Failed 'HidD_SetNumInputBuffers' while initializing device.")); - ::CloseHandle(Device); - Device = 0; - return false; - } - - - // Create a manual-reset non-signaled event. - ReadOverlapped.hEvent = ::CreateEvent(0, TRUE, FALSE, 0); - - if (!ReadOverlapped.hEvent) - { - OVR_ASSERT_LOG(false, ("Failed to create event.")); - ::CloseHandle(Device); - Device = 0; - return false; - } - - if (!initInfo()) - { - OVR_ASSERT_LOG(false, ("Failed to get HIDDevice info.")); - - ::CloseHandle(ReadOverlapped.hEvent); - memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); - - ::CloseHandle(Device); - Device = 0; - return false; - } - - if (!initializeRead()) - { - OVR_ASSERT_LOG(false, ("Failed to get intialize read for HIDDevice.")); - - ::CloseHandle(ReadOverlapped.hEvent); - memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); - - ::CloseHandle(Device); - Device = 0; - return false; - } - - return true; -} - -void HIDDevice::HIDShutdown() -{ - - HIDManager->Manager->pThread->RemoveTicksNotifier(this); - HIDManager->Manager->pThread->RemoveMessageNotifier(this); - - closeDevice(); - LogText("OVR::Win32::HIDDevice - Closed '%s'\n", DevDesc.Path.ToCStr()); -} - -bool HIDDevice::initializeRead() -{ - - if (!ReadRequested) - { - HIDManager->Manager->pThread->AddOverlappedEvent(this, ReadOverlapped.hEvent); - ReadRequested = true; - } - - // Read resets the event... - while(::ReadFile(Device, ReadBuffer, InputReportBufferLength, 0, &ReadOverlapped)) - { - processReadResult(); - } - - if (GetLastError() != ERROR_IO_PENDING) - { - // Some other error (such as unplugged). - closeDeviceOnIOError(); - return false; - } - - return true; -} - -bool HIDDevice::processReadResult() -{ - - OVR_ASSERT(ReadRequested); - - DWORD bytesRead = 0; - - if (GetOverlappedResult(Device, &ReadOverlapped, &bytesRead, FALSE)) - { - // We've got data. - if (Handler) - { - Handler->OnInputReport(ReadBuffer, bytesRead); - } - - // TBD: Not needed? - // Event should be reset by Read call... - ReadOverlapped.Pointer = 0; - ReadOverlapped.Internal = 0; - ReadOverlapped.InternalHigh = 0; - return true; - } - else - { - if (GetLastError() != ERROR_IO_PENDING) - { - closeDeviceOnIOError(); - return false; - } - } - - return false; -} - -void HIDDevice::closeDevice() -{ - if (ReadRequested) - { - HIDManager->Manager->pThread->RemoveOverlappedEvent(this, ReadOverlapped.hEvent); - ReadRequested = false; - // Must call this to avoid Win32 assertion; CloseHandle is not enough. - ::CancelIo(Device); - } - - ::CloseHandle(ReadOverlapped.hEvent); - memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); - - ::CloseHandle(Device); - Device = 0; -} - -void HIDDevice::closeDeviceOnIOError() -{ - LogText("OVR::Win32::HIDDevice - Lost connection to '%s'\n", DevDesc.Path.ToCStr()); - closeDevice(); -} - -bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length) -{ - if (!ReadRequested) - return false; - - BOOLEAN res = HIDManager->HidD_SetFeature(Device, data, (ULONG) length); - return (res == TRUE); -} - -bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length) -{ - if (!ReadRequested) - return false; - - BOOLEAN res = HIDManager->HidD_GetFeature(Device, data, (ULONG) length); - return (res == TRUE); -} - -void HIDDevice::OnOverlappedEvent(HANDLE hevent) -{ - OVR_UNUSED(hevent); - OVR_ASSERT(hevent == ReadOverlapped.hEvent); - - if (processReadResult()) - { - // Proceed to read again. - initializeRead(); - } -} - -double HIDDevice::OnTicks(double tickSeconds) -{ - if (Handler) - { - return Handler->OnTicks(tickSeconds); - } - - return DeviceManagerThread::Notifier::OnTicks(tickSeconds); -} - -bool HIDDevice::OnDeviceMessage(DeviceMessageType messageType, - const String& devicePath, - bool* error) -{ - - // Is this the correct device? - if (DevDesc.Path.CompareNoCase(devicePath) != 0) - { - return false; - } - - if (messageType == DeviceMessage_DeviceAdded && !Device) - { - // A closed device has been re-added. Try to reopen. - if (!openDevice()) - { - LogError("OVR::Win32::HIDDevice - Failed to reopen a device '%s' that was re-added.\n", devicePath.ToCStr()); - *error = true; - return true; - } - - LogText("OVR::Win32::HIDDevice - Reopened device '%s'\n", devicePath.ToCStr()); - } - - HIDHandler::HIDDeviceMessageType handlerMessageType = HIDHandler::HIDDeviceMessage_DeviceAdded; - if (messageType == DeviceMessage_DeviceAdded) - { - } - else if (messageType == DeviceMessage_DeviceRemoved) - { - handlerMessageType = HIDHandler::HIDDeviceMessage_DeviceRemoved; - } - else - { - OVR_ASSERT(0); - } - - if (Handler) - { - Handler->OnDeviceMessage(handlerMessageType); - } - - *error = false; - return true; -} - -HIDDeviceManager* HIDDeviceManager::CreateInternal(Win32::DeviceManager* devManager) -{ - - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr manager = *new Win32::HIDDeviceManager(devManager); - - if (manager) - { - if (manager->Initialize()) - { - manager->AddRef(); - } - else - { - manager.Clear(); - } - } - - return manager.GetPtr(); -} - -} // namespace Win32 - -//------------------------------------------------------------------------------------- -// ***** Creation - -// Creates a new HIDDeviceManager and initializes OVR. -HIDDeviceManager* HIDDeviceManager::Create(Ptr& deviceManager) -{ - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr deviceManagerWin32 = *new Win32::DeviceManager; - - if (!deviceManagerWin32) - { - return NULL; - } - - if (!deviceManagerWin32->Initialize(0)) - { - return NULL; - } - - deviceManager = deviceManagerWin32; - - return deviceManagerWin32->GetHIDDeviceManager(); -} - -} // namespace OVR diff --git a/LibOVR/Src/OVR_Win32_HIDDevice.h b/LibOVR/Src/OVR_Win32_HIDDevice.h deleted file mode 100644 index 4e75914..0000000 --- a/LibOVR/Src/OVR_Win32_HIDDevice.h +++ /dev/null @@ -1,205 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_HIDDevice.h -Content : Win32 HID device implementation. -Created : February 22, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HIDDevice_h -#define OVR_Win32_HIDDevice_h - -#include "OVR_HIDDevice.h" -#include "OVR_Win32_DeviceManager.h" - -#include -#include - -//------------------------------------------------------------------------------------- -// Define needed "hidsdi.h" functionality to avoid requiring DDK installation. -// #include "hidsdi.h" - -#ifndef _HIDSDI_H -#define _HIDSDI_H -#include - -#define HIDP_STATUS_SUCCESS (0x11 << 16) -struct HIDP_PREPARSED_DATA; - -struct HIDD_ATTRIBUTES -{ - ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES) - USHORT VendorID; - USHORT ProductID; - USHORT VersionNumber; -}; - -struct HIDP_CAPS -{ - USHORT Usage; - USHORT UsagePage; - USHORT InputReportByteLength; - USHORT OutputReportByteLength; - USHORT FeatureReportByteLength; - USHORT Reserved[17]; - - USHORT NumberLinkCollectionNodes; - USHORT NumberInputButtonCaps; - USHORT NumberInputValueCaps; - USHORT NumberInputDataIndices; - USHORT NumberOutputButtonCaps; - USHORT NumberOutputValueCaps; - USHORT NumberOutputDataIndices; - USHORT NumberFeatureButtonCaps; - USHORT NumberFeatureValueCaps; - USHORT NumberFeatureDataIndices; -}; - -#include -#endif - - -namespace OVR { namespace Win32 { - -class HIDDeviceManager; -class DeviceManager; - -//------------------------------------------------------------------------------------- -// ***** Win32 HIDDevice - -class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier -{ -public: - - HIDDevice(HIDDeviceManager* manager); - - // This is a minimal constructor used during enumeration for us to pass - // a HIDDevice to the visit function (so that it can query feature reports). - HIDDevice(HIDDeviceManager* manager, HANDLE device); - - ~HIDDevice(); - - bool HIDInitialize(const String& path); - void HIDShutdown(); - - // OVR::HIDDevice - bool SetFeatureReport(UByte* data, UInt32 length); - bool GetFeatureReport(UByte* data, UInt32 length); - - - // DeviceManagerThread::Notifier - void OnOverlappedEvent(HANDLE hevent); - double OnTicks(double tickSeconds); - bool OnDeviceMessage(DeviceMessageType messageType, const String& devicePath, bool* error); - -private: - bool openDevice(); - bool initInfo(); - bool initializeRead(); - bool processReadResult(); - void closeDevice(); - void closeDeviceOnIOError(); - - bool inMinimalMode; - HIDDeviceManager* HIDManager; - HANDLE Device; - HIDDeviceDesc DevDesc; - - OVERLAPPED ReadOverlapped; - bool ReadRequested; - - enum { ReadBufferSize = 96 }; - UByte ReadBuffer[ReadBufferSize]; - - UInt16 InputReportBufferLength; - UInt16 OutputReportBufferLength; - UInt16 FeatureReportBufferLength; -}; - -//------------------------------------------------------------------------------------- -// ***** Win32 HIDDeviceManager - -class HIDDeviceManager : public OVR::HIDDeviceManager -{ - friend class HIDDevice; -public: - - HIDDeviceManager(DeviceManager* manager); - virtual ~HIDDeviceManager(); - - virtual bool Initialize(); - virtual void Shutdown(); - - virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor); - virtual OVR::HIDDevice* Open(const String& path); - - // Fills HIDDeviceDesc by using the path. - // Returns 'true' if successful, 'false' otherwise. - bool GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const; - - GUID GetHIDGuid() { return HidGuid; } - - static HIDDeviceManager* CreateInternal(DeviceManager* manager); - -private: - - DeviceManager* Manager; // Back pointer can just be a raw pointer. - - HMODULE hHidLib; - GUID HidGuid; - - // Macros to declare and resolve needed functions from library. -#define OVR_DECLARE_HIDFUNC(func, rettype, args) \ -typedef rettype (__stdcall *PFn_##func) args; \ -PFn_##func func; -#define OVR_RESOLVE_HIDFUNC(func) \ -func = (PFn_##func)::GetProcAddress(hHidLib, #func) - - OVR_DECLARE_HIDFUNC(HidD_GetHidGuid, void, (GUID *hidGuid)); - OVR_DECLARE_HIDFUNC(HidD_SetNumInputBuffers, BOOLEAN, (HANDLE hidDev, ULONG numberBuffers)); - OVR_DECLARE_HIDFUNC(HidD_GetFeature, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength)); - OVR_DECLARE_HIDFUNC(HidD_SetFeature, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength)); - OVR_DECLARE_HIDFUNC(HidD_GetAttributes, BOOLEAN, (HANDLE hidDev, HIDD_ATTRIBUTES *attributes)); - OVR_DECLARE_HIDFUNC(HidD_GetManufacturerString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength)); - OVR_DECLARE_HIDFUNC(HidD_GetProductString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength)); - OVR_DECLARE_HIDFUNC(HidD_GetSerialNumberString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength)); - OVR_DECLARE_HIDFUNC(HidD_GetPreparsedData, BOOLEAN, (HANDLE hidDev, HIDP_PREPARSED_DATA **preparsedData)); - OVR_DECLARE_HIDFUNC(HidD_FreePreparsedData, BOOLEAN, (HIDP_PREPARSED_DATA *preparsedData)); - OVR_DECLARE_HIDFUNC(HidP_GetCaps, NTSTATUS,(HIDP_PREPARSED_DATA *preparsedData, HIDP_CAPS* caps)); - - HANDLE CreateHIDFile(const char* path, bool exclusiveAccess = true) const - { - return ::CreateFileA(path, GENERIC_WRITE|GENERIC_READ, - (!exclusiveAccess) ? (FILE_SHARE_READ|FILE_SHARE_WRITE) : 0x0, - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - } - - // Helper functions to fill in HIDDeviceDesc from open device handle. - bool initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc) const; - bool initUsage(HANDLE hidDev, HIDDeviceDesc* desc) const; - void initStrings(HANDLE hidDev, HIDDeviceDesc* desc) const; - - bool getFullDesc(HANDLE hidDev, HIDDeviceDesc* desc) const; -}; - -}} // namespace OVR::Win32 - -#endif // OVR_Win32_HIDDevice_h diff --git a/LibOVR/Src/OVR_Win32_HMDDevice.cpp b/LibOVR/Src/OVR_Win32_HMDDevice.cpp deleted file mode 100644 index e16a060..0000000 --- a/LibOVR/Src/OVR_Win32_HMDDevice.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_HMDDevice.cpp -Content : Win32 Interface to HMD - detects HMD display -Created : September 21, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HMDDevice.h" - -#include "OVR_Win32_DeviceManager.h" -#include "util/Util_Render_Stereo.h" - -#include - -namespace OVR { namespace Win32 { - -using namespace OVR::Util::Render; - -//------------------------------------------------------------------------------------- - -HMDDeviceCreateDesc::HMDDeviceCreateDesc(DeviceFactory* factory, - const String& deviceId, const String& displayDeviceName) - : DeviceCreateDesc(factory, Device_HMD), - DeviceId(deviceId), DisplayDeviceName(displayDeviceName), - Contents(0) -{ - Desktop.X = 0; - Desktop.Y = 0; - ResolutionInPixels = Sizei(0); - ScreenSizeInMeters = Sizef(0.0f); - VCenterFromTopInMeters = 0.0f; - LensSeparationInMeters = 0.0f; -} -HMDDeviceCreateDesc::HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other) - : DeviceCreateDesc(other.pFactory, Device_HMD), - DeviceId(other.DeviceId), DisplayDeviceName(other.DisplayDeviceName), - Contents(other.Contents) -{ - Desktop.X = other.Desktop.X; - Desktop.Y = other.Desktop.Y; - ResolutionInPixels = other.ResolutionInPixels; - ScreenSizeInMeters = other.ScreenSizeInMeters; - VCenterFromTopInMeters = other.VCenterFromTopInMeters; - LensSeparationInMeters = other.LensSeparationInMeters; -} - -HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc** pcandidate) const -{ - if ((other.Type != Device_HMD) || (other.pFactory != pFactory)) - return Match_None; - - // There are several reasons we can come in here: - // a) Matching this HMD Monitor created desc to OTHER HMD Monitor desc - // - Require exact device DeviceId/DeviceName match - // b) Matching SensorDisplayInfo created desc to OTHER HMD Monitor desc - // - This DeviceId is empty; becomes candidate - // c) Matching this HMD Monitor created desc to SensorDisplayInfo desc - // - This other.DeviceId is empty; becomes candidate - - const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other; - - if ((DeviceId == s2.DeviceId) && - (DisplayDeviceName == s2.DisplayDeviceName)) - { - // Non-null DeviceId may match while size is different if screen size was overwritten - // by SensorDisplayInfo in prior iteration. - if (!DeviceId.IsEmpty() || - (ScreenSizeInMeters == s2.ScreenSizeInMeters) ) - { - *pcandidate = 0; - return Match_Found; - } - } - - - // DisplayInfo takes precedence, although we try to match it first. - if ((ResolutionInPixels == s2.ResolutionInPixels) && - (ScreenSizeInMeters == s2.ScreenSizeInMeters)) - { - if (DeviceId.IsEmpty() && !s2.DeviceId.IsEmpty()) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - - *pcandidate = 0; - return Match_Found; - } - - // SensorDisplayInfo may override resolution settings, so store as candidate. - if (s2.DeviceId.IsEmpty()) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - // OTHER HMD Monitor desc may initialize DeviceName/Id - else if (DeviceId.IsEmpty()) - { - *pcandidate = const_cast((const DeviceCreateDesc*)this); - return Match_Candidate; - } - - return Match_None; -} - - -bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other, - bool* newDeviceFlag) -{ - // This candidate was the the "best fit" to apply sensor DisplayInfo to. - OVR_ASSERT(other.Type == Device_HMD); - - const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other; - - // Force screen size on resolution from SensorDisplayInfo. - // We do this because USB detection is more reliable as compared to HDMI EDID, - // which may be corrupted by splitter reporting wrong monitor - if (s2.DeviceId.IsEmpty()) - { - // disconnected HMD: replace old descriptor by the 'fake' one. - ScreenSizeInMeters = s2.ScreenSizeInMeters; - Contents |= Contents_Screen; - - if (s2.Contents & HMDDeviceCreateDesc::Contents_Distortion) - { - memcpy(DistortionK, s2.DistortionK, sizeof(float)*4); - // TODO: DistortionEqn - Contents |= Contents_Distortion; - } - DeviceId = s2.DeviceId; - DisplayDeviceName = s2.DisplayDeviceName; - Desktop.X = s2.Desktop.X; - Desktop.Y = s2.Desktop.Y; - if (newDeviceFlag) *newDeviceFlag = true; - } - else if (DeviceId.IsEmpty()) - { - // This branch is executed when 'fake' HMD descriptor is being replaced by - // the real one. - DeviceId = s2.DeviceId; - DisplayDeviceName = s2.DisplayDeviceName; - Desktop.X = s2.Desktop.X; - Desktop.Y = s2.Desktop.Y; - - // ScreenSize and Resolution are NOT assigned here, since they may have - // come from a sensor DisplayInfo (which has precedence over HDMI). - - if (newDeviceFlag) *newDeviceFlag = true; - } - else - { - if (newDeviceFlag) *newDeviceFlag = false; - } - - return true; -} - -bool HMDDeviceCreateDesc::MatchDevice(const String& path) -{ - return DeviceId.CompareNoCase(path) == 0; -} - -//------------------------------------------------------------------------------------- - - -const wchar_t* FormatDisplayStateFlags(wchar_t* buff, int length, DWORD flags) -{ - buff[0] = 0; - if (flags & DISPLAY_DEVICE_ACTIVE) - wcscat_s(buff, length, L"Active "); - if (flags & DISPLAY_DEVICE_MIRRORING_DRIVER) - wcscat_s(buff, length, L"Mirroring_Driver "); - if (flags & DISPLAY_DEVICE_MODESPRUNED) - wcscat_s(buff, length, L"ModesPruned "); - if (flags & DISPLAY_DEVICE_PRIMARY_DEVICE) - wcscat_s(buff, length, L"Primary "); - if (flags & DISPLAY_DEVICE_REMOVABLE) - wcscat_s(buff, length, L"Removable "); - if (flags & DISPLAY_DEVICE_VGA_COMPATIBLE) - wcscat_s(buff, length, L"VGA_Compatible "); - return buff; -} - - -//------------------------------------------------------------------------------------- -// Callback for monitor enumeration to store all the monitor handles - -// Used to capture all the active monitor handles -struct MonitorSet -{ - enum { MaxMonitors = 8 }; - HMONITOR Monitors[MaxMonitors]; - int MonitorCount; -}; - -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; -}; - -//------------------------------------------------------------------------------------- -// ***** HMDDeviceFactory - -HMDDeviceFactory &HMDDeviceFactory::GetInstance() -{ - static HMDDeviceFactory instance; - return instance; -} - -void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) -{ - MonitorSet monitors; - monitors.MonitorCount = 0; - // Get all the monitor handles - EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors); - - bool foundHMD = false; - - // DeviceManager* manager = getManager(); - 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++) - { - - /* - wchar_t buff[500], flagsBuff[200]; - - swprintf_s(buff, 500, L"\nDEV: \"%s\" \"%s\" 0x%08x=%s\n \"%s\" \"%s\"\n", - dd.DeviceName, dd.DeviceString, - dd.StateFlags, FormatDisplayStateFlags(flagsBuff, 200, dd.StateFlags), - dd.DeviceID, dd.DeviceKey); - ::OutputDebugString(buff); - */ - - for (j = 0; - (ZeroMemory(&ddm, sizeof(ddm)), ddm.cb = sizeof(ddm), - EnumDisplayDevices(dd.DeviceName, j, &ddm, 0)) != 0; j++) - { - /* - wchar_t mbuff[500]; - swprintf_s(mbuff, 500, L"MON: \"%s\" \"%s\" 0x%08x=%s\n \"%s\" \"%s\"\n", - ddm.DeviceName, ddm.DeviceString, - ddm.StateFlags, FormatDisplayStateFlags(flagsBuff, 200, ddm.StateFlags), - ddm.DeviceID, ddm.DeviceKey); - ::OutputDebugString(mbuff); - */ - - // 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); - - // The default monitor coordinates - int mx = 0; - int my = 0; - int mwidth = 1280; - int mheight = 800; - - // 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 - mx = info.rcMonitor.left; - my = info.rcMonitor.top; - //mwidth = info.rcMonitor.right - info.rcMonitor.left; - //mheight = info.rcMonitor.bottom - info.rcMonitor.top; - break; - } - } - - HMDDeviceCreateDesc hmdCreateDesc(this, deviceId, displayDeviceName); - - // Hard-coded defaults in case the device doesn't have the data itself. - if (wcsstr(ddm.DeviceID, L"OVR0003")) - { // DK2 prototypes and variants (default to HmdType_DK2) - hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12576f, 0.07074f, 0.12576f*0.5f, 0.0635f ); - } - else if (wcsstr(ddm.DeviceID, L"OVR0002")) - { // HD Prototypes (default to HmdType_DKHDProto) - hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12096f, 0.06804f, 0.06804f*0.5f, 0.0635f ); - } - else if (wcsstr(ddm.DeviceID, L"OVR0001")) - { // DK1 - hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f, 0.0936f*0.5f, 0.0635f); - } - else if (wcsstr(ddm.DeviceID, L"OVR00")) - { // Future Oculus HMD devices (default to DK1 dimensions) - hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f, 0.0936f*0.5f, 0.0635f); - } - else - { // Duct-tape prototype - hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.12096f, 0.0756f, 0.0756f*0.5f, 0.0635f); - } - - OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %s\n", - deviceId.ToCStr(), displayDeviceName.ToCStr())); - - // Notify caller about detected device. This will call EnumerateAddDevice - // if the this is the first time device was detected. - visitor.Visit(hmdCreateDesc); - foundHMD = true; - break; - } - } - } - - // Real HMD device is not found; however, we still may have a 'fake' HMD - // device created via SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo. - // Need to find it and set 'Enumerated' to true to avoid Removal notification. - if (!foundHMD) - { - Ptr hmdDevDesc = getManager()->FindDevice("", Device_HMD); - if (hmdDevDesc) - hmdDevDesc->Enumerated = true; - } -} - -#include "OVR_Common_HMDDevice.cpp" - -}} // namespace OVR::Win32 - - diff --git a/LibOVR/Src/OVR_Win32_HMDDevice.h b/LibOVR/Src/OVR_Win32_HMDDevice.h deleted file mode 100644 index 022089e..0000000 --- a/LibOVR/Src/OVR_Win32_HMDDevice.h +++ /dev/null @@ -1,153 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_HMDDevice.h -Content : Win32 HMDDevice implementation -Created : September 21, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_HMDDevice_h -#define OVR_Win32_HMDDevice_h - -#include "OVR_Win32_DeviceManager.h" -#include "OVR_Profile.h" - -namespace OVR { namespace Win32 { - -class HMDDevice; - - -//------------------------------------------------------------------------------------- - -// HMDDeviceFactory enumerates attached Oculus HMD devices. -// -// This is currently done by matching monitor device strings. - -class HMDDeviceFactory : public DeviceFactory -{ -public: - static HMDDeviceFactory &GetInstance(); - - // Enumerates devices, creating and destroying relevant objects in manager. - virtual void EnumerateDevices(EnumerateVisitor& visitor); - -protected: - DeviceManager* getManager() const { return (DeviceManager*) pManager; } -}; - - -class HMDDeviceCreateDesc : public DeviceCreateDesc -{ - friend class HMDDevice; - -protected: - enum - { - Contents_Screen = 1, - Contents_Distortion = 2, - }; - String DeviceId; - String DisplayDeviceName; - struct - { - int X, Y; - } Desktop; - unsigned int Contents; - - Sizei ResolutionInPixels; - Sizef ScreenSizeInMeters; - float VCenterFromTopInMeters; - float LensSeparationInMeters; - - // TODO: update these to splines. - DistortionEqnType DistortionEqn; - float DistortionK[4]; - -public: - HMDDeviceCreateDesc(DeviceFactory* factory, - const String& deviceId, const String& displayDeviceName); - HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other); - - virtual DeviceCreateDesc* Clone() const - { - return new HMDDeviceCreateDesc(*this); - } - - virtual DeviceBase* NewDeviceInstance(); - - virtual MatchResult MatchDevice(const DeviceCreateDesc& other, - DeviceCreateDesc**) const; - - // Matches device by path. - virtual bool MatchDevice(const String& path); - - virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL); - - virtual bool GetDeviceInfo(DeviceInfo* info) const; - - void SetScreenParameters(int x, int y, - int hres, int vres, - float hsize, float vsize, - float vCenterFromTopInMeters, float lensSeparationInMeters); - void SetDistortion(const float* dks); - - HmdTypeEnum GetHmdType() const; -}; - - -//------------------------------------------------------------------------------------- - -// HMDDevice represents an Oculus HMD device unit. An instance of this class -// is typically created from the DeviceManager. -// After HMD device is created, we its sensor data can be obtained by -// first creating a Sensor object and then wrappig it in SensorFusion. - -class HMDDevice : public DeviceImpl -{ -public: - HMDDevice(HMDDeviceCreateDesc* createDesc); - ~HMDDevice(); - - virtual bool Initialize(DeviceBase* parent); - virtual void Shutdown(); - - // Requests the currently used default profile. This profile affects the - // settings reported by HMDInfo. - virtual Profile* GetProfile(); - virtual const char* GetProfileName(); - virtual bool SetProfileName(const char* name); - - // Query associated sensor. - virtual OVR::SensorDevice* GetSensor(); - -protected: - HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); } - - // User name for the profile used with this device. - String ProfileName; - mutable Ptr pCachedProfile; -}; - - -}} // namespace OVR::Win32 - -#endif // OVR_Win32_HMDDevice_h - diff --git a/LibOVR/Src/OVR_Win32_SensorDevice.cpp b/LibOVR/Src/OVR_Win32_SensorDevice.cpp deleted file mode 100644 index d1a9fdb..0000000 --- a/LibOVR/Src/OVR_Win32_SensorDevice.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_SensorDevice.cpp -Content : Win32 SensorDevice implementation -Created : March 12, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorDevice.h" - -#include "OVR_Win32_HMDDevice.h" -#include "OVR_SensorImpl.h" -#include "OVR_DeviceImpl.h" - -namespace OVR { namespace Win32 { - -} // namespace Win32 - -//------------------------------------------------------------------------------------- -void SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo - (const SensorDisplayInfoImpl& displayInfo, - DeviceFactory::EnumerateVisitor& visitor) -{ - Win32::HMDDeviceCreateDesc hmdCreateDesc(&Win32::HMDDeviceFactory::GetInstance(), String(), String()); - - hmdCreateDesc.SetScreenParameters( 0, 0, - displayInfo.HResolution, displayInfo.VResolution, - displayInfo.HScreenSize, displayInfo.VScreenSize, - displayInfo.VCenter, displayInfo.LensSeparation); - - if ((displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) == SensorDisplayInfoImpl::Base_Distortion) - { - // TODO: update to spline system. - hmdCreateDesc.SetDistortion(displayInfo.DistortionK); - } - - visitor.Visit(hmdCreateDesc); -} - -} // namespace OVR - - diff --git a/LibOVR/Src/OVR_Win32_SensorDevice.h b/LibOVR/Src/OVR_Win32_SensorDevice.h deleted file mode 100644 index b75ddb2..0000000 --- a/LibOVR/Src/OVR_Win32_SensorDevice.h +++ /dev/null @@ -1,35 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_SensorDevice.h -Content : Win32 SensorDevice implementation -Created : March 12, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_SensorDevice_h -#define OVR_Win32_SensorDevice_h - -namespace OVR { namespace Win32 { - -}} // namespace OVR::Win32 - -#endif // OVR_Win32_SensorDevice_h - diff --git a/LibOVR/Src/Sensors/OVR_DeviceConstants.h b/LibOVR/Src/Sensors/OVR_DeviceConstants.h new file mode 100644 index 0000000..445ae74 --- /dev/null +++ b/LibOVR/Src/Sensors/OVR_DeviceConstants.h @@ -0,0 +1,184 @@ +/************************************************************************************ + +Filename : OVR_DeviceConstants.h +Content : Device constants +Created : February 5, 2013 +Authors : Lee Cooper + +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_DeviceConstants_h +#define OVR_DeviceConstants_h + +#include "../Kernel/OVR_Math.h" + +// CAPI forward declarations. +struct ovrSensorData_; +typedef struct ovrSensorData_ ovrSensorData; + +namespace OVR { + + +//------------------------------------------------------------------------------------- +// Different device types supported by OVR; this type is reported by DeviceBase::GetType. +// +enum DeviceType +{ + Device_None, + Device_Manager, + Device_Sensor, + Device_LatencyTester, + Device_BootLoader, + Device_All = 0xFF // Set for enumeration only, to enumerate all device types. +}; + + + +//------------------------------------------------------------------------------------- +// Different lens distortion types supported by devices. +// +enum DistortionEqnType +{ + Distortion_No_Override = -1, + // These two are leagcy and deprecated. + Distortion_Poly4 = 0, // scale = (K0 + K1*r^2 + K2*r^4 + K3*r^6) + Distortion_RecipPoly4 = 1, // scale = 1/(K0 + K1*r^2 + K2*r^4 + K3*r^6) + + // CatmullRom10 is the preferred distortion format. + Distortion_CatmullRom10 = 2, // scale = Catmull-Rom spline through points (1.0, K[1]...K[9]) + + Distortion_LAST // For ease of enumeration. +}; + + +//------------------------------------------------------------------------------------- +// HMD types. +// +enum HmdTypeEnum +{ + HmdType_None, + + HmdType_DKProto, // First duct-tape model, never sold. + HmdType_DK1, // DevKit1 - on sale to developers. + HmdType_DKHDProto, // DKHD - shown at various shows, never sold. + HmdType_DKHD2Proto, // DKHD2, 5.85-inch panel, never sold. + 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, + + // Reminder - this header file is public - codenames only! + + HmdType_Unknown, // Used for unnamed HW lab experiments. + + HmdType_LAST +}; + + +//------------------------------------------------------------------------------------- +// HMD shutter types. +// +enum HmdShutterTypeEnum +{ + HmdShutter_Global, + HmdShutter_RollingTopToBottom, + HmdShutter_RollingLeftToRight, + HmdShutter_RollingRightToLeft, + // TODO: + // color-sequential e.g. LCOS? + // alternate eyes? + // alternate columns? + // outside-in? + + HmdShutter_LAST +}; + + + +//------------------------------------------------------------------------------------- +// For headsets that use eye cups +// +enum EyeCupType +{ + // Public lenses + EyeCup_DK1A = 0, + EyeCup_DK1B = 1, + EyeCup_DK1C = 2, + + EyeCup_DK2A = 3, + + // Internal R&D codenames. + // Reminder - this header file is public - codenames only! + EyeCup_DKHD2A, + EyeCup_OrangeA, + EyeCup_RedA, + EyeCup_PinkA, + EyeCup_BlueA, + EyeCup_Delilah1A, + EyeCup_Delilah2A, + EyeCup_JamesA, + EyeCup_SunMandalaA, + + EyeCup_LAST +}; + + +//----------------------------------------------------------------------------- +// BodyFrameState +// +#pragma pack(push, 8) + +class SensorDataType +{ +public: + + SensorDataType() : Temperature(0.0f), AbsoluteTimeSeconds(0.0) { } + + // C-interop support + SensorDataType(const ovrSensorData& s); + operator ovrSensorData () const; + + Vector3f Acceleration; // in m/s^2 + Vector3f RotationRate; // in rad/s + Vector3f MagneticField; // in Gauss + + float Temperature; // in degrees Celsius + + // The absolute time from the host computers perspective that the message should be + // interpreted as. This is based on incoming timestamp and processed by a filter + // that syncs the clocks while attempting to keep the distance between messages + // device clock matching. + // + // Integration should use TimeDelta, but prediction into the future should derive + // the delta time from PredictToSeconds - AbsoluteTimeSeconds. + // + // This value will generally be <= the return from a call to ovr_GetTimeInSeconds(), + // but could be greater by under 1 ms due to system time update interrupt delays. + // + double AbsoluteTimeSeconds; +}; + +static_assert((sizeof(SensorDataType) == 3*sizeof(Vector3f) + sizeof(float) + sizeof(double)), "sizeof(SensorDataType) failure"); + +#pragma pack(pop) + + +} // namespace OVR + +#endif diff --git a/LibOVR/Src/Service/Service_NetClient.cpp b/LibOVR/Src/Service/Service_NetClient.cpp new file mode 100644 index 0000000..c6af2cd --- /dev/null +++ b/LibOVR/Src/Service/Service_NetClient.cpp @@ -0,0 +1,882 @@ +/************************************************************************************ + +Filename : Service_NetClient.cpp +Content : Client for service interface +Created : June 12, 2014 +Authors : Michael Antonov, 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 "Service_NetClient.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 { + +using namespace OVR::Net; + + +//// NetClient + +NetClient::NetClient() : + LatencyTesterAvailable(false), + HMDCount(0), + EdgeTriggeredHMDCount(false) +{ + GetSession()->AddSessionListener(this); + + // Register RPC functions + registerRPC(); + + Start(); + + // Must be at end of function + PushDestroyCallbacks(); +} + +NetClient::~NetClient() +{ +} + +void NetClient::OnSystemDestroy() +{ + onSystemDestroy(); +} + +void NetClient::OnThreadDestroy() +{ + onThreadDestroy(); +} + +int NetClient::Run() +{ + SetThreadName("NetClient"); + + while (!Terminated) + { + // Note: There is no watchdog here because the watchdog is part of the private code + + GetSession()->Poll(false); + + if (GetSession()->GetActiveSocketsCount() == 0) + { + Thread::MSleep(10); + } + } + + return 0; +} + +void NetClient::OnReceive(ReceivePayload* pPayload, ListenerReceiveResult* lrrOut) +{ + OVR_UNUSED(lrrOut); + OVR_UNUSED(pPayload); +} + +void NetClient::OnDisconnected(Connection* conn) +{ + OVR_UNUSED(conn); + + OVR_DEBUG_LOG(("[NetClient] Disconnected")); + + EdgeTriggeredHMDCount = false; +} + +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)", + conn->RemoteMajorVersion, conn->RemoteMinorVersion, conn->RemotePatchVersion, + RPCVersion_Major, RPCVersion_Minor, RPCVersion_Patch)); + + EdgeTriggeredHMDCount = false; +} + +bool NetClient::Connect(bool blocking) +{ + // 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); + + // Attempt to connect + OVR::Net::SessionResult result = GetSession()->ConnectPTCP(&bbp, &sa, blocking); + + // Already connected counts as success too + return result == Net::SessionResult_OK || + result == Net::SessionResult_AlreadyConnected || + result == Net::SessionResult_ConnectInProgress; +} + +void NetClient::Disconnect() +{ + GetSession()->Shutdown(); +} + +bool NetClient::IsConnected(bool attemptReconnect, bool blockOnReconnect) +{ + // If it was able to connect, + if (GetSession()->GetConnectionCount() > 0) + { + return true; + } + else if (attemptReconnect) + { + // Attempt to connect here + Connect(blockOnReconnect); + + // If it connected, + if (GetSession()->GetConnectionCount() > 0) + { + return true; + } + } + + // No connections + return false; +} + +void NetClient::GetLocalProtocolVersion(int& major, int& minor, int& patch) +{ + major = RPCVersion_Major; + minor = RPCVersion_Minor; + patch = RPCVersion_Patch; +} + +bool NetClient::GetRemoteProtocolVersion(int& major, int& minor, int& patch) +{ + Ptr conn = GetSession()->GetConnectionAtIndex(0); + + if (conn) + { + major = conn->RemoteMajorVersion; + minor = conn->RemoteMinorVersion; + patch = conn->RemotePatchVersion; + return true; + } + + return false; +} + + +//// NetClient API + +const char* NetClient::GetStringValue(VirtualHmdId hmd, const char* key, const char* default_val) +{ + if (!IsConnected(true, true)) + { + return ""; + } + + // If a null value is provided, + if (!default_val) + { + default_val = ""; + } + + ProfileGetValue1_Str = default_val; + + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + bsOut.Write(key); + bsOut.Write(default_val); + if (!GetRPC1()->CallBlocking("GetStringValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return ""; + } + if (!returnData.Read(ProfileGetValue1_Str)) + { + OVR_ASSERT(false); + } + return ProfileGetValue1_Str.ToCStr(); +} +bool NetClient::GetBoolValue(VirtualHmdId hmd, const char* key, bool default_val) +{ + if (!IsConnected(true, true)) + { + return default_val; + } + + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + bsOut.Write(key); + bsOut.Write(default_val); + if (!GetRPC1()->CallBlocking("GetBoolValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return default_val; + } + uint8_t out = 0; + if (!returnData.Read(out)) + { + OVR_ASSERT(false); + } + return out != 0; +} +int NetClient::GetIntValue(VirtualHmdId hmd, const char* key, int default_val) +{ + if (!IsConnected(true, true)) + { + return default_val; + } + + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + bsOut.Write(key); + bsOut.Write(default_val); + if (!GetRPC1()->CallBlocking("GetIntValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return default_val; + } + int32_t out = (int32_t)default_val; + if (!returnData.Read(out)) + { + OVR_ASSERT(false); + } + return out; +} +double NetClient::GetNumberValue(VirtualHmdId hmd, const char* key, double default_val) +{ + if (!IsConnected(true, true)) + { + return default_val; + } + + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + bsOut.Write(key); + bsOut.Write(default_val); + if (!GetRPC1()->CallBlocking("GetNumberValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return default_val; + } + double out = 0.; + returnData.Read(out); + return out; +} +int NetClient::GetNumberValues(VirtualHmdId hmd, const char* key, double* values, int num_vals) +{ + if (!IsConnected(true, true)) + { + return 0; + } + + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + bsOut.Write(key); + + int32_t w = (int32_t)num_vals; + bsOut.Write(w); + + if (!GetRPC1()->CallBlocking("GetNumberValues_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return 0; + } + + int32_t out = 0; + if (!returnData.Read(out)) + { + OVR_ASSERT(false); + } + OVR_ASSERT(out >= 0 && out <= num_vals); + if (out < 0) + { + out = 0; + } + else if (out > num_vals) + { + out = num_vals; + } + + for (int i = 0; i < out && i < num_vals; i++) + { + if (!returnData.Read(values[i])) + { + return i; + } + } + + return out; +} + +bool NetClient::SetStringValue(VirtualHmdId hmd, const char* key, const char* val) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + bsOut.Write(key); + + bsOut.Write(val); + + if (!GetRPC1()->Signal("SetStringValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) + { + return false; + } + + return true; +} + +bool NetClient::SetBoolValue(VirtualHmdId hmd, const char* key, bool val) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + bsOut.Write(key); + + uint8_t b = val ? 1 : 0; + bsOut.Write(b); + + if (!GetRPC1()->Signal("SetBoolValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) + { + return false; + } + + return true; +} + +bool NetClient::SetIntValue(VirtualHmdId hmd, const char* key, int val) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + bsOut.Write(key); + + int32_t w = (int32_t)val; + bsOut.Write(w); + + if (!GetRPC1()->Signal("SetIntValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) + { + return false; + } + + return true; +} + +bool NetClient::SetNumberValue(VirtualHmdId hmd, const char* key, double val) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + bsOut.Write(key); + + bsOut.Write(val); + + if (!GetRPC1()->Signal("SetNumberValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) + { + return false; + } + + return true; +} + +bool NetClient::SetNumberValues(VirtualHmdId hmd, const char* key, const double* vals, int num_vals) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + bsOut.Write(key); + + int32_t w_count = (int32_t)num_vals; + bsOut.Write(w_count); + + for (int i = 0; i < num_vals; i++) + { + bsOut.Write(vals[i]); + } + + if (!GetRPC1()->Signal("SetNumberValues_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) + { + return false; + } + + return true; +} + +int NetClient::Hmd_Detect() +{ + if (!IsConnected(true, false)) + { + return 0; + } + + // If using edge-triggered HMD counting, + if (EdgeTriggeredHMDCount) + { + // Return the last update from the server + return HMDCount; + } + + // Otherwise: We need to ask the first time + + OVR::Net::BitStream bsOut, returnData; + + if (!GetRPC1()->CallBlocking("Hmd_Detect_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return 0; + } + + int32_t out = 0; + if (!returnData.Read(out)) + { + OVR_ASSERT(false); + } + HMDCount = out; + EdgeTriggeredHMDCount = true; + return out; +} + +bool NetClient::Hmd_Create(int index, HMDNetworkInfo* netInfo) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut, returnData; + + int32_t w = (int32_t)index; + 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; + } + + return netInfo->Deserialize(&returnData); +} + +bool NetClient::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut, returnData; + + bsOut.Write(InvalidVirtualHmdId); + + if (!GetRPC1()->CallBlocking("GetDriverMode_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return false; + } + + int32_t w_driverInstalled = 0; + int32_t w_compatMode = 0; + int32_t w_hideDK1Mode = 0; + returnData.Read(w_driverInstalled); + returnData.Read(w_compatMode); + if (!returnData.Read(w_hideDK1Mode)) + { + return false; + } + + driverInstalled = w_driverInstalled != 0; + compatMode = w_compatMode != 0; + hideDK1Mode = w_hideDK1Mode != 0; + return true; +} + +bool NetClient::SetDriverMode(bool compatMode, bool hideDK1Mode) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut, returnData; + + bsOut.Write(InvalidVirtualHmdId); + + int32_t w_compatMode, w_hideDK1Mode; + w_compatMode = compatMode ? 1 : 0; + w_hideDK1Mode = hideDK1Mode ? 1 : 0; + bsOut.Write(w_compatMode); + bsOut.Write(w_hideDK1Mode); + + if (!GetRPC1()->CallBlocking("SetDriverMode_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return false; + } + + int32_t out = 0; + if (!returnData.Read(out)) + { + OVR_ASSERT(false); + return false; + } + + return out != 0; +} + +bool NetClient::Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow) +{ + if (!IsConnected(false, false)) + { + return false; + } + + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + + #ifdef OVR_OS_LINUX + if (hWindow == NULL) + { + return false; + } + unsigned long hWinWord = *(unsigned long *)hWindow; + #else + UInt64 hWinWord = (UPInt)hWindow; + #endif + bsOut.Write(hWinWord); + + if (!GetRPC1()->CallBlocking("Hmd_AttachToWindow_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) + { + return false; + } + + return true; +} + +void NetClient::Hmd_Release(VirtualHmdId hmd) +{ + if (!IsConnected(false, false)) + { + return; + } + + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + bool result = GetRPC1()->CallBlocking("Hmd_Release_1", &bsOut, GetSession()->GetConnectionAtIndex(0)); + OVR_ASSERT_AND_UNUSED(result, result); +} + +void NetClient::SetLastError(String str) +{ + Hmd_GetLastError_Str = str; +} + +// Last string is cached locally. +const char* NetClient::Hmd_GetLastError(VirtualHmdId hmd) +{ + if (hmd == InvalidVirtualHmdId || !IsConnected(false, false)) + { + return Hmd_GetLastError_Str.ToCStr(); + } + + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + if (!GetRPC1()->CallBlocking("Hmd_GetLastError_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return Hmd_GetLastError_Str.ToCStr(); + } + if (!returnData.Read(Hmd_GetLastError_Str)) + { + OVR_ASSERT(false); + } + return Hmd_GetLastError_Str.ToCStr(); +} + + +// Fills in description about HMD; this is the same as filled in by ovrHmd_Create. +// The actual descriptor is a par +bool NetClient::Hmd_GetHmdInfo(VirtualHmdId hmd, HMDInfo* hmdInfo) +{ + if (!IsConnected(false, false)) + { + 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); +} + + +//------------------------------------------------------------------------------------- +unsigned int NetClient::Hmd_GetEnabledCaps(VirtualHmdId hmd) +{ + if (!IsConnected(false, false)) + { + 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); + } + return c; +} + +// Returns new caps after modification +unsigned int NetClient::Hmd_SetEnabledCaps(VirtualHmdId hmd, unsigned int hmdCaps) +{ + if (!IsConnected(false, false)) + { + return 0; + } + + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + + uint32_t c = (uint32_t)hmdCaps; + bsOut.Write(c); + + if (!GetRPC1()->CallBlocking("Hmd_SetEnabledCaps_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return 0; + } + + c = 0; + if (!returnData.Read(c)) + { + OVR_ASSERT(false); + } + return c; +} + + +//------------------------------------------------------------------------------------- +// *** Tracking Setup + +bool NetClient::Hmd_ConfigureTracking(VirtualHmdId hmd, unsigned supportedCaps, unsigned requiredCaps) +{ + if (!IsConnected(false, false)) + { + return false; + } + + 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; + } + + uint8_t b; + if (!returnData.Read(b)) + { + OVR_ASSERT(false); + } + + return b != 0; +} + + +void NetClient::Hmd_ResetTracking(VirtualHmdId hmd) +{ + if (!IsConnected(false, false)) + { + return; + } + + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + if (!GetRPC1()->CallBlocking("Hmd_ResetTracking_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) + { + return; + } +} + +bool NetClient::LatencyUtil_ProcessInputs(double startTestSeconds, unsigned char rgbColorOut[3]) +{ + if (!IsConnected(false, false)) + { + return false; + } + + if (!LatencyTesterAvailable) + { + return false; + } + + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(startTestSeconds); + if (!GetRPC1()->CallBlocking("LatencyUtil_ProcessInputs_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return false; + } + + uint8_t u; + returnData.Read(u); + rgbColorOut[0] = u; + returnData.Read(u); + rgbColorOut[1] = u; + if (!returnData.Read(u)) + { + return false; + } + rgbColorOut[2] = u; + + return true; +} + +const char* NetClient::LatencyUtil_GetResultsString() +{ + if (!IsConnected(false, false)) + { + return NULL; + } + + OVR::Net::BitStream bsOut, returnData; + if (!GetRPC1()->CallBlocking("LatencyUtil_GetResultsString_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return NULL; + } + + if (!returnData.Read(LatencyUtil_GetResultsString_Str)) + { + OVR_ASSERT(false); + } + + return LatencyUtil_GetResultsString_Str.ToCStr(); +} + +bool NetClient::ShutdownServer() +{ + if (!IsConnected(false, false)) + { + return false; + } + + OVR::Net::BitStream bsOut; + GetRPC1()->BroadcastSignal("Shutdown_1", &bsOut); + + return true; +} + + +//// Push Notifications: + +void NetClient::registerRPC() +{ +#define RPC_REGISTER_SLOT(observerScope, functionName) \ + observerScope.SetHandler(OVR::Net::Plugins::RPCSlot::FromMember(this)); pRPC->RegisterSlot(OVR_STRINGIZE(functionName), observerScope); + + // Register RPC functions: + RPC_REGISTER_SLOT(InitialServerStateScope, InitialServerState_1); + RPC_REGISTER_SLOT(LatencyTesterAvailableScope, LatencyTesterAvailable_1); + RPC_REGISTER_SLOT(DefaultLogOutputScope, DefaultLogOutput_1); + RPC_REGISTER_SLOT(HMDCountUpdateScope, HMDCountUpdate_1); +} + +void NetClient::InitialServerState_1(BitStream* userData, ReceivePayload* pPayload) +{ + LatencyTesterAvailable_1(userData, pPayload); +} + +void NetClient::LatencyTesterAvailable_1(BitStream* userData, ReceivePayload* pPayload) +{ + OVR_UNUSED(pPayload); + + uint8_t b = 0; + if (!userData->Read(b)) + { + OVR_ASSERT(false); + return; + } + + LatencyTesterAvailable = (b != 0); +} + +void NetClient::DefaultLogOutput_1(BitStream* userData, ReceivePayload* pPayload) +{ + OVR_UNUSED(pPayload); + + String formattedText; + LogMessageType messageType = Log_Text; // Will normally be overwritten below. + userData->Read(messageType); + if (userData->Read(formattedText)) + { + if (OVR::Log::GetGlobalLog()) + { + OVR::String logStr = "[From Service] "; + logStr.AppendString(formattedText); + OVR::Log::GetGlobalLog()->LogMessage(messageType, "%s", logStr.ToCStr()); + } + } +} + +void NetClient::HMDCountUpdate_1(BitStream* userData, ReceivePayload* pPayload) +{ + OVR_UNUSED(pPayload); + + int32_t hmdCount = 0; + if (!userData->Read(hmdCount)) + { + OVR_ASSERT(false); + return; + } + + HMDCount = hmdCount; + EdgeTriggeredHMDCount = true; +} + + +}} // namespace OVR::Service diff --git a/LibOVR/Src/Service/Service_NetClient.h b/LibOVR/Src/Service/Service_NetClient.h new file mode 100644 index 0000000..ab7906e --- /dev/null +++ b/LibOVR/Src/Service/Service_NetClient.h @@ -0,0 +1,149 @@ +/************************************************************************************ + +Filename : Service_NetClient.h +Content : Client for service interface +Created : June 12, 2014 +Authors : Michael Antonov, 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_Service_NetClient_h +#define OVR_Service_NetClient_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" + +namespace OVR { namespace Service { + +using namespace OVR::Net; + + +//------------------------------------------------------------------------------------- +// NetClient + +class NetClient : public NetSessionCommon, + public Net::Plugins::NetworkPlugin, + public SystemSingletonBase +{ + 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 + bool GetRemoteProtocolVersion(int& major, int& minor, int& patch); + + void SetLastError(String str); + +public: + // Persistent key-value storage + const char* GetStringValue(VirtualHmdId hmd, const char* key, const char* default_val); + bool GetBoolValue(VirtualHmdId hmd, const char* key, bool default_val); + int GetIntValue(VirtualHmdId hmd, const char* key, int default_val); + double GetNumberValue(VirtualHmdId hmd, const char* key, double default_val); + int GetNumberValues(VirtualHmdId hmd, const char* key, double* values, int num_vals); + + bool SetStringValue(VirtualHmdId hmd, const char* key, const char* val); + bool SetBoolValue(VirtualHmdId hmd, const char* key, bool val); + bool SetIntValue(VirtualHmdId hmd, const char* key, int val); + bool SetNumberValue(VirtualHmdId hmd, const char* key, double val); + bool SetNumberValues(VirtualHmdId hmd, const char* key, const double* vals, int num_vals); + + bool GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode); + bool SetDriverMode(bool compatMode, bool hideDK1Mode); + + int Hmd_Detect(); + bool Hmd_Create(int index, HMDNetworkInfo* netInfo); + void Hmd_Release(VirtualHmdId hmd); + + // Last string is cached locally. + const char* Hmd_GetLastError(VirtualHmdId hmd); + + // TBD: Replace with a function to return internal, original HMDInfo? + + // Fills in description about HMD; this is the same as filled in by ovrHmd_Create. + // The actual descriptor is a par + bool Hmd_GetHmdInfo(VirtualHmdId hmd, HMDInfo* hmdInfo); + + //------------------------------------------------------------------------------------- + unsigned int Hmd_GetEnabledCaps(VirtualHmdId hmd); + // Returns new caps after modification + unsigned int Hmd_SetEnabledCaps(VirtualHmdId hmd, unsigned int hmdCaps); + + // Updates driver render target + bool Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow); + + //------------------------------------------------------------------------------------- + // *** Tracking Setup + + bool Hmd_ConfigureTracking(VirtualHmdId hmd, unsigned supportedCaps, unsigned requiredCaps); + void Hmd_ResetTracking(VirtualHmdId hmd); + + // TBD: Camera frames + bool LatencyUtil_ProcessInputs(double startTestSeconds, unsigned char rgbColorOut[3]); + const char* LatencyUtil_GetResultsString(); + + bool ShutdownServer(); + +protected: + String Hmd_GetLastError_Str; + String LatencyUtil_GetResultsString_Str; + String ProfileGetValue1_Str, ProfileGetValue3_Str; + +protected: + //// Push Notifications: + + void registerRPC(); + + ObserverScope InitialServerStateScope; + void InitialServerState_1(BitStream* userData, ReceivePayload* pPayload); + + ObserverScope LatencyTesterAvailableScope; + void LatencyTesterAvailable_1(BitStream* userData, ReceivePayload* pPayload); + + ObserverScope DefaultLogOutputScope; + void DefaultLogOutput_1(BitStream* userData, ReceivePayload* pPayload); + + ObserverScope HMDCountUpdateScope; + void HMDCountUpdate_1(BitStream* userData, ReceivePayload* pPayload); +}; + + +}} // namespace OVR::Service + +#endif // OVR_Service_NetClient_h diff --git a/LibOVR/Src/Service/Service_NetSessionCommon.cpp b/LibOVR/Src/Service/Service_NetSessionCommon.cpp new file mode 100644 index 0000000..ba2c773 --- /dev/null +++ b/LibOVR/Src/Service/Service_NetSessionCommon.cpp @@ -0,0 +1,343 @@ +/************************************************************************************ + +Filename : Service_NetSessionCommon.cpp +Content : Server for service interface +Created : June 12, 2014 +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 "Service_NetSessionCommon.h" +#include "../OVR_Stereo.h" + +namespace OVR { namespace Service { + + +//// NetSessionCommon + +NetSessionCommon::NetSessionCommon() : + Terminated(false) +{ + pSession = new Net::Session; + OVR_ASSERT(pSession != NULL); + + pRPC = new Net::Plugins::RPC1; + OVR_ASSERT(pRPC != NULL); + + pSession->AddSessionListener(pRPC); +} + +NetSessionCommon::~NetSessionCommon() +{ + if (pSession) + { + delete pSession; + pSession = NULL; + } + if (pRPC) + { + delete pRPC; + pRPC = NULL; + } + + Terminated = true; + + OVR_ASSERT(IsFinished()); +} + +void NetSessionCommon::onSystemDestroy() +{ + Terminated = true; + + Join(); + + Release(); +} + +void NetSessionCommon::onThreadDestroy() +{ + Terminated = true; + if (pSession) + { + pSession->Shutdown(); + } +} + +void NetSessionCommon::SerializeHMDInfo(Net::BitStream *bitStream, HMDInfo* hmdInfo) +{ + 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); + + w = hmdInfo->ShimInfo.DeviceNumber; + bitStream->Write(w); + + w = hmdInfo->ShimInfo.NativeWidth; + bitStream->Write(w); + + w = hmdInfo->ShimInfo.NativeHeight; + bitStream->Write(w); + + w = hmdInfo->ShimInfo.Rotation; + bitStream->Write(w); + + bitStream->Write(hmdInfo->ScreenSizeInMeters.w); + bitStream->Write(hmdInfo->ScreenSizeInMeters.h); + bitStream->Write(hmdInfo->ScreenGapSizeInMeters); + bitStream->Write(hmdInfo->CenterFromTopInMeters); + bitStream->Write(hmdInfo->LensSeparationInMeters); + + w = hmdInfo->DesktopX; + bitStream->Write(w); + + w = hmdInfo->DesktopY; + bitStream->Write(w); + + w = hmdInfo->Shutter.Type; + bitStream->Write(w); + + 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); + + w = hmdInfo->DisplayId; + bitStream->Write(w); + + bitStream->Write(hmdInfo->PrintedSerial); + + uint8_t b = hmdInfo->InCompatibilityMode ? 1 : 0; + bitStream->Write(b); + + w = hmdInfo->VendorId; + bitStream->Write(w); + + w = hmdInfo->ProductId; + bitStream->Write(w); + + bitStream->Write(hmdInfo->CameraFrustumFarZInMeters); + bitStream->Write(hmdInfo->CameraFrustumHFovInRadians); + bitStream->Write(hmdInfo->CameraFrustumNearZInMeters); + bitStream->Write(hmdInfo->CameraFrustumVFovInRadians); + + w = hmdInfo->FirmwareMajor; + bitStream->Write(w); + + w = hmdInfo->FirmwareMinor; + bitStream->Write(w); + + bitStream->Write(hmdInfo->PelOffsetR.x); + bitStream->Write(hmdInfo->PelOffsetR.y); + bitStream->Write(hmdInfo->PelOffsetB.x); + bitStream->Write(hmdInfo->PelOffsetB.y); + + // 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. + + // 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; +} + +// 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 }, +}; + +bool IsInStringArray(const char* a[], const char* key) +{ + for (int i = 0; a[i]; ++i) + { + if (OVR_strcmp(a[i], key) == 0) + return true; + } + + return false; +} + +const char *NetSessionCommon::FilterKeyPrefix(const char* key) +{ + // If key starts with BypassPrefix, + if (strstr(key, BypassPrefix) == key) + { + key += strlen(BypassPrefix); + } + + return key; +} + +bool NetSessionCommon::IsServiceProperty(EGetterSetters e, const char* key) +{ + if ((e >= 0 && e < ENumTypes) && IsInStringArray(KeyNames[e], key)) + { + return true; + } + + // If key starts with BypassPrefix, + if (strstr(key, BypassPrefix) == key) + { + return true; + } + + return false; +} + + +}} // namespace OVR::Service diff --git a/LibOVR/Src/Service/Service_NetSessionCommon.h b/LibOVR/Src/Service/Service_NetSessionCommon.h new file mode 100644 index 0000000..79c0cfb --- /dev/null +++ b/LibOVR/Src/Service/Service_NetSessionCommon.h @@ -0,0 +1,142 @@ +/************************************************************************************ + +Filename : Service_NetSessionCommon.h +Content : Shared networking for service +Created : June 12, 2014 +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_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" + +namespace OVR { + +class HMDInfo; + +namespace Service { + + +//----------------------------------------------------------------------------- +// VirtualHmdId + +// This is an identifier that is unique to each VirtualHmd object on the server +// side. The client side uses this to opaquely reference those objects. + +typedef int32_t VirtualHmdId; +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 + +// HMDInfo section related to networking +struct HMDNetworkInfo +{ + HMDNetworkInfo() : + NetId(InvalidVirtualHmdId) + { + } + + // Network identifier for HMD + VirtualHmdId NetId; + + // Name of the shared memory object + String SharedMemoryName; + + void Serialize(Net::BitStream* bs) + { + bs->Write(NetId); + bs->Write(SharedMemoryName); + } + bool Deserialize(Net::BitStream* bs) + { + bs->Read(NetId); + return bs->Read(SharedMemoryName); + } +}; + + +//------------------------------------------------------------------------------------- +// ***** NetSessionCommon + +// Common part networking session/RPC implementation shared between client and server. + +class NetSessionCommon : public Thread +{ +protected: + virtual void onSystemDestroy(); + virtual void onThreadDestroy(); + +public: + NetSessionCommon(); + virtual ~NetSessionCommon(); + + Net::Plugins::RPC1* GetRPC1() const + { + return pRPC; + } + Net::Session* GetSession() const + { + return pSession; + } + + static void SerializeHMDInfo(Net::BitStream* bitStream, HMDInfo* hmdInfo); + static bool DeserializeHMDInfo(Net::BitStream* bitStream, HMDInfo* hmdInfo); + +public: + // Getter/setter tools + enum EGetterSetters + { + // Note: If this enumeration changes, then the Servce_NetSessionCommon.cpp + // IsServiceProperty() function should be updated. + + EGetStringValue, + EGetBoolValue, + EGetIntValue, + EGetNumberValue, + EGetNumberValues, + ESetStringValue, + ESetBoolValue, + ESetIntValue, + ESetNumberValue, + ESetNumberValues, + + ENumTypes + }; + + static const char* FilterKeyPrefix(const char* key); + static bool IsServiceProperty(EGetterSetters e, const char* key); + +protected: + bool Terminated; // Thread termination flag + Net::Session* pSession; // Networking session + Net::Plugins::RPC1* pRPC; // Remote procedure calls object +}; + + +}} // namespace OVR::Service + +#endif // OVR_Service_NetSessionCommon_h diff --git a/LibOVR/Src/Tracking/Tracking_PoseState.h b/LibOVR/Src/Tracking/Tracking_PoseState.h new file mode 100644 index 0000000..19e2ee2 --- /dev/null +++ b/LibOVR/Src/Tracking/Tracking_PoseState.h @@ -0,0 +1,133 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..e13c3ef --- /dev/null +++ b/LibOVR/Src/Tracking/Tracking_SensorState.h @@ -0,0 +1,212 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..a506b26 --- /dev/null +++ b/LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp @@ -0,0 +1,207 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..c2922c8 --- /dev/null +++ b/LibOVR/Src/Tracking/Tracking_SensorStateReader.h @@ -0,0 +1,87 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..a1b35ed --- /dev/null +++ b/LibOVR/Src/Util/GUIConsole.h @@ -0,0 +1,51 @@ +/************************************************************************************ + +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_ImageWindow.cpp b/LibOVR/Src/Util/Util_ImageWindow.cpp index cb091c7..4c120f9 100644 --- a/LibOVR/Src/Util/Util_ImageWindow.cpp +++ b/LibOVR/Src/Util/Util_ImageWindow.cpp @@ -5,16 +5,16 @@ Content : An output object for windows that can display raw images for tes Created : March 13, 2014 Authors : Dean Beeler -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -23,12 +23,13 @@ See the License for the specific language governing permissions and limitations under the License. *************************************************************************************/ -#include "../../Include/OVR.h" +#include "../../Include/OVR_Kernel.h" #include "Util_ImageWindow.h" #if defined(OVR_OS_WIN32) +#define WIN32_LEAN_AND_MEAN #include #include "DWrite.h" @@ -51,7 +52,16 @@ namespace OVR { namespace Util { ID2D1Factory* ImageWindow::pD2DFactory = NULL; IDWriteFactory* ImageWindow::pDWriteFactory = NULL; -ImageWindow* ImageWindow::globalWindow[4]; +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( @@ -95,55 +105,69 @@ LRESULT CALLBACK MainWndProc( //return 0; } + ImageWindow::ImageWindow( uint32_t width, uint32_t height ) : - frontBufferMutex( new Mutex() ) + hWindow(NULL), + pRT(NULL), + //resolution(), + frontBufferMutex( new Mutex() ), + frames(), + greyBitmap(NULL), + colorBitmap(NULL) { - - HINSTANCE hInst = LoadLibrary( L"d2d1.dll" ); - HINSTANCE hInstWrite = LoadLibrary( L"Dwrite.dll" ); - D2D1CreateFactoryFn createFactory = NULL; DWriteCreateFactoryFn writeFactory = NULL; - if( hInst ) + if (!hInstD2d1) + { + hInstD2d1 = LoadLibraryW( L"d2d1.dll" ); + } + + if (!hInstD2d1) + { + hInstD2d1 = LoadLibraryW( L"Dwrite.dll" ); + } + + if( hInstD2d1 ) { - createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInst, "D2D1CreateFactory" ); + createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInstD2d1, "D2D1CreateFactory" ); } - if( hInstWrite ) + if( hInstDwrite ) { - writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstWrite, "DWriteCreateFactory" ); + writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstDwrite, "DWriteCreateFactory" ); } - globalWindow[windowCount] = this; - - ++windowCount; + // TODO: see note where globalWindow is declared. + globalWindow[windowCount++ % MaxWindows] = this; + OVR_ASSERT(windowCount < MaxWindows); if( pD2DFactory == NULL && createFactory && writeFactory ) { - createFactory( + // Create a Direct2D factory. + HRESULT hResult = createFactory( D2D1_FACTORY_TYPE_MULTI_THREADED, __uuidof(ID2D1Factory), NULL, - &pD2DFactory + &pD2DFactory // This will be AddRef'd for us. ); + OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); // Create a DirectWrite factory. - writeFactory( + hResult = writeFactory( DWRITE_FACTORY_TYPE_SHARED, - __uuidof(pDWriteFactory), - reinterpret_cast(&pDWriteFactory) + __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 ); - SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this ); - - pRT = NULL; - greyBitmap = NULL; - colorBitmap = NULL; + if (hWindow) + { + SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this ); + } } ImageWindow::~ImageWindow() @@ -155,7 +179,7 @@ ImageWindow::~ImageWindow() globalWindow[i] = NULL; break; } -} + } if( greyBitmap ) greyBitmap->Release(); @@ -177,81 +201,110 @@ ImageWindow::~ImageWindow() delete frontBufferMutex; - ShowWindow( hWindow, SW_HIDE ); - DestroyWindow( hWindow ); + 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 ) { - // 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; - } - - result = tmpTarget->CreateBitmap( size, colorBitmapProps, &colorBitmap ); - if( result != S_OK ) - { - greyBitmap->Release(); - greyBitmap = NULL; - - tmpTarget->Release(); - tmpTarget = NULL; - } - pRT = tmpTarget; - } - } + 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() @@ -508,4 +561,14 @@ void ImageWindow::addText( float x, float y, float r, float g, float b, OVR::Str }} -#endif //defined(OVR_OS_WIN32) \ No newline at end of file +#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 index 4b88959..979dd93 100644 --- a/LibOVR/Src/Util/Util_ImageWindow.h +++ b/LibOVR/Src/Util/Util_ImageWindow.h @@ -7,14 +7,14 @@ Authors : Dean Beeler Copyright : Copyright 2014 Oculus, Inc. All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -28,13 +28,14 @@ limitations under the License. #define UTIL_IMAGEWINDOW_H #if defined(OVR_OS_WIN32) -#define WIN32_LEAN_AND_MEAN 1 -#include +#include +#include +#define WIN32_LEAN_AND_MEAN +#include #include #include #endif -#include "../../Include/OVR.h" #include "../Kernel/OVR_Hash.h" #include "../Kernel/OVR_Array.h" #include "../Kernel/OVR_Threads.h" @@ -154,6 +155,9 @@ private: static int windowCount; static ID2D1Factory* pD2DFactory; static IDWriteFactory* pDWriteFactory; + static HINSTANCE hInstD2d1; + static HINSTANCE hInstDwrite; + }; #else @@ -171,16 +175,16 @@ public: 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 ) { } - void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) { } + 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 ) { } + void AssociateSurface( void* surface ) { OVR_UNUSED(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 ) { } + 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; } @@ -197,4 +201,4 @@ private: }} // namespace OVR::Util -#endif \ No newline at end of file +#endif diff --git a/LibOVR/Src/Util/Util_Interface.cpp b/LibOVR/Src/Util/Util_Interface.cpp index d96423c..5090729 100644 --- a/LibOVR/Src/Util/Util_Interface.cpp +++ b/LibOVR/Src/Util/Util_Interface.cpp @@ -8,16 +8,16 @@ Content : Simple interface, utilised by internal demos, Created : February 20, 2014 Authors : Tom Heath -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -31,4 +31,4 @@ limitations under the License. -//Files left in to ease its possible return...... \ No newline at end of file +//Files left in to ease its possible return...... diff --git a/LibOVR/Src/Util/Util_Interface.h b/LibOVR/Src/Util/Util_Interface.h index 1bbf638..ab08715 100644 --- a/LibOVR/Src/Util/Util_Interface.h +++ b/LibOVR/Src/Util/Util_Interface.h @@ -1,6 +1,5 @@ /************************************************************************************ -PublicHeader: OVR.h Filename : Util_Interface.h Content : Simple interface, utilised by internal demos, with access to wider SDK as needed. @@ -9,16 +8,16 @@ Content : Simple interface, utilised by internal demos, Created : February 20, 2014 Authors : Tom Heath -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -30,7 +29,7 @@ limitations under the License. #ifndef OVR_Util_Interface_h #define OVR_Util_Interface_h -#include "../../Src/OVR_CAPI.h" +#include "../OVR_CAPI.h" //Files left in to ease its possible return...... diff --git a/LibOVR/Src/Util/Util_LatencyTest.cpp b/LibOVR/Src/Util/Util_LatencyTest.cpp deleted file mode 100644 index 3017c72..0000000 --- a/LibOVR/Src/Util/Util_LatencyTest.cpp +++ /dev/null @@ -1,570 +0,0 @@ -/************************************************************************************ - -Filename : Util_LatencyTest.cpp -Content : Wraps the lower level LatencyTester interface and adds functionality. -Created : February 14, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_LatencyTest.h" - -#include "../Kernel/OVR_Log.h" -#include "../Kernel/OVR_Timer.h" - -namespace OVR { namespace Util { - -static const UInt32 TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION = 16*10; -static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION = 16*10; -static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT = 16*5; -static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS = 16*5; -static const UInt32 DEFAULT_NUMBER_OF_SAMPLES = 10; // For both color 1->2 and color 2->1 transitions. -static const UInt32 INITIAL_SAMPLES_TO_IGNORE = 4; -static const UInt32 TIMEOUT_WAITING_FOR_TEST_STARTED = 1000; -static const UInt32 TIMEOUT_WAITING_FOR_COLOR_DETECTED = 4000; -static const Color CALIBRATE_BLACK(0, 0, 0); -static const Color CALIBRATE_WHITE(255, 255, 255); -static const Color COLOR1(0, 0, 0); -static const Color COLOR2(255, 255, 255); -static const Color SENSOR_DETECT_THRESHOLD(128, 255, 255); -static const float BIG_FLOAT = 1000000.0f; -static const float SMALL_FLOAT = -1000000.0f; - -//------------------------------------------------------------------------------------- -// ***** LatencyTest - -LatencyTest::LatencyTest(LatencyTestDevice* device) - : Handler(getThis()) -{ - if (device != NULL) - { - SetDevice(device); - } - - reset(); - - srand(Timer::GetTicksMs()); -} - -LatencyTest::~LatencyTest() -{ - clearMeasurementResults(); -} - -bool LatencyTest::SetDevice(LatencyTestDevice* device) -{ - - if (device != Device) - { - Handler.RemoveHandlerFromDevices(); - - Device = device; - - if (Device != NULL) - { - Device->AddMessageHandler(&Handler); - - // Set trigger threshold. - LatencyTestConfiguration configuration(SENSOR_DETECT_THRESHOLD, false); // No samples streaming. - Device->SetConfiguration(configuration, true); - - // Set display to initial (3 dashes). - LatencyTestDisplay ltd(2, 0x40400040); - Device->SetDisplay(ltd); - } - } - - return true; -} - -UInt32 LatencyTest::getRandomComponent(UInt32 range) -{ - UInt32 val = rand() % range; - return val; -} - -void LatencyTest::BeginTest() -{ - if (State == State_WaitingForButton) - { - // Set color to black and wait a while. - RenderColor = CALIBRATE_BLACK; - - State = State_WaitingForSettlePreCalibrationColorBlack; - OVR_DEBUG_LOG(("State_WaitingForButton -> State_WaitingForSettlePreCalibrationColorBlack.")); - - setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION); - } -} - -void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage) -{ - // For debugging. -/* if (msg.Type == Message_LatencyTestSamples) - { - MessageLatencyTestSamples* pSamples = (MessageLatencyTestSamples*) &msg; - - if (pSamples->Samples.GetSize() > 0) - { - // Just show the first one for now. - Color c = pSamples->Samples[0]; - OVR_DEBUG_LOG(("%d %d %d", c.R, c.G, c.B)); - } - return; - } -*/ - - if (latencyTestMessage == LatencyTest_Timer) - { - if (!Device) - { - reset(); - return; - } - - if (State == State_WaitingForSettlePreCalibrationColorBlack) - { - // Send calibrate message to device and wait a while. - Device->SetCalibrate(CALIBRATE_BLACK); - - State = State_WaitingForSettlePostCalibrationColorBlack; - OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorBlack -> State_WaitingForSettlePostCalibrationColorBlack.")); - - setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION); - } - else if (State == State_WaitingForSettlePostCalibrationColorBlack) - { - // Change color to white and wait a while. - RenderColor = CALIBRATE_WHITE; - - State = State_WaitingForSettlePreCalibrationColorWhite; - OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorBlack -> State_WaitingForSettlePreCalibrationColorWhite.")); - - setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION); - } - else if (State == State_WaitingForSettlePreCalibrationColorWhite) - { - // Send calibrate message to device and wait a while. - Device->SetCalibrate(CALIBRATE_WHITE); - - State = State_WaitingForSettlePostCalibrationColorWhite; - OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorWhite -> State_WaitingForSettlePostCalibrationColorWhite.")); - - setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION); - } - else if (State == State_WaitingForSettlePostCalibrationColorWhite) - { - // Calibration is done. Switch to color 1 and wait for it to settle. - RenderColor = COLOR1; - - State = State_WaitingForSettlePostMeasurement; - OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorWhite -> State_WaitingForSettlePostMeasurement.")); - - UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS); - setTimer(waitTime); - } - else if (State == State_WaitingForSettlePostMeasurement) - { - // Prepare for next measurement. - - // Create a new result object. - MeasurementResult* pResult = new MeasurementResult(); - Results.PushBack(pResult); - - State = State_WaitingToTakeMeasurement; - OVR_DEBUG_LOG(("State_WaitingForSettlePostMeasurement -> State_WaitingToTakeMeasurement.")); - } - else if (State == State_WaitingForTestStarted) - { - // We timed out waiting for 'TestStarted'. Abandon this measurement and setup for the next. - getActiveResult()->TimedOutWaitingForTestStarted = true; - - State = State_WaitingForSettlePostMeasurement; - OVR_DEBUG_LOG(("** Timed out waiting for 'TestStarted'.")); - OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForSettlePostMeasurement.")); - - UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS); - setTimer(waitTime); - } - else if (State == State_WaitingForColorDetected) - { - // We timed out waiting for 'ColorDetected'. Abandon this measurement and setup for the next. - getActiveResult()->TimedOutWaitingForColorDetected = true; - - State = State_WaitingForSettlePostMeasurement; - OVR_DEBUG_LOG(("** Timed out waiting for 'ColorDetected'.")); - OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement.")); - - UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS); - setTimer(waitTime); - } - } - else if (latencyTestMessage == LatencyTest_ProcessInputs) - { - if (State == State_WaitingToTakeMeasurement) - { - if (!Device) - { - reset(); - return; - } - - // Send 'StartTest' feature report with opposite target color. - if (RenderColor == COLOR1) - { - RenderColor = COLOR2; - } - else - { - RenderColor = COLOR1; - } - - getActiveResult()->TargetColor = RenderColor; - - // Record time so we can determine usb roundtrip time. - getActiveResult()->StartTestSeconds = Timer::GetSeconds(); - - Device->SetStartTest(RenderColor); - - State = State_WaitingForTestStarted; - OVR_DEBUG_LOG(("State_WaitingToTakeMeasurement -> State_WaitingForTestStarted.")); - - setTimer(TIMEOUT_WAITING_FOR_TEST_STARTED); - - LatencyTestDisplay ltd(2, 0x40090040); - Device->SetDisplay(ltd); - } - } - else if (msg.Type == Message_LatencyTestButton) - { - BeginTest(); - } - else if (msg.Type == Message_LatencyTestStarted) - { - if (State == State_WaitingForTestStarted) - { - clearTimer(); - - // Record time so we can determine usb roundtrip time. - getActiveResult()->TestStartedSeconds = Timer::GetSeconds(); - - State = State_WaitingForColorDetected; - OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForColorDetected.")); - - setTimer(TIMEOUT_WAITING_FOR_COLOR_DETECTED); - } - } - else if (msg.Type == Message_LatencyTestColorDetected) - { - if (State == State_WaitingForColorDetected) - { - // Record time to detect color. - MessageLatencyTestColorDetected* pDetected = (MessageLatencyTestColorDetected*) &msg; - UInt16 elapsedTime = pDetected->Elapsed; - OVR_DEBUG_LOG(("Time to 'ColorDetected' = %d", elapsedTime)); - - getActiveResult()->DeviceMeasuredElapsedMilliS = elapsedTime; - - if (areResultsComplete()) - { - // We're done. - processResults(); - reset(); - } - else - { - // Run another measurement. - State = State_WaitingForSettlePostMeasurement; - OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement.")); - - UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS); - setTimer(waitTime); - - LatencyTestDisplay ltd(2, 0x40400040); - Device->SetDisplay(ltd); - } - } - } - else if (msg.Type == Message_DeviceRemoved) - { - reset(); - } -} - -LatencyTest::MeasurementResult* LatencyTest::getActiveResult() -{ - OVR_ASSERT(!Results.IsEmpty()); - return Results.GetLast(); -} - -void LatencyTest::setTimer(UInt32 timeMilliS) -{ - ActiveTimerMilliS = timeMilliS; -} - -void LatencyTest::clearTimer() -{ - ActiveTimerMilliS = 0; -} - -void LatencyTest::reset() -{ - clearMeasurementResults(); - State = State_WaitingForButton; - - HaveOldTime = false; - ActiveTimerMilliS = 0; -} - -void LatencyTest::clearMeasurementResults() -{ - while(!Results.IsEmpty()) - { - MeasurementResult* pElem = Results.GetFirst(); - pElem->RemoveNode(); - delete pElem; - } -} - -LatencyTest::LatencyTestHandler::~LatencyTestHandler() -{ - RemoveHandlerFromDevices(); -} - -void LatencyTest::LatencyTestHandler::OnMessage(const Message& msg) -{ - pLatencyTestUtil->handleMessage(msg); -} - -void LatencyTest::ProcessInputs() -{ - updateForTimeouts(); - handleMessage(Message(), LatencyTest_ProcessInputs); -} - -bool LatencyTest::DisplayScreenColor(Color& colorToDisplay) -{ - updateForTimeouts(); - - if (State == State_WaitingForButton) - { - return false; - } - - colorToDisplay = RenderColor; - return true; -} - -const char* LatencyTest::GetResultsString() -{ - if (!ResultsString.IsEmpty() && ReturnedResultString != ResultsString.ToCStr()) - { - ReturnedResultString = ResultsString; - return ReturnedResultString.ToCStr(); - } - - return NULL; -} - -bool LatencyTest::areResultsComplete() -{ - UInt32 initialMeasurements = 0; - - UInt32 measurements1to2 = 0; - UInt32 measurements2to1 = 0; - - MeasurementResult* pCurr = Results.GetFirst(); - while(true) - { - // Process. - if (!pCurr->TimedOutWaitingForTestStarted && - !pCurr->TimedOutWaitingForColorDetected) - { - initialMeasurements++; - - if (initialMeasurements > INITIAL_SAMPLES_TO_IGNORE) - { - if (pCurr->TargetColor == COLOR2) - { - measurements1to2++; - } - else - { - measurements2to1++; - } - } - } - - if (Results.IsLast(pCurr)) - { - break; - } - pCurr = Results.GetNext(pCurr); - } - - if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES && - measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES) - { - return true; - } - - return false; -} - -void LatencyTest::processResults() -{ - - UInt32 minTime1To2 = UINT_MAX; - UInt32 maxTime1To2 = 0; - float averageTime1To2 = 0.0f; - UInt32 minTime2To1 = UINT_MAX; - UInt32 maxTime2To1 = 0; - float averageTime2To1 = 0.0f; - - float minUSBTripMilliS = BIG_FLOAT; - float maxUSBTripMilliS = SMALL_FLOAT; - float averageUSBTripMilliS = 0.0f; - UInt32 countUSBTripTime = 0; - - UInt32 measurementsCount = 0; - UInt32 measurements1to2 = 0; - UInt32 measurements2to1 = 0; - - MeasurementResult* pCurr = Results.GetFirst(); - UInt32 count = 0; - while(true) - { - count++; - - if (!pCurr->TimedOutWaitingForTestStarted && - !pCurr->TimedOutWaitingForColorDetected) - { - measurementsCount++; - - if (measurementsCount > INITIAL_SAMPLES_TO_IGNORE) - { - if (pCurr->TargetColor == COLOR2) - { - measurements1to2++; - - if (measurements1to2 <= DEFAULT_NUMBER_OF_SAMPLES) - { - UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS; - - minTime1To2 = Alg::Min(elapsed, minTime1To2); - maxTime1To2 = Alg::Max(elapsed, maxTime1To2); - - averageTime1To2 += (float) elapsed; - } - } - else - { - measurements2to1++; - - if (measurements2to1 <= DEFAULT_NUMBER_OF_SAMPLES) - { - UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS; - - minTime2To1 = Alg::Min(elapsed, minTime2To1); - maxTime2To1 = Alg::Max(elapsed, maxTime2To1); - - averageTime2To1 += (float) elapsed; - } - } - - float usbRountripElapsedMilliS = Timer::MsPerSecond * (float) (pCurr->TestStartedSeconds - pCurr->StartTestSeconds); - minUSBTripMilliS = Alg::Min(usbRountripElapsedMilliS, minUSBTripMilliS); - maxUSBTripMilliS = Alg::Max(usbRountripElapsedMilliS, maxUSBTripMilliS); - averageUSBTripMilliS += usbRountripElapsedMilliS; - countUSBTripTime++; - } - } - - if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES && - measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES) - { - break; - } - - if (Results.IsLast(pCurr)) - { - break; - } - pCurr = Results.GetNext(pCurr); - } - - averageTime1To2 /= (float) DEFAULT_NUMBER_OF_SAMPLES; - averageTime2To1 /= (float) DEFAULT_NUMBER_OF_SAMPLES; - - averageUSBTripMilliS /= countUSBTripTime; - - float finalResult = 0.5f * (averageTime1To2 + averageTime2To1); - finalResult += averageUSBTripMilliS; - - ResultsString.Clear(); - ResultsString.AppendFormat("RESULT=%.1f (add half Tracker period) [b->w %d|%.1f|%d] [w->b %d|%.1f|%d] [usb rndtrp %.1f|%.1f|%.1f] [cnt %d] [tmouts %d]", - finalResult, - minTime1To2, averageTime1To2, maxTime1To2, - minTime2To1, averageTime2To1, maxTime2To1, - minUSBTripMilliS, averageUSBTripMilliS, maxUSBTripMilliS, - DEFAULT_NUMBER_OF_SAMPLES*2, count - measurementsCount); - - // Display result on latency tester display. - LatencyTestDisplay ltd(1, (int)finalResult); - Device->SetDisplay(ltd); -} - -void LatencyTest::updateForTimeouts() -{ - if (!HaveOldTime) - { - HaveOldTime = true; - OldTime = Timer::GetTicksMs(); - return; - } - - UInt32 newTime = Timer::GetTicksMs(); - UInt32 elapsedMilliS = newTime - OldTime; - if (newTime < OldTime) - { - elapsedMilliS = OldTime - newTime; - elapsedMilliS = UINT_MAX - elapsedMilliS; - } - OldTime = newTime; - - elapsedMilliS = Alg::Min(elapsedMilliS, (UInt32) 100); // Clamp at 100mS in case we're not being called very often. - - - if (ActiveTimerMilliS == 0) - { - return; - } - - if (elapsedMilliS >= ActiveTimerMilliS) - { - ActiveTimerMilliS = 0; - handleMessage(Message(), LatencyTest_Timer); - return; - } - - ActiveTimerMilliS -= elapsedMilliS; -} - -}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_LatencyTest.h b/LibOVR/Src/Util/Util_LatencyTest.h deleted file mode 100644 index 0844603..0000000 --- a/LibOVR/Src/Util/Util_LatencyTest.h +++ /dev/null @@ -1,173 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : Util_LatencyTest.h -Content : Wraps the lower level LatencyTesterDevice and adds functionality. -Created : February 14, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_LatencyTest_h -#define OVR_Util_LatencyTest_h - -#include "../OVR_Device.h" - -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_List.h" - -namespace OVR { namespace Util { - - -//------------------------------------------------------------------------------------- -// ***** LatencyTest -// -// LatencyTest utility class wraps the low level LatencyTestDevice and manages the scheduling -// of a latency test. A single test is composed of a series of individual latency measurements -// which are used to derive min, max, and an average latency value. -// -// Developers are required to call the following methods: -// SetDevice - Sets the LatencyTestDevice to be used for the tests. -// ProcessInputs - This should be called at the same place in the code where the game engine -// reads the headset orientation from LibOVR (typically done by calling -// 'GetOrientation' on the SensorFusion object). Calling this at the right time -// enables us to measure the same latency that occurs for headset orientation -// changes. -// DisplayScreenColor - The latency tester works by sensing the color of the pixels directly -// beneath it. The color of these pixels can be set by drawing a small -// quad at the end of the rendering stage. The quad should be small -// such that it doesn't significantly impact the rendering of the scene, -// but large enough to be 'seen' by the sensor. See the SDK -// documentation for more information. -// GetResultsString - Call this to get a string containing the most recent results. -// If the string has already been gotten then NULL will be returned. -// The string pointer will remain valid until the next time this -// method is called. -// - -class LatencyTest : public NewOverrideBase -{ -public: - LatencyTest(LatencyTestDevice* device = NULL); - ~LatencyTest(); - - // Set the Latency Tester device that we'll use to send commands to and receive - // notification messages from. - bool SetDevice(LatencyTestDevice* device); - - // Returns true if this LatencyTestUtil has a Latency Tester device. - bool HasDevice() const - { return Handler.IsHandlerInstalled(); } - - void ProcessInputs(); - bool DisplayScreenColor(Color& colorToDisplay); - const char* GetResultsString(); - - bool IsMeasuringNow() const { return (State != State_WaitingForButton); } - - // Begin test. Equivalent to pressing the button on the latency tester. - void BeginTest(); - -private: - LatencyTest* getThis() { return this; } - - enum LatencyTestMessageType - { - LatencyTest_None, - LatencyTest_Timer, - LatencyTest_ProcessInputs, - }; - - UInt32 getRandomComponent(UInt32 range); - void handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage = LatencyTest_None); - void reset(); - void setTimer(UInt32 timeMilliS); - void clearTimer(); - - class LatencyTestHandler : public MessageHandler - { - LatencyTest* pLatencyTestUtil; - public: - LatencyTestHandler(LatencyTest* latencyTester) : pLatencyTestUtil(latencyTester) { } - ~LatencyTestHandler(); - - virtual void OnMessage(const Message& msg); - }; - - bool areResultsComplete(); - void processResults(); - void updateForTimeouts(); - - Ptr Device; - LatencyTestHandler Handler; - - enum TesterState - { - State_WaitingForButton, - State_WaitingForSettlePreCalibrationColorBlack, - State_WaitingForSettlePostCalibrationColorBlack, - State_WaitingForSettlePreCalibrationColorWhite, - State_WaitingForSettlePostCalibrationColorWhite, - State_WaitingToTakeMeasurement, - State_WaitingForTestStarted, - State_WaitingForColorDetected, - State_WaitingForSettlePostMeasurement - }; - TesterState State; - - bool HaveOldTime; - UInt32 OldTime; - UInt32 ActiveTimerMilliS; - - Color RenderColor; - - struct MeasurementResult : public ListNode, public NewOverrideBase - { - MeasurementResult() - : DeviceMeasuredElapsedMilliS(0), - TimedOutWaitingForTestStarted(false), - TimedOutWaitingForColorDetected(false), - StartTestSeconds(0.0), - TestStartedSeconds(0.0) - {} - - Color TargetColor; - - UInt32 DeviceMeasuredElapsedMilliS; - - bool TimedOutWaitingForTestStarted; - bool TimedOutWaitingForColorDetected; - - double StartTestSeconds; - double TestStartedSeconds; - }; - - List Results; - void clearMeasurementResults(); - - MeasurementResult* getActiveResult(); - - StringBuffer ResultsString; - String ReturnedResultString; -}; - -}} // namespace OVR::Util - -#endif // OVR_Util_LatencyTest_h diff --git a/LibOVR/Src/Util/Util_LatencyTest2.cpp b/LibOVR/Src/Util/Util_LatencyTest2.cpp deleted file mode 100644 index 6fc8b1f..0000000 --- a/LibOVR/Src/Util/Util_LatencyTest2.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/************************************************************************************ - -Filename : Util_LatencyTest2.cpp -Content : Wraps the lower level LatencyTester interface for DK2 and adds functionality. -Created : March 10, 2014 -Authors : Volga Aksoy - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_LatencyTest2.h" - -#include "../OVR_CAPI.h" -#include "../Kernel/OVR_Log.h" -#include "../Kernel/OVR_Timer.h" - - -namespace OVR { namespace Util { - -//------------------------------------------------------------------------------------- -// ***** LatencyTest2 - -LatencyTest2::LatencyTest2(SensorDevice* device) - : Handler(getThis()) - , TestActive(false) - , StartTiming(-1) - , LatencyMeasuredInSeconds(-1) - , LastPixelReadMsg(NULL) - , RenderColorValue(0) - , NumMsgsBeforeSettle(0) - , NumTestsSuccessful(0) -{ - if (device != NULL) - { - SetSensorDevice(device); - } -} - -LatencyTest2::~LatencyTest2() -{ - HmdDevice = NULL; - LatencyTesterDev = NULL; - - Handler.RemoveHandlerFromDevices(); -} - -bool LatencyTest2::SetSensorDevice(SensorDevice* device) -{ - Lock::Locker devLocker(&TesterLock); - - // Enable/Disable pixel read from HMD - if (device != HmdDevice) - { - Handler.RemoveHandlerFromDevices(); - - HmdDevice = device; - - if (HmdDevice != NULL) - { - HmdDevice->AddMessageHandler(&Handler); - } - } - - return true; -} - -bool LatencyTest2::SetDisplayDevice(LatencyTestDevice* device) -{ - Lock::Locker devLocker(&TesterLock); - - if (device != LatencyTesterDev) - { - LatencyTesterDev = device; - if (LatencyTesterDev != NULL) - { - // Set display to initial (3 dashes). - LatencyTestDisplay ltd(2, 0x40400040); - LatencyTesterDev->SetDisplay(ltd); - } - } - - return true; -} - -void LatencyTest2::BeginTest(double startTime) -{ - Lock::Locker devLocker(&TesterLock); - - if (!TestActive) - { - TestActive = true; - NumMsgsBeforeSettle = 0; - - // Go to next pixel value - //RenderColorValue = (RenderColorValue == 0) ? 255 : 0; - RenderColorValue = (RenderColorValue + LT2_ColorIncrement) % 256; - RawStartTiming = LastPixelReadMsg.RawSensorTime; - - if (startTime > 0.0) - StartTiming = startTime; - else - StartTiming = ovr_GetTimeInSeconds(); - - } -} - -void LatencyTest2::handleMessage(const MessagePixelRead& msg) -{ - Lock::Locker devLocker(&TesterLock); - - // Hold onto the last message as we will use this when we start a new test - LastPixelReadMsg = msg; - - // If color readback index is valid, store it in the lock-less queue. - int readbackIndex = 0; - if (FrameTimeRecord::ColorToReadbackIndex(&readbackIndex, msg.PixelReadValue)) - { - RecentFrameSet.AddValue(readbackIndex, msg.FrameTimeSeconds); - LockessRecords.SetState(RecentFrameSet); - } - - NumMsgsBeforeSettle++; - - if (TestActive) - { - int pixelValueDiff = RenderColorValue - LastPixelReadMsg.PixelReadValue; - int rawTimeDiff = LastPixelReadMsg.RawFrameTime - RawStartTiming; - - if (pixelValueDiff < LT2_PixelTestThreshold && pixelValueDiff > -LT2_PixelTestThreshold) - { - TestActive = false; - - LatencyMeasuredInSeconds = LastPixelReadMsg.FrameTimeSeconds - StartTiming; - RawLatencyMeasured = rawTimeDiff; - //LatencyMeasuredInSeconds = RawLatencyMeasured / 1000000.0; - - if(LatencyTesterDev && (NumTestsSuccessful % 5) == 0) - { - int displayNum = (int)(RawLatencyMeasured / 100.0); - //int displayNum = NumMsgsBeforeSettle; - //int displayNum = (int)(LatencyMeasuredInSeconds * 1000.0); - LatencyTestDisplay ltd(1, displayNum); - LatencyTesterDev->SetDisplay(ltd); - } - - NumTestsSuccessful++; - } - else if (TestActive && (rawTimeDiff / 1000) > LT2_TimeoutWaitingForColorDetected) - { - TestActive = false; - LatencyMeasuredInSeconds = -1; - } - } -} - -LatencyTest2::PixelReadHandler::~PixelReadHandler() -{ - RemoveHandlerFromDevices(); -} - -void LatencyTest2::PixelReadHandler::OnMessage(const Message& msg) -{ - if(msg.Type == Message_PixelRead) - pLatencyTestUtil->handleMessage(static_cast(msg)); -} - -bool LatencyTest2::DisplayScreenColor(Color& colorToDisplay) -{ - Lock::Locker devLocker(&TesterLock); - colorToDisplay = Color(RenderColorValue, RenderColorValue, RenderColorValue, 255); - - return TestActive; -} - -}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_LatencyTest2.h b/LibOVR/Src/Util/Util_LatencyTest2.h deleted file mode 100644 index 61e8477..0000000 --- a/LibOVR/Src/Util/Util_LatencyTest2.h +++ /dev/null @@ -1,238 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : Util_LatencyTest2.h -Content : Wraps the lower level LatencyTester interface for DK2 and adds functionality. -Created : March 10, 2014 -Authors : Volga Aksoy - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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_LatencyTest2_h -#define OVR_Util_LatencyTest2_h - -#include "../OVR_Device.h" - -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_List.h" -#include "../Kernel/OVR_Lockless.h" - -namespace OVR { namespace Util { - - -enum { - LT2_ColorIncrement = 32, - LT2_PixelTestThreshold = LT2_ColorIncrement / 3, - LT2_IncrementCount = 256 / LT2_ColorIncrement, - LT2_TimeoutWaitingForColorDetected = 1000 // 1 second -}; - -//------------------------------------------------------------------------------------- - -// Describes frame scanout time used for latency testing. -struct FrameTimeRecord -{ - int ReadbackIndex; - double TimeSeconds; - - // Utility functions to convert color to readBack indices and back. - // The purpose of ReadbackIndex is to allow direct comparison by value. - - static bool ColorToReadbackIndex(int *readbackIndex, unsigned char color) - { - int compareColor = color - LT2_ColorIncrement/2; - int index = color / LT2_ColorIncrement; // Use color without subtraction due to rounding. - int delta = compareColor - index * LT2_ColorIncrement; - - if ((delta < LT2_PixelTestThreshold) && (delta > -LT2_PixelTestThreshold)) - { - *readbackIndex = index; - return true; - } - return false; - } - - static unsigned char ReadbackIndexToColor(int readbackIndex) - { - OVR_ASSERT(readbackIndex < LT2_IncrementCount); - return (unsigned char)(readbackIndex * LT2_ColorIncrement + LT2_ColorIncrement/2); - } -}; - -// FrameTimeRecordSet is a container holding multiple consecutive frame timing records -// returned from the lock-less state. Used by FrameTimeManager. - -struct FrameTimeRecordSet -{ - enum { - RecordCount = 4, - RecordMask = RecordCount - 1 - }; - FrameTimeRecord Records[RecordCount]; - int NextWriteIndex; - - FrameTimeRecordSet() - { - NextWriteIndex = 0; - memset(this, 0, sizeof(FrameTimeRecordSet)); - } - - void AddValue(int readValue, double timeSeconds) - { - Records[NextWriteIndex].ReadbackIndex = readValue; - Records[NextWriteIndex].TimeSeconds = timeSeconds; - NextWriteIndex ++; - if (NextWriteIndex == RecordCount) - NextWriteIndex = 0; - } - // Matching should be done starting from NextWrite index - // until wrap-around - - const FrameTimeRecord& operator [] (int i) const - { - return Records[(NextWriteIndex + i) & RecordMask]; - } - - const FrameTimeRecord& GetMostRecentFrame() - { - return Records[(NextWriteIndex - 1) & RecordMask]; - } - - // Advances I to absolute color index - bool FindReadbackIndex(int* i, int readbackIndex) const - { - for (; *i < RecordCount; (*i)++) - { - if ((*this)[*i].ReadbackIndex == readbackIndex) - return true; - } - return false; - } - - bool IsAllZeroes() const - { - for (int i = 0; i < RecordCount; i++) - if (Records[i].ReadbackIndex != 0) - return false; - return true; - } -}; - - -//------------------------------------------------------------------------------------- -// ***** LatencyTest2 -// -// LatencyTest2 utility class wraps the low level SensorDevice and manages the scheduling -// of a latency test. A single test is composed of a series of individual latency measurements -// which are used to derive min, max, and an average latency value. -// -// Developers are required to call the following methods: -// SetDevice - Sets the SensorDevice to be used for the tests. -// ProcessInputs - This should be called at the same place in the code where the game engine -// reads the headset orientation from LibOVR (typically done by calling -// 'GetOrientation' on the SensorFusion object). Calling this at the right time -// enables us to measure the same latency that occurs for headset orientation -// changes. -// DisplayScreenColor - The latency tester works by sensing the color of the pixels directly -// beneath it. The color of these pixels can be set by drawing a small -// quad at the end of the rendering stage. The quad should be small -// such that it doesn't significantly impact the rendering of the scene, -// but large enough to be 'seen' by the sensor. See the SDK -// documentation for more information. -// GetResultsString - Call this to get a string containing the most recent results. -// If the string has already been gotten then NULL will be returned. -// The string pointer will remain valid until the next time this -// method is called. -// - -class LatencyTest2 : public NewOverrideBase -{ -public: - LatencyTest2(SensorDevice* device = NULL); - ~LatencyTest2(); - - // Set the Latency Tester device that we'll use to send commands to and receive - // notification messages from. - bool SetSensorDevice(SensorDevice* device); - bool SetDisplayDevice(LatencyTestDevice* device); - - // Returns true if this LatencyTestUtil has a Latency Tester device. - bool HasDisplayDevice() const { return LatencyTesterDev.GetPtr() != NULL; } - bool HasDevice() const { return Handler.IsHandlerInstalled(); } - - bool DisplayScreenColor(Color& colorToDisplay); - //const char* GetResultsString(); - - // Begin test. Equivalent to pressing the button on the latency tester. - void BeginTest(double startTime = -1.0f); - bool IsMeasuringNow() const { return TestActive; } - double GetMeasuredLatency() const { return LatencyMeasuredInSeconds; } - -// - FrameTimeRecordSet GetLocklessState() { return LockessRecords.GetState(); } - -private: - LatencyTest2* getThis() { return this; } - - enum LatencyTestMessageType - { - LatencyTest_None, - LatencyTest_Timer, - LatencyTest_ProcessInputs, - }; - - void handleMessage(const MessagePixelRead& msg); - - class PixelReadHandler : public MessageHandler - { - LatencyTest2* pLatencyTestUtil; - public: - PixelReadHandler(LatencyTest2* latencyTester) : pLatencyTestUtil(latencyTester) { } - ~PixelReadHandler(); - - virtual void OnMessage(const Message& msg); - }; - PixelReadHandler Handler; - - Ptr HmdDevice; - Ptr LatencyTesterDev; - - Lock TesterLock; - bool TestActive; - unsigned char RenderColorValue; - MessagePixelRead LastPixelReadMsg; - double StartTiming; - unsigned int RawStartTiming; - UInt32 RawLatencyMeasured; - double LatencyMeasuredInSeconds; - int NumMsgsBeforeSettle; - unsigned int NumTestsSuccessful; - - // MA: - // Frames are added here, then copied into lockess state - FrameTimeRecordSet RecentFrameSet; - LocklessUpdater LockessRecords; -}; - - - -}} // namespace OVR::Util - -#endif // OVR_Util_LatencyTest2_h diff --git a/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp b/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp new file mode 100644 index 0000000..e34bf19 --- /dev/null +++ b/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp @@ -0,0 +1,118 @@ +/************************************************************************************ + +Filename : Util_LatencyTest2Reader.cpp +Content : Shared functionality for the DK2 latency tester +Created : July 8, 2014 +Authors : Volga Aksoy, 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_LatencyTest2Reader.h" + +namespace OVR { namespace Util { + + +//// FrameTimeRecord + +bool FrameTimeRecord::ColorToReadbackIndex(int *readbackIndex, unsigned char color) +{ + int compareColor = color - LT2_ColorIncrement/2; + int index = color / LT2_ColorIncrement; // Use color without subtraction due to rounding. + int delta = compareColor - index * LT2_ColorIncrement; + + if ((delta < LT2_PixelTestThreshold) && (delta > -LT2_PixelTestThreshold)) + { + *readbackIndex = index; + return true; + } + return false; +} + +unsigned char FrameTimeRecord::ReadbackIndexToColor(int readbackIndex) +{ + OVR_ASSERT(readbackIndex < LT2_IncrementCount); + return (unsigned char)(readbackIndex * LT2_ColorIncrement + LT2_ColorIncrement/2); +} + + +//// FrameTimeRecordSet + +FrameTimeRecordSet::FrameTimeRecordSet() +{ + NextWriteIndex = 0; + memset(this, 0, sizeof(FrameTimeRecordSet)); +} + +void FrameTimeRecordSet::AddValue(int readValue, double timeSeconds) +{ + Records[NextWriteIndex].ReadbackIndex = readValue; + Records[NextWriteIndex].TimeSeconds = timeSeconds; + NextWriteIndex++; + if (NextWriteIndex == RecordCount) + NextWriteIndex = 0; +} +// Matching should be done starting from NextWrite index +// until wrap-around + +const FrameTimeRecord& FrameTimeRecordSet::operator [] (int i) const +{ + return Records[(NextWriteIndex + i) & RecordMask]; +} + +const FrameTimeRecord& FrameTimeRecordSet::GetMostRecentFrame() +{ + return Records[(NextWriteIndex - 1) & RecordMask]; +} + +// Advances I to absolute color index +bool FrameTimeRecordSet::FindReadbackIndex(int* i, int readbackIndex) const +{ + for (; *i < RecordCount; (*i)++) + { + if ((*this)[*i].ReadbackIndex == readbackIndex) + return true; + } + return false; +} + +bool FrameTimeRecordSet::IsAllZeroes() const +{ + for (int i = 0; i < RecordCount; i++) + if (Records[i].ReadbackIndex != 0) + return false; + return true; +} + + +//// RecordStateReader + +void RecordStateReader::GetRecordSet(FrameTimeRecordSet& recordset) +{ + if(!Updater) + { + return; + } + + recordset = Updater->SharedLatencyTestState.GetState(); + return; +} + + +}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_LatencyTest2Reader.h b/LibOVR/Src/Util/Util_LatencyTest2Reader.h new file mode 100644 index 0000000..1863e62 --- /dev/null +++ b/LibOVR/Src/Util/Util_LatencyTest2Reader.h @@ -0,0 +1,63 @@ +/************************************************************************************ + +Filename : Util_LatencyTest2Reader.h +Content : Shared functionality for the DK2 latency tester +Created : July 8, 2014 +Authors : Volga Aksoy, 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_LatencyTest2Reader_h +#define OVR_Util_LatencyTest2Reader_h + +#include "../Tracking/Tracking_SensorState.h" +#include "Util_LatencyTest2State.h" + +namespace OVR { namespace Util { + + +//----------------------------------------------------------------------------- +// RecordStateReader + +// User interface to retrieve pose from the sensor fusion subsystem +class RecordStateReader : public NewOverrideBase +{ +protected: + const Tracking::CombinedSharedStateUpdater* Updater; + +public: + RecordStateReader() + : Updater(NULL) + { + } + + // Initialize the updater + void SetUpdater(const Tracking::CombinedSharedStateUpdater *updater) + { + Updater = updater; + } + + void GetRecordSet(FrameTimeRecordSet& recordset); +}; + + +}} // namespace OVR::Util + +#endif // OVR_Util_LatencyTest2Reader_h diff --git a/LibOVR/Src/Util/Util_LatencyTest2State.h b/LibOVR/Src/Util/Util_LatencyTest2State.h new file mode 100644 index 0000000..0b4ffd6 --- /dev/null +++ b/LibOVR/Src/Util/Util_LatencyTest2State.h @@ -0,0 +1,96 @@ +/************************************************************************************ + +Filename : Util_LatencyTest2Reader.h +Content : Shared functionality for the DK2 latency tester +Created : July 8, 2014 +Authors : Volga Aksoy, 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_LatencyTest2_State_h +#define OVR_Util_LatencyTest2_State_h + +#include "../Kernel/OVR_Lockless.h" + +namespace OVR { namespace Util { + + +enum LatencyTester2Constants +{ + LT2_ColorIncrement = 32, + LT2_PixelTestThreshold = LT2_ColorIncrement / 3, + LT2_IncrementCount = 256 / LT2_ColorIncrement, + LT2_TimeoutWaitingForColorDetected = 1000 // 1 second +}; + + +//------------------------------------------------------------------------------------- +// FrameTimeRecord + +// Describes frame scan-out time used for latency testing. +struct FrameTimeRecord +{ + int ReadbackIndex; + double TimeSeconds; + + // Utility functions to convert color to readBack indices and back. + // The purpose of ReadbackIndex is to allow direct comparison by value. + + static bool ColorToReadbackIndex(int *readbackIndex, unsigned char color); + static unsigned char ReadbackIndexToColor(int readbackIndex); +}; + + +//----------------------------------------------------------------------------- +// FrameTimeRecordSet + +// FrameTimeRecordSet is a container holding multiple consecutive frame timing records +// returned from the lock-less state. Used by FrameTimeManager. +struct FrameTimeRecordSet +{ + enum { + RecordCount = 4, + RecordMask = RecordCount - 1 + }; + FrameTimeRecord Records[RecordCount]; + int NextWriteIndex; + + FrameTimeRecordSet(); + + void AddValue(int readValue, double timeSeconds); + // Matching should be done starting from NextWrite index + // until wrap-around + + const FrameTimeRecord& operator [] (int i) const; + + const FrameTimeRecord& GetMostRecentFrame(); + + // Advances I to absolute color index + bool FindReadbackIndex(int* i, int readbackIndex) const; + + bool IsAllZeroes() const; +}; + +typedef LocklessUpdater LockessRecordUpdater; + + +}} // namespace OVR::Util + +#endif // OVR_Util_LatencyTest2_State_h diff --git a/LibOVR/Src/Util/Util_Render_Stereo.cpp b/LibOVR/Src/Util/Util_Render_Stereo.cpp index e84381e..aa82b35 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.cpp +++ b/LibOVR/Src/Util/Util_Render_Stereo.cpp @@ -5,18 +5,18 @@ Content : Stereo rendering configuration implementation Created : October 22, 2012 Authors : Michael Antonov, Andrew Reisse, Tom Forsyth -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 +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,10 +25,11 @@ limitations under the License. *************************************************************************************/ #include "Util_Render_Stereo.h" -#include "../OVR_SensorFusion.h" namespace OVR { namespace Util { namespace Render { +using namespace OVR::Tracking; + //----------------------------------------------------------------------------------- // **** Useful debug functions. @@ -37,21 +38,21 @@ char const* GetDebugNameEyeCupType ( EyeCupType eyeCupType ) { switch ( eyeCupType ) { - case EyeCup_DK1A: return "DK1 A"; break; - case EyeCup_DK1B: return "DK1 B"; break; - case EyeCup_DK1C: return "DK1 C"; break; - case EyeCup_DKHD2A: return "DKHD2 A"; break; - case EyeCup_OrangeA: return "Orange A"; break; - case EyeCup_RedA: return "Red A"; break; - case EyeCup_PinkA: return "Pink A"; break; - case EyeCup_BlueA: return "Blue A"; break; - case EyeCup_Delilah1A: return "Delilah 1 A"; break; - case EyeCup_Delilah2A: return "Delilah 2 A"; break; - case EyeCup_JamesA: return "James A"; break; - case EyeCup_SunMandalaA: return "Sun Mandala A"; break; - case EyeCup_DK2A: return "DK2 A"; break; - case EyeCup_LAST: return "LAST"; break; - default: OVR_ASSERT ( false ); return "Error"; break; + case EyeCup_DK1A: return "DK1 A"; + case EyeCup_DK1B: return "DK1 B"; + case EyeCup_DK1C: return "DK1 C"; + case EyeCup_DKHD2A: return "DKHD2 A"; + case EyeCup_OrangeA: return "Orange A"; + case EyeCup_RedA: return "Red A"; + case EyeCup_PinkA: return "Pink A"; + case EyeCup_BlueA: return "Blue A"; + case EyeCup_Delilah1A: return "Delilah 1 A"; + case EyeCup_Delilah2A: return "Delilah 2 A"; + case EyeCup_JamesA: return "James A"; + case EyeCup_SunMandalaA: return "Sun Mandala A"; + case EyeCup_DK2A: return "DK2 A"; + case EyeCup_LAST: return "LAST"; + default: OVR_ASSERT ( false ); return "Error"; } } @@ -59,17 +60,17 @@ char const* GetDebugNameHmdType ( HmdTypeEnum hmdType ) { switch ( hmdType ) { - case HmdType_None: return "None"; break; - case HmdType_DK1: return "DK1"; break; - case HmdType_DKProto: return "DK1 prototype"; break; - case HmdType_DKHDProto: return "DK HD prototype 1"; break; - case HmdType_DKHDProto566Mi: return "DK HD prototype 566 Mi"; break; - case HmdType_DKHD2Proto: return "DK HD prototype 585"; break; - case HmdType_CrystalCoveProto: return "Crystal Cove"; break; - case HmdType_DK2: return "DK2"; break; - case HmdType_Unknown: return "Unknown"; break; - case HmdType_LAST: return "LAST"; break; - default: OVR_ASSERT ( false ); return "Error"; break; + case HmdType_None: return "None"; + case HmdType_DK1: return "DK1"; + case HmdType_DKProto: return "DK1 prototype"; + case HmdType_DKHDProto: return "DK HD prototype 1"; + case HmdType_DKHDProto566Mi: return "DK HD prototype 566 Mi"; + case HmdType_DKHD2Proto: return "DK HD prototype 585"; + case HmdType_CrystalCoveProto: return "Crystal Cove"; + case HmdType_DK2: return "DK2"; + case HmdType_Unknown: return "Unknown"; + case HmdType_LAST: return "LAST"; + default: OVR_ASSERT ( false ); return "Error"; } } @@ -80,7 +81,7 @@ char const* GetDebugNameHmdType ( HmdTypeEnum hmdType ) struct DistortionAndFov { DistortionRenderDesc Distortion; - FovPort Fov; + FovPort Fov; }; static DistortionAndFov CalculateDistortionAndFovInternal ( StereoEye eyeType, HmdRenderInfo const &hmd, @@ -198,14 +199,14 @@ static StereoEyeParams CalculateStereoEyeParamsInternal ( StereoEye eyeType, Hmd // this is the mapping of actual physical eye FOV (and our eyes do not zoom!) // to screen space. ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov ( fov ); - + // The size of the final FB, which is fixed and determined by the physical size of the device display. Recti distortedViewport = GetFramebufferViewport ( eyeType, hmd ); Vector3f virtualCameraOffset = CalculateEyeVirtualCameraOffset(hmd, eyeType, bMonoRenderingMode); StereoEyeParams result; result.Eye = eyeType; - result.ViewAdjust = Matrix4f::Translation(virtualCameraOffset); + result.HmdToEyeViewOffset = Matrix4f::Translation(virtualCameraOffset); result.Distortion = distortion; result.DistortionViewport = distortedViewport; result.Fov = fov; @@ -372,6 +373,8 @@ StereoConfig::StereoConfig(StereoMode mode) Hmd.ResolutionInPixels = Sizei(1280, 800); Hmd.ScreenSizeInMeters = Sizef(0.1498f, 0.0936f); Hmd.ScreenGapSizeInMeters = 0.0f; + Hmd.PelOffsetR = Vector2f ( 0.0f, 0.0f ); + Hmd.PelOffsetB = Vector2f ( 0.0f, 0.0f ); Hmd.CenterFromTopInMeters = 0.0468f; Hmd.LensSeparationInMeters = 0.0635f; Hmd.LensDiameterInMeters = 0.035f; @@ -442,7 +445,7 @@ const StereoEyeParamsWithOrtho& StereoConfig::GetEyeRenderParams(StereoEye eye) UpdateComputedState(); } - static const UByte eyeParamIndices[3] = { 0, 0, 1 }; + static const uint8_t eyeParamIndices[3] = { 0, 0, 1 }; OVR_ASSERT(eye < sizeof(eyeParamIndices)); return EyeRenderParams[eyeParamIndices[eye]]; @@ -544,8 +547,10 @@ void StereoConfig::UpdateComputedState() eyeTypes[1] = StereoEye_Right; break; - default: - OVR_ASSERT( false ); break; + default: + numEyes = 0; + OVR_ASSERT( false ); + break; } // If either of these fire, you've probably forgotten to call SetRendertargetSize() @@ -787,13 +792,106 @@ static const int DMA_NumTrisPerEye = (DMA_GridSize)*(DMA_GridSize)*2; -void DistortionMeshDestroy ( DistortionMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices ) +DistortionMeshVertexData DistortionMeshMakeVertex ( Vector2f screenNDC, + bool rightEye, + const HmdRenderInfo &hmdRenderInfo, + const DistortionRenderDesc &distortion, const ScaleAndOffset2D &eyeToSourceNDC ) +{ + DistortionMeshVertexData result; + + float xOffset = 0.0f; + if (rightEye) + { + xOffset = 1.0f; + } + + Vector2f tanEyeAnglesR, tanEyeAnglesG, tanEyeAnglesB; + TransformScreenNDCToTanFovSpaceChroma ( &tanEyeAnglesR, &tanEyeAnglesG, &tanEyeAnglesB, + distortion, screenNDC ); + + result.TanEyeAnglesR = tanEyeAnglesR; + result.TanEyeAnglesG = tanEyeAnglesG; + result.TanEyeAnglesB = tanEyeAnglesB; + + HmdShutterTypeEnum shutterType = hmdRenderInfo.Shutter.Type; + switch ( shutterType ) + { + case HmdShutter_Global: + result.TimewarpLerp = 0.0f; + break; + case HmdShutter_RollingLeftToRight: + // Retrace is left to right - left eye goes 0.0 -> 0.5, then right goes 0.5 -> 1.0 + result.TimewarpLerp = screenNDC.x * 0.25f + 0.25f; + if (rightEye) + { + result.TimewarpLerp += 0.5f; + } + break; + case HmdShutter_RollingRightToLeft: + // Retrace is right to left - right eye goes 0.0 -> 0.5, then left goes 0.5 -> 1.0 + result.TimewarpLerp = 0.75f - screenNDC.x * 0.25f; + if (rightEye) + { + result.TimewarpLerp -= 0.5f; + } + break; + case HmdShutter_RollingTopToBottom: + // Retrace is top to bottom on both eyes at the same time. + result.TimewarpLerp = screenNDC.y * 0.5f + 0.5f; + break; + default: OVR_ASSERT ( false ); break; + } + + // When does the fade-to-black edge start? Chosen heuristically. + float fadeOutBorderFractionTexture = 0.1f; + float fadeOutBorderFractionTextureInnerEdge = 0.1f; + float fadeOutBorderFractionScreen = 0.1f; + float fadeOutFloor = 0.6f; // the floor controls how much black is in the fade region + + if (hmdRenderInfo.HmdType == HmdType_DK1) + { + fadeOutBorderFractionTexture = 0.3f; + fadeOutBorderFractionTextureInnerEdge = 0.075f; + fadeOutBorderFractionScreen = 0.075f; + fadeOutFloor = 0.25f; + } + + // Fade out at texture edges. + // The furthest out will be the blue channel, because of chromatic aberration (true of any standard lens) + Vector2f sourceTexCoordBlueNDC = TransformTanFovSpaceToRendertargetNDC ( eyeToSourceNDC, tanEyeAnglesB ); + if (rightEye) + { + // The inner edge of the eye texture is usually much more magnified, because it's right against the middle of the screen, not the FOV edge. + // So we want a different scaling factor for that. This code flips the texture NDC so that +1.0 is the inner edge + sourceTexCoordBlueNDC.x = -sourceTexCoordBlueNDC.x; + } + float edgeFadeIn = ( 1.0f / fadeOutBorderFractionTextureInnerEdge ) * ( 1.0f - sourceTexCoordBlueNDC.x ) ; // Inner + edgeFadeIn = Alg::Min ( edgeFadeIn, ( 1.0f / fadeOutBorderFractionTexture ) * ( 1.0f + sourceTexCoordBlueNDC.x ) ); // Outer + edgeFadeIn = Alg::Min ( edgeFadeIn, ( 1.0f / fadeOutBorderFractionTexture ) * ( 1.0f - sourceTexCoordBlueNDC.y ) ); // Upper + edgeFadeIn = Alg::Min ( edgeFadeIn, ( 1.0f / fadeOutBorderFractionTexture ) * ( 1.0f + sourceTexCoordBlueNDC.y ) ); // Lower + + // Also fade out at screen edges. Since this is in pixel space, no need to do inner specially. + float edgeFadeInScreen = ( 1.0f / fadeOutBorderFractionScreen ) * + ( 1.0f - Alg::Max ( Alg::Abs ( screenNDC.x ), Alg::Abs ( screenNDC.y ) ) ); + edgeFadeIn = Alg::Min ( edgeFadeInScreen, edgeFadeIn ) + fadeOutFloor; + + // 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; + + return result; +} + + +void DistortionMeshDestroy ( DistortionMeshVertexData *pVertices, uint16_t *pTriangleMeshIndices ) { OVR_FREE ( pVertices ); OVR_FREE ( pTriangleMeshIndices ); } -void DistortionMeshCreate ( DistortionMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, +void DistortionMeshCreate ( DistortionMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, int *pNumVertices, int *pNumTriangles, const StereoEyeParams &stereoParams, const HmdRenderInfo &hmdRenderInfo ) { @@ -804,17 +902,17 @@ void DistortionMeshCreate ( DistortionMeshVertexData **ppVertices, UInt16 **ppTr // Generate mesh into allocated data and return result. DistortionMeshCreate(ppVertices, ppTriangleListIndices, &vertexCount, &triangleCount, rightEye, hmdRenderInfo, stereoParams.Distortion, stereoParams.EyeToSourceNDC); - + *pNumVertices = vertexCount; *pNumTriangles = triangleCount; } // Generate distortion mesh for a eye. -void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, +void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, int *pNumVertices, int *pNumTriangles, bool rightEye, - const HmdRenderInfo &hmdRenderInfo, + const HmdRenderInfo &hmdRenderInfo, const DistortionRenderDesc &distortion, const ScaleAndOffset2D &eyeToSourceNDC ) { *pNumVertices = DMA_NumVertsPerEye; @@ -822,7 +920,7 @@ void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTri *ppVertices = (DistortionMeshVertexData*) OVR_ALLOC( sizeof(DistortionMeshVertexData) * (*pNumVertices) ); - *ppTriangleListIndices = (UInt16*) OVR_ALLOC( sizeof(UInt16) * (*pNumTriangles) * 3 ); + *ppTriangleListIndices = (uint16_t*) OVR_ALLOC( sizeof(uint16_t) * (*pNumTriangles) * 3 ); if (!*ppVertices || !*ppTriangleListIndices) { @@ -841,20 +939,9 @@ void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTri return; } - // When does the fade-to-black edge start? Chosen heuristically. - const float fadeOutBorderFraction = 0.075f; - - - // Populate vertex buffer info - float xOffset = 0.0f; - float uOffset = 0.0f; - OVR_UNUSED(uOffset); - if (rightEye) - { - xOffset = 1.0f; - uOffset = 0.5f; - } + + // Populate vertex buffer info // First pass - build up raw vertex data. DistortionMeshVertexData* pcurVert = *ppVertices; @@ -870,72 +957,23 @@ void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTri sourceCoordNDC.y = 2.0f * ( (float)y / (float)DMA_GridSize ) - 1.0f; Vector2f tanEyeAngle = TransformRendertargetNDCToTanFovSpace ( eyeToSourceNDC, sourceCoordNDC ); - // This is the function that does the really heavy lifting. + // Find a corresponding screen position. + // Note - this function does not have to be precise - we're just trying to match the mesh tessellation + // with the shape of the distortion to minimise the number of trianlges needed. Vector2f screenNDC = TransformTanFovSpaceToScreenNDC ( distortion, tanEyeAngle, false ); - - // We then need RGB UVs. Since chromatic aberration is generated from screen coords, not - // directly from texture NDCs, we can't just use tanEyeAngle, we need to go the long way round. - Vector2f tanEyeAnglesR, tanEyeAnglesG, tanEyeAnglesB; - TransformScreenNDCToTanFovSpaceChroma ( &tanEyeAnglesR, &tanEyeAnglesG, &tanEyeAnglesB, - distortion, screenNDC ); - - pcurVert->TanEyeAnglesR = tanEyeAnglesR; - pcurVert->TanEyeAnglesG = tanEyeAnglesG; - pcurVert->TanEyeAnglesB = tanEyeAnglesB; - - - HmdShutterTypeEnum shutterType = hmdRenderInfo.Shutter.Type; - switch ( shutterType ) - { - case HmdShutter_Global: - pcurVert->TimewarpLerp = 0.0f; - break; - case HmdShutter_RollingLeftToRight: - // Retrace is left to right - left eye goes 0.0 -> 0.5, then right goes 0.5 -> 1.0 - pcurVert->TimewarpLerp = screenNDC.x * 0.25f + 0.25f; - if (rightEye) - { - pcurVert->TimewarpLerp += 0.5f; - } - break; - case HmdShutter_RollingRightToLeft: - // Retrace is right to left - right eye goes 0.0 -> 0.5, then left goes 0.5 -> 1.0 - pcurVert->TimewarpLerp = 0.75f - screenNDC.x * 0.25f; - if (rightEye) - { - pcurVert->TimewarpLerp -= 0.5f; - } - break; - case HmdShutter_RollingTopToBottom: - // Retrace is top to bottom on both eyes at the same time. - pcurVert->TimewarpLerp = screenNDC.y * 0.5f + 0.5f; - break; - default: OVR_ASSERT ( false ); break; - } - - // Fade out at texture edges. - float edgeFadeIn = ( 1.0f / fadeOutBorderFraction ) * - ( 1.0f - Alg::Max ( Alg::Abs ( sourceCoordNDC.x ), Alg::Abs ( sourceCoordNDC.y ) ) ); - // Also fade out at screen edges. - float edgeFadeInScreen = ( 2.0f / fadeOutBorderFraction ) * - ( 1.0f - Alg::Max ( Alg::Abs ( screenNDC.x ), Alg::Abs ( screenNDC.y ) ) ); - edgeFadeIn = Alg::Min ( edgeFadeInScreen, edgeFadeIn ); - - // Don't let verts overlap to the other eye. + // ...but don't let verts overlap to the other eye. screenNDC.x = Alg::Max ( -1.0f, Alg::Min ( screenNDC.x, 1.0f ) ); screenNDC.y = Alg::Max ( -1.0f, Alg::Min ( screenNDC.y, 1.0f ) ); - pcurVert->Shade = Alg::Max ( 0.0f, Alg::Min ( edgeFadeIn, 1.0f ) ); - pcurVert->ScreenPosNDC.x = 0.5f * screenNDC.x - 0.5f + xOffset; - pcurVert->ScreenPosNDC.y = -screenNDC.y; - + // From those screen positions, generate the vertex. + *pcurVert = DistortionMeshMakeVertex ( screenNDC, rightEye, hmdRenderInfo, distortion, eyeToSourceNDC ); pcurVert++; } } - // Populate index buffer info - UInt16 *pcurIndex = *ppTriangleListIndices; + // Populate index buffer info + uint16_t *pcurIndex = *ppTriangleListIndices; for ( int triNum = 0; triNum < DMA_GridSize * DMA_GridSize; triNum++ ) { @@ -982,23 +1020,23 @@ void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTri // so linear interpolation works better & we can use fewer tris. if ( ( x < DMA_GridSize/2 ) != ( y < DMA_GridSize/2 ) ) // != is logical XOR { - *pcurIndex++ = (UInt16)FirstVertex; - *pcurIndex++ = (UInt16)FirstVertex+1; - *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1)+1; + *pcurIndex++ = (uint16_t)FirstVertex; + *pcurIndex++ = (uint16_t)FirstVertex+1; + *pcurIndex++ = (uint16_t)FirstVertex+(DMA_GridSize+1)+1; - *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1)+1; - *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1); - *pcurIndex++ = (UInt16)FirstVertex; + *pcurIndex++ = (uint16_t)FirstVertex+(DMA_GridSize+1)+1; + *pcurIndex++ = (uint16_t)FirstVertex+(DMA_GridSize+1); + *pcurIndex++ = (uint16_t)FirstVertex; } else { - *pcurIndex++ = (UInt16)FirstVertex; - *pcurIndex++ = (UInt16)FirstVertex+1; - *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1); + *pcurIndex++ = (uint16_t)FirstVertex; + *pcurIndex++ = (uint16_t)FirstVertex+1; + *pcurIndex++ = (uint16_t)FirstVertex+(DMA_GridSize+1); - *pcurIndex++ = (UInt16)FirstVertex+1; - *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1)+1; - *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1); + *pcurIndex++ = (uint16_t)FirstVertex+1; + *pcurIndex++ = (uint16_t)FirstVertex+(DMA_GridSize+1)+1; + *pcurIndex++ = (uint16_t)FirstVertex+(DMA_GridSize+1); } } } @@ -1013,13 +1051,13 @@ static const int HMA_NumVertsPerEye = (HMA_GridSize+1)*(HMA_GridSize+1); static const int HMA_NumTrisPerEye = (HMA_GridSize)*(HMA_GridSize)*2; -void HeightmapMeshDestroy ( HeightmapMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices ) +void HeightmapMeshDestroy ( HeightmapMeshVertexData *pVertices, uint16_t *pTriangleMeshIndices ) { OVR_FREE ( pVertices ); OVR_FREE ( pTriangleMeshIndices ); } -void HeightmapMeshCreate ( HeightmapMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, +void HeightmapMeshCreate ( HeightmapMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, int *pNumVertices, int *pNumTriangles, const StereoEyeParams &stereoParams, const HmdRenderInfo &hmdRenderInfo ) { @@ -1037,7 +1075,7 @@ void HeightmapMeshCreate ( HeightmapMeshVertexData **ppVertices, UInt16 **ppTria // Generate heightmap mesh for one eye. -void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, +void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, int *pNumVertices, int *pNumTriangles, bool rightEye, const HmdRenderInfo &hmdRenderInfo, const ScaleAndOffset2D &eyeToSourceNDC ) @@ -1046,7 +1084,7 @@ void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTrian *pNumTriangles = HMA_NumTrisPerEye; *ppVertices = (HeightmapMeshVertexData*) OVR_ALLOC( sizeof(HeightmapMeshVertexData) * (*pNumVertices) ); - *ppTriangleListIndices = (UInt16*) OVR_ALLOC( sizeof(UInt16) * (*pNumTriangles) * 3 ); + *ppTriangleListIndices = (uint16_t*) OVR_ALLOC( sizeof(uint16_t) * (*pNumTriangles) * 3 ); if (!*ppVertices || !*ppTriangleListIndices) { @@ -1066,14 +1104,7 @@ void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTrian } // Populate vertex buffer info - float xOffset = 0.0f; - float uOffset = 0.0f; - - if (rightEye) - { - xOffset = 1.0f; - uOffset = 0.5f; - } + // float xOffset = (rightEye ? 1.0f : 0.0f); Currently disabled because its usage is disabled below. // First pass - build up raw vertex data. HeightmapMeshVertexData* pcurVert = *ppVertices; @@ -1087,7 +1118,7 @@ void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTrian sourceCoordNDC.x = 2.0f * ( (float)x / (float)HMA_GridSize ) - 1.0f; sourceCoordNDC.y = 2.0f * ( (float)y / (float)HMA_GridSize ) - 1.0f; Vector2f tanEyeAngle = TransformRendertargetNDCToTanFovSpace ( eyeToSourceNDC, sourceCoordNDC ); - + pcurVert->TanEyeAngles = tanEyeAngle; HmdShutterTypeEnum shutterType = hmdRenderInfo.Shutter.Type; @@ -1132,8 +1163,8 @@ void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTrian } - // Populate index buffer info - UInt16 *pcurIndex = *ppTriangleListIndices; + // Populate index buffer info + uint16_t *pcurIndex = *ppTriangleListIndices; for ( int triNum = 0; triNum < HMA_GridSize * HMA_GridSize; triNum++ ) { @@ -1180,23 +1211,23 @@ void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTrian // so linear interpolation works better & we can use fewer tris. if ( ( x < HMA_GridSize/2 ) != ( y < HMA_GridSize/2 ) ) // != is logical XOR { - *pcurIndex++ = (UInt16)FirstVertex; - *pcurIndex++ = (UInt16)FirstVertex+1; - *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1)+1; + *pcurIndex++ = (uint16_t)FirstVertex; + *pcurIndex++ = (uint16_t)FirstVertex+1; + *pcurIndex++ = (uint16_t)FirstVertex+(HMA_GridSize+1)+1; - *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1)+1; - *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1); - *pcurIndex++ = (UInt16)FirstVertex; + *pcurIndex++ = (uint16_t)FirstVertex+(HMA_GridSize+1)+1; + *pcurIndex++ = (uint16_t)FirstVertex+(HMA_GridSize+1); + *pcurIndex++ = (uint16_t)FirstVertex; } else { - *pcurIndex++ = (UInt16)FirstVertex; - *pcurIndex++ = (UInt16)FirstVertex+1; - *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1); + *pcurIndex++ = (uint16_t)FirstVertex; + *pcurIndex++ = (uint16_t)FirstVertex+1; + *pcurIndex++ = (uint16_t)FirstVertex+(HMA_GridSize+1); - *pcurIndex++ = (UInt16)FirstVertex+1; - *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1)+1; - *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1); + *pcurIndex++ = (uint16_t)FirstVertex+1; + *pcurIndex++ = (uint16_t)FirstVertex+(HMA_GridSize+1)+1; + *pcurIndex++ = (uint16_t)FirstVertex+(HMA_GridSize+1); } } } @@ -1272,10 +1303,10 @@ PredictionValues PredictionGetDeviceValues ( const HmdRenderInfo &hmdRenderInfo, return result; } -Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&eyeViewAdjust ) +Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&hmdToEyeViewOffset ) { - Matrix4f worldFromPredictedView = (eyeViewAdjust * predictedViewFromWorld).InvertedHomogeneousTransform(); - Matrix4f matRenderFromNowStart = (eyeViewAdjust * renderedViewFromWorld) * worldFromPredictedView; + Matrix4f worldFromPredictedView = (hmdToEyeViewOffset * predictedViewFromWorld).InvertedHomogeneousTransform(); + Matrix4f matRenderFromNowStart = (hmdToEyeViewOffset * renderedViewFromWorld) * worldFromPredictedView; // The sensor-predicted 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. @@ -1306,22 +1337,35 @@ Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matri return matRenderFromNowStart; } -Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&eyeViewAdjust ) +Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&hmdToEyeViewOffset ) { - Matrix4f worldFromPredictedView = (eyeViewAdjust * predictedViewFromWorld).InvertedHomogeneousTransform(); - Matrix4f matRenderXform = (eyeViewAdjust * renderedViewFromWorld) * worldFromPredictedView; + Matrix4f worldFromPredictedView = (hmdToEyeViewOffset * predictedViewFromWorld).InvertedHomogeneousTransform(); + Matrix4f matRenderXform = (hmdToEyeViewOffset * renderedViewFromWorld) * worldFromPredictedView; return matRenderXform.Inverted(); } TimewarpMachine::TimewarpMachine() -{ + : VsyncEnabled(false), + RenderInfo(), + CurrentPredictionValues(), + DistortionTimeCount(0), + DistortionTimeCurrentStart(0.0), + //DistortionTimes[], + DistortionTimeAverage(0.f), + //EyeRenderPoses[], + LastFramePresentFlushTime(0.0), + PresentFlushToPresentFlushSeconds(0.f), + NextFramePresentFlushTime(0.0) +{ + #if defined(OVR_BUILD_DEBUG) + memset(DistortionTimes, 0, sizeof(DistortionTimes)); + #endif + for ( int i = 0; i < 2; i++ ) { - EyeRenderPoses[i] = Transformf(); + EyeRenderPoses[i] = Posef(); } - DistortionTimeCount = 0; - VsyncEnabled = false; } void TimewarpMachine::Reset(HmdRenderInfo& renderInfo, bool vsyncEnabled, double timeNow) @@ -1338,21 +1382,36 @@ void TimewarpMachine::Reset(HmdRenderInfo& renderInfo, bool vsyncEnabled, double void TimewarpMachine::AfterPresentAndFlush(double timeNow) { + AfterPresentWithoutFlush(); + AfterPresentFinishes ( timeNow ); +} + +void TimewarpMachine::AfterPresentWithoutFlush() +{ + // We've only issued the Present - it hasn't actually finished (i.e. appeared) + // But we need to estimate when the next Present will appear, so extrapolate from previous data. + NextFramePresentFlushTime = LastFramePresentFlushTime + 2.0 * (double)PresentFlushToPresentFlushSeconds; +} + +void TimewarpMachine::AfterPresentFinishes(double timeNow) +{ + // The present has now actually happened. PresentFlushToPresentFlushSeconds = (float)(timeNow - LastFramePresentFlushTime); LastFramePresentFlushTime = timeNow; NextFramePresentFlushTime = timeNow + (double)PresentFlushToPresentFlushSeconds; } + + double TimewarpMachine::GetViewRenderPredictionTime() { // Note that PredictionGetDeviceValues() did all the vsync-dependent thinking for us. return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToRenderedScene; } -Transformf TimewarpMachine::GetViewRenderPredictionPose(SensorFusion &sfusion) +bool TimewarpMachine::GetViewRenderPredictionPose(SensorStateReader* reader, Posef& pose) { - double predictionTime = GetViewRenderPredictionTime(); - return sfusion.GetPoseAtTime(predictionTime); + return reader->GetPoseAtTime(GetViewRenderPredictionTime(), pose); } double TimewarpMachine::GetVisiblePixelTimeStart() @@ -1365,31 +1424,43 @@ double TimewarpMachine::GetVisiblePixelTimeEnd() // Note that PredictionGetDeviceValues() did all the vsync-dependent thinking for us. return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToTimewarpEnd; } -Transformf TimewarpMachine::GetPredictedVisiblePixelPoseStart(SensorFusion &sfusion) +bool TimewarpMachine::GetPredictedVisiblePixelPoseStart(SensorStateReader* reader, Posef& pose) { - double predictionTime = GetVisiblePixelTimeStart(); - return sfusion.GetPoseAtTime(predictionTime); + return reader->GetPoseAtTime(GetVisiblePixelTimeStart(), pose); } -Transformf TimewarpMachine::GetPredictedVisiblePixelPoseEnd (SensorFusion &sfusion) +bool TimewarpMachine::GetPredictedVisiblePixelPoseEnd(SensorStateReader* reader, Posef& pose) { - double predictionTime = GetVisiblePixelTimeEnd(); - return sfusion.GetPoseAtTime(predictionTime); + return reader->GetPoseAtTime(GetVisiblePixelTimeEnd(), pose); } -Matrix4f TimewarpMachine::GetTimewarpDeltaStart(SensorFusion &sfusion, Transformf const &renderedPose) +bool TimewarpMachine::GetTimewarpDeltaStart(SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform) { - Transformf visiblePose = GetPredictedVisiblePixelPoseStart ( sfusion ); + Posef visiblePose; + if (!GetPredictedVisiblePixelPoseStart(reader, visiblePose)) + { + return false; + } + Matrix4f visibleMatrix(visiblePose); Matrix4f renderedMatrix(renderedPose); Matrix4f identity; // doesn't matter for orientation-only timewarp - return TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix, identity ); + transform = TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix, identity ); + + return true; } -Matrix4f TimewarpMachine::GetTimewarpDeltaEnd (SensorFusion &sfusion, Transformf const &renderedPose) +bool TimewarpMachine::GetTimewarpDeltaEnd(SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform) { - Transformf visiblePose = GetPredictedVisiblePixelPoseEnd ( sfusion ); + Posef visiblePose; + if (!GetPredictedVisiblePixelPoseEnd(reader, visiblePose)) + { + return false; + } + Matrix4f visibleMatrix(visiblePose); Matrix4f renderedMatrix(renderedPose); Matrix4f identity; // doesn't matter for orientation-only timewarp - return TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix, identity ); + transform = TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix, identity ); + + return true; } @@ -1402,19 +1473,30 @@ double TimewarpMachine::JustInTime_GetDistortionWaitUntilTime() return LastFramePresentFlushTime; } - const float fudgeFactor = 0.002f; // Found heuristically - 1ms is too short because of timing granularity - may need further tweaking! - float howLongBeforePresent = DistortionTimeAverage + fudgeFactor; + // Note - 1-2ms fudge factor (because Windows timer granularity etc) is NOT added here, + // because otherwise you end up adding multiple fudge factors! + // So it's left for the calling app to add just one fudge factor. + + float howLongBeforePresent = DistortionTimeAverage; // Subtlety here. Technically, the correct time is NextFramePresentFlushTime - howLongBeforePresent. // However, if the app drops a frame, this then perpetuates it, // i.e. if the display is running at 60fps, but the last frame was slow, // (e.g. because of swapping or whatever), then NextFramePresentFlushTime is - // 33ms in the future, not 16ms. Since this function supplies the + // 33ms in the future, not 16ms. Since this function supplies the // time to wait until, the app will indeed wait until 32ms, so the framerate // drops to 30fps and never comes back up! // So we return the *ideal* framerate, not the *actual* framerate. return LastFramePresentFlushTime + (float)( CurrentPredictionValues.PresentFlushToPresentFlush - howLongBeforePresent ); } +double TimewarpMachine::JustInTime_AverageDistortionTime() +{ + if ( JustInTime_NeedDistortionTimeMeasurement() ) + { + return 0.0; + } + return DistortionTimeAverage; +} bool TimewarpMachine::JustInTime_NeedDistortionTimeMeasurement() const { diff --git a/LibOVR/Src/Util/Util_Render_Stereo.h b/LibOVR/Src/Util/Util_Render_Stereo.h index 326059e..2ac863c 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.h +++ b/LibOVR/Src/Util/Util_Render_Stereo.h @@ -1,21 +1,20 @@ /************************************************************************************ -PublicHeader: OVR.h Filename : Util_Render_Stereo.h Content : Sample stereo rendering configuration classes. Created : October 22, 2012 Authors : Michael Antonov, Tom Forsyth -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +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.1 +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, @@ -29,13 +28,9 @@ limitations under the License. #define OVR_Util_Render_Stereo_h #include "../OVR_Stereo.h" +#include "../Tracking/Tracking_SensorStateReader.h" - -namespace OVR { - -class SensorFusion; - -namespace Util { namespace Render { +namespace OVR { namespace Util { namespace Render { @@ -333,20 +328,25 @@ struct DistortionMeshVertexData Vector2f TanEyeAnglesB; }; +// If you just want a single point on the screen transformed. +DistortionMeshVertexData DistortionMeshMakeVertex ( Vector2f screenNDC, + bool rightEye, + const HmdRenderInfo &hmdRenderInfo, + const DistortionRenderDesc &distortion, const ScaleAndOffset2D &eyeToSourceNDC ); -void DistortionMeshCreate ( DistortionMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, +void DistortionMeshCreate ( DistortionMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, int *pNumVertices, int *pNumTriangles, const StereoEyeParams &stereoParams, const HmdRenderInfo &hmdRenderInfo ); -// Generate distortion mesh for a eye. This version requires less data then stereoParms, supporting -// dynamic change in render target viewport. -void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, +// Generate distortion mesh for a eye. +// This version requires less data then stereoParms, supporting dynamic change in render target viewport. +void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, int *pNumVertices, int *pNumTriangles, bool rightEye, const HmdRenderInfo &hmdRenderInfo, const DistortionRenderDesc &distortion, const ScaleAndOffset2D &eyeToSourceNDC ); -void DistortionMeshDestroy ( DistortionMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices ); +void DistortionMeshDestroy ( DistortionMeshVertexData *pVertices, uint16_t *pTriangleMeshIndices ); //----------------------------------------------------------------------------------- @@ -368,17 +368,17 @@ struct HeightmapMeshVertexData }; -void HeightmapMeshCreate ( HeightmapMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, +void HeightmapMeshCreate ( HeightmapMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, int *pNumVertices, int *pNumTriangles, const StereoEyeParams &stereoParams, const HmdRenderInfo &hmdRenderInfo ); // Generate heightmap mesh for a eye. This version requires less data then stereoParms, supporting // dynamic change in render target viewport. -void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, +void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, int *pNumVertices, int *pNumTriangles, bool rightEye, const HmdRenderInfo &hmdRenderInfo, const ScaleAndOffset2D &eyeToSourceNDC ); -void HeightmapMeshDestroy ( HeightmapMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices ); +void HeightmapMeshDestroy ( HeightmapMeshVertexData *pVertices, uint16_t *pTriangleMeshIndices ); @@ -411,8 +411,8 @@ PredictionValues PredictionGetDeviceValues ( const HmdRenderInfo &hmdRenderInfo, // (which may have been computed later on, and thus is more accurate), and this // will return the matrix to pass to the timewarp distortion shader. // TODO: deal with different handedness? -Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&eyeViewAdjust ); -Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&eyeViewAdjust ); +Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&hmdToEyeViewOffset ); +Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&hmdToEyeViewOffset ); @@ -429,12 +429,16 @@ public: // The only reliable time in most engines is directly after the frame-present and GPU flush-and-wait. // This call should be done right after that to give this system the timing info it needs. void AfterPresentAndFlush(double timeNow); + // But some engines queue up the frame-present and only later find out when it actually happened. + // They should call these two at those times. + void AfterPresentWithoutFlush(); + void AfterPresentFinishes(double timeNow); // The "average" time the rendered frame will show up, // and the predicted pose of the HMD at that time. // You usually only need to call one of these functions. double GetViewRenderPredictionTime(); - Transformf GetViewRenderPredictionPose(SensorFusion &sfusion); + bool GetViewRenderPredictionPose(Tracking::SensorStateReader* reader, Posef& transform); // Timewarp prediction functions. You usually only need to call one of these three sets of functions. @@ -443,14 +447,13 @@ public: double GetVisiblePixelTimeStart(); double GetVisiblePixelTimeEnd(); // Predicted poses of the HMD at those first and last pixels. - Transformf GetPredictedVisiblePixelPoseStart(SensorFusion &sfusion); - Transformf GetPredictedVisiblePixelPoseEnd (SensorFusion &sfusion); + bool GetPredictedVisiblePixelPoseStart(Tracking::SensorStateReader* reader, Posef& transform); + bool GetPredictedVisiblePixelPoseEnd(Tracking::SensorStateReader* 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) - Matrix4f GetTimewarpDeltaStart(SensorFusion &sfusion, Transformf const &renderedPose); - Matrix4f GetTimewarpDeltaEnd (SensorFusion &sfusion, Transformf const &renderedPose); - + bool GetTimewarpDeltaStart(Tracking::SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform); + bool GetTimewarpDeltaEnd(Tracking::SensorStateReader* 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, @@ -465,26 +468,25 @@ public: bool JustInTime_NeedDistortionTimeMeasurement() const; void JustInTime_BeforeDistortionTimeMeasurement(double timeNow); void JustInTime_AfterDistortionTimeMeasurement(double timeNow); - + double JustInTime_AverageDistortionTime(); // Just for profiling - use JustInTime_GetDistortionWaitUntilTime() for functionality. private: - bool VsyncEnabled; HmdRenderInfo RenderInfo; PredictionValues CurrentPredictionValues; - enum { NumDistortionTimes = 10 }; + enum { NumDistortionTimes = 100 }; int DistortionTimeCount; double DistortionTimeCurrentStart; float DistortionTimes[NumDistortionTimes]; float DistortionTimeAverage; // Pose at which last time the eye was rendered. - Transformf EyeRenderPoses[2]; + Posef EyeRenderPoses[2]; // Absolute time of the last present+flush double LastFramePresentFlushTime; - // Seconds between presentflushes + // Seconds between present+flushes float PresentFlushToPresentFlushSeconds; // Predicted absolute time of the next present+flush double NextFramePresentFlushTime; diff --git a/LibOVR/Src/Util/Util_SystemGUI.cpp b/LibOVR/Src/Util/Util_SystemGUI.cpp new file mode 100644 index 0000000..76eb890 --- /dev/null +++ b/LibOVR/Src/Util/Util_SystemGUI.cpp @@ -0,0 +1,190 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..c6b8d6f --- /dev/null +++ b/LibOVR/Src/Util/Util_SystemGUI.h @@ -0,0 +1,39 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..cbfd057 --- /dev/null +++ b/LibOVR/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/LibOVR/Src/Util/Util_SystemInfo.cpp b/LibOVR/Src/Util/Util_SystemInfo.cpp new file mode 100644 index 0000000..0fca243 --- /dev/null +++ b/LibOVR/Src/Util/Util_SystemInfo.cpp @@ -0,0 +1,289 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..b150560 --- /dev/null +++ b/LibOVR/Src/Util/Util_SystemInfo.h @@ -0,0 +1,51 @@ +/************************************************************************************ + +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 new file mode 100644 index 0000000..46799fb --- /dev/null +++ b/LibOVR/Src/Util/Util_SystemInfo_OSX.mm @@ -0,0 +1,106 @@ + /************************************************************************************ + + 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 { + -- cgit v1.2.3