diff options
135 files changed, 26057 insertions, 0 deletions
diff --git a/+android.ha b/+android.ha new file mode 100644 index 0000000..f8dc55b --- /dev/null +++ b/+android.ha @@ -0,0 +1,13 @@ +use types::c; + +@symbol("__android_log_write") fn _androlog(prio: int, tag: *const c::char, text: *const c::char) void; + +fn androlog(prio: int, text: str) void = { +	const text = c::fromstr(text); +	defer free(text); +	_androlog(prio, *(&"hacraft\0": **const c::char), text); +}; + +export @symbol("android_main") fn android_main() void = { +	main(); +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ddeefe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/hacraft +/resources @@ -0,0 +1,674 @@ +                    GNU GENERAL PUBLIC LICENSE +                       Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +                            Preamble + +  The GNU General Public License is a free, copyleft license for +software and other kinds of works. + +  The licenses for most software and other practical works are designed +to take away your freedom to share and change the works.  By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users.  We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors.  You can apply it to +your programs, too. + +  When we speak of free software, we are referring to freedom, not +price.  Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + +  To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights.  Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + +  For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received.  You must make sure that they, too, receive +or can get the source code.  And you must show them these terms so they +know their rights. + +  Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + +  For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software.  For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + +  Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so.  This is fundamentally incompatible with the aim of +protecting users' freedom to change the software.  The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable.  Therefore, we +have designed this version of the GPL to prohibit the practice for those +products.  If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + +  Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary.  To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + +  The precise terms and conditions for copying, distribution and +modification follow. + +                       TERMS AND CONDITIONS + +  0. Definitions. + +  "This License" refers to version 3 of the GNU General Public License. + +  "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + +  "The Program" refers to any copyrightable work licensed under this +License.  Each licensee is addressed as "you".  "Licensees" and +"recipients" may be individuals or organizations. + +  To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy.  The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + +  A "covered work" means either the unmodified Program or a work based +on the Program. + +  To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy.  Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + +  To "convey" a work means any kind of propagation that enables other +parties to make or receive copies.  Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + +  An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License.  If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +  1. Source Code. + +  The "source code" for a work means the preferred form of the work +for making modifications to it.  "Object code" means any non-source +form of a work. + +  A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + +  The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form.  A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + +  The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities.  However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work.  For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + +  The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + +  The Corresponding Source for a work in source code form is that +same work. + +  2. Basic Permissions. + +  All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met.  This License explicitly affirms your unlimited +permission to run the unmodified Program.  The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work.  This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + +  You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force.  You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright.  Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + +  Conveying under any other circumstances is permitted solely under +the conditions stated below.  Sublicensing is not allowed; section 10 +makes it unnecessary. + +  3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +  No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + +  When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + +  4. Conveying Verbatim Copies. + +  You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + +  You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + +  5. Conveying Modified Source Versions. + +  You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + +    a) The work must carry prominent notices stating that you modified +    it, and giving a relevant date. + +    b) The work must carry prominent notices stating that it is +    released under this License and any conditions added under section +    7.  This requirement modifies the requirement in section 4 to +    "keep intact all notices". + +    c) You must license the entire work, as a whole, under this +    License to anyone who comes into possession of a copy.  This +    License will therefore apply, along with any applicable section 7 +    additional terms, to the whole of the work, and all its parts, +    regardless of how they are packaged.  This License gives no +    permission to license the work in any other way, but it does not +    invalidate such permission if you have separately received it. + +    d) If the work has interactive user interfaces, each must display +    Appropriate Legal Notices; however, if the Program has interactive +    interfaces that do not display Appropriate Legal Notices, your +    work need not make them do so. + +  A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit.  Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + +  6. Conveying Non-Source Forms. + +  You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + +    a) Convey the object code in, or embodied in, a physical product +    (including a physical distribution medium), accompanied by the +    Corresponding Source fixed on a durable physical medium +    customarily used for software interchange. + +    b) Convey the object code in, or embodied in, a physical product +    (including a physical distribution medium), accompanied by a +    written offer, valid for at least three years and valid for as +    long as you offer spare parts or customer support for that product +    model, to give anyone who possesses the object code either (1) a +    copy of the Corresponding Source for all the software in the +    product that is covered by this License, on a durable physical +    medium customarily used for software interchange, for a price no +    more than your reasonable cost of physically performing this +    conveying of source, or (2) access to copy the +    Corresponding Source from a network server at no charge. + +    c) Convey individual copies of the object code with a copy of the +    written offer to provide the Corresponding Source.  This +    alternative is allowed only occasionally and noncommercially, and +    only if you received the object code with such an offer, in accord +    with subsection 6b. + +    d) Convey the object code by offering access from a designated +    place (gratis or for a charge), and offer equivalent access to the +    Corresponding Source in the same way through the same place at no +    further charge.  You need not require recipients to copy the +    Corresponding Source along with the object code.  If the place to +    copy the object code is a network server, the Corresponding Source +    may be on a different server (operated by you or a third party) +    that supports equivalent copying facilities, provided you maintain +    clear directions next to the object code saying where to find the +    Corresponding Source.  Regardless of what server hosts the +    Corresponding Source, you remain obligated to ensure that it is +    available for as long as needed to satisfy these requirements. + +    e) Convey the object code using peer-to-peer transmission, provided +    you inform other peers where the object code and Corresponding +    Source of the work are being offered to the general public at no +    charge under subsection 6d. + +  A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + +  A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling.  In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage.  For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product.  A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + +  "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source.  The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + +  If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information.  But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + +  The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed.  Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + +  Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + +  7. Additional Terms. + +  "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law.  If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + +  When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it.  (Additional permissions may be written to require their own +removal in certain cases when you modify the work.)  You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + +  Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + +    a) Disclaiming warranty or limiting liability differently from the +    terms of sections 15 and 16 of this License; or + +    b) Requiring preservation of specified reasonable legal notices or +    author attributions in that material or in the Appropriate Legal +    Notices displayed by works containing it; or + +    c) Prohibiting misrepresentation of the origin of that material, or +    requiring that modified versions of such material be marked in +    reasonable ways as different from the original version; or + +    d) Limiting the use for publicity purposes of names of licensors or +    authors of the material; or + +    e) Declining to grant rights under trademark law for use of some +    trade names, trademarks, or service marks; or + +    f) Requiring indemnification of licensors and authors of that +    material by anyone who conveys the material (or modified versions of +    it) with contractual assumptions of liability to the recipient, for +    any liability that these contractual assumptions directly impose on +    those licensors and authors. + +  All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10.  If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term.  If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + +  If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + +  Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + +  8. Termination. + +  You may not propagate or modify a covered work except as expressly +provided under this License.  Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + +  However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + +  Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +  Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License.  If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + +  9. Acceptance Not Required for Having Copies. + +  You are not required to accept this License in order to receive or +run a copy of the Program.  Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance.  However, +nothing other than this License grants you permission to propagate or +modify any covered work.  These actions infringe copyright if you do +not accept this License.  Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + +  10. Automatic Licensing of Downstream Recipients. + +  Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License.  You are not responsible +for enforcing compliance by third parties with this License. + +  An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations.  If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + +  You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License.  For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + +  11. Patents. + +  A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based.  The +work thus licensed is called the contributor's "contributor version". + +  A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version.  For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + +  Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + +  In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement).  To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + +  If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients.  "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + +  If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + +  A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License.  You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + +  Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + +  12. No Surrender of Others' Freedom. + +  If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License.  If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all.  For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + +  13. Use with the GNU Affero General Public License. + +  Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work.  The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + +  14. Revised Versions of this License. + +  The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time.  Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +  Each version is given a distinguishing version number.  If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation.  If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + +  If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + +  Later license versions may give you additional or different +permissions.  However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + +  15. Disclaimer of Warranty. + +  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +  16. Limitation of Liability. + +  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + +  17. Interpretation of Sections 15 and 16. + +  If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + +                     END OF TERMS AND CONDITIONS + +            How to Apply These Terms to Your New Programs + +  If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +  To do so, attach the following notices to the program.  It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + +    <one line to give the program's name and a brief idea of what it does.> +    Copyright (C) <year>  <name of author> + +    This program is free software: you can redistribute it and/or modify +    it under the terms of the GNU General Public License as published by +    the Free Software Foundation, either version 3 of the License, or +    (at your option) any later version. + +    This program is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +    GNU General Public License for more details. + +    You should have received a copy of the GNU General Public License +    along with this program.  If not, see <https://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + +  If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + +    <program>  Copyright (C) <year>  <name of author> +    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. +    This is free software, and you are welcome to redistribute it +    under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License.  Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + +  You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<https://www.gnu.org/licenses/>. + +  The GNU General Public License does not permit incorporating your program +into proprietary programs.  If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library.  If this is what you want to do, use the GNU Lesser General +Public License instead of this License.  But first, please read +<https://www.gnu.org/licenses/why-not-lgpl.html>. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..41a7258 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +.POSIX: +.SUFFIXES: + +BIN = hacraft +LIBS = -lc -lSDL2 + +all: $(BIN) + +clean: +	rm $(BIN) + +$(BIN): +	hare build -o $@ $(LIBS) + +.PHONY: all clean $(BIN) @@ -0,0 +1,83 @@ +Minecraft 1.19.3 (exactly) is required. + +The default resource pack must be present at resources/assets. +Use unzip client.jar -d resources/ 'assets/*' to extract from a client jar. + +Set online-mode=false and network-compression-threshold=-1 +in server.properties. + +Hint: handy client and server download links are provided at +<https://minecraft.wiki/w/Java_Edition_1.19.3>. + +Vsync is hardcoded to be disabled. You can change this in window.ha. I used +GALLIUM_HUD to view frame times, so there is no built-in FPS display. + +The chunk tessellation runs on the main thread, and the work distribution is +rather dumb, so a frame rate drop will be visible whenever new chunks are being +loaded. + +Patched versions of the following libraries are included in the source tree: + - hare-json <https://sr.ht/~sircmpwn/hare-json/> + - hare-png <https://git.sr.ht/~sircmpwn/hare-png> + - hare-sdl2 <https://sr.ht/~sircmpwn/hare-sdl2/> + - hare-glm <https://sr.ht/~vladh/hare-glm/> + +A few words on what to expect: + +Most of this code is pretty bad, really. Most of the "architecture"-level stuff +is questionable (I knew this back then, but not really how to fix it). A lot +was written to be cleaned up in the future; such code may or may not have a +TODO attached. + +Weirdly enough, the less deep you are in the call stack, the messier things +seem to get. The destructors for various global state in particular are +half-implemented, and probably broken in numerous ways. Nowadays I'd try to +resist the urge to split application glue logic over so many pseudo-modules. +Ideally it would all be in one file. + +Overall, if you came here expecting examples of good ways to do things in Hare, +you're probably in the wrong place. The utility modules dejson, htab and trace +are kinda okay, though. + +The part that is probably the most complete is model rendering. Pretty much +everything there is supported (unless I forgot something), with the exception +of tintindex (which is why grass etc. is gray), and block transparency +information (which is why there are holes everywhere). Both of these require +hardcoded information about blocks, though I had plans to possibly implement +the latter by inspecting the model and textures instead. + +There's some sketchiness to the asset loading too, though. I went back and +forth on whether to load textures up front, or on demand while loading models. +There are similarish problems with model loading, where you get spurious error +messages about unresolved texture names in template model files that aren't +ever actually used directly. + +I don't like how registries are handled. The split into objreg and idreg was +probably a mistake; I used to have everything handled with IDs. + +Notable world interactions that work are health/death and portals. + +The Android support did work, at least at one point. (Though it's very +half-baked.) I didn't bother making sure that it does anymore, though. + +Also, yes, the naming style used here differs from the usual Hare convention. +This is because I got fed up with name conflicts between types and local +variables. For globals I used SCREAMING_SNAKE_CASE, which, yes, is very +exhausting given the amount of them that there are. Probably not a choice I'll +make again. + +Copyright notice (if anyone really cares): + +	Copyright (C) Lassi Pulkkinen + +	This program is free software: you can redistribute it and/or modify +	it under the terms of the GNU General Public License version 3 as +	published by the Free Software Foundation. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU General Public License for more details. + +	You should have received a copy of the GNU General Public License +	along with this program.  If not, see <https://www.gnu.org/licenses/>. diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..2eb9c79 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,43 @@ +plugins { +	id 'com.android.application' version '8.1.0' +} + +android { +	namespace 'fi.pulk.hacraft' +	compileSdk 33 + +	defaultConfig { +		applicationId 'fi.pulk.hacraft' +		versionCode 1 +		versionName '1.0' +		minSdk 19 +		targetSdk 28 + +		externalNativeBuild { +			cmake { +				arguments '-DSDL_ROOT=' + project.property('sdlRoot') +				abiFilters 'arm64-v8a', 'x86_64' +			} +		} +	} + +	externalNativeBuild { +		cmake { +			path 'jni/CMakeLists.txt' +		} +	} + +	sourceSets { +		main { +			java.srcDir project.property('sdlRoot') \ +				+ '/android-project/app/src/main/java' +		} +	} + +	lintOptions { +		// SDL's java shim has unaddressed linter warnings, and this is +		// how they deal with them, apparently. *shrug* +		// (Based on android-project/app/build.gradle, anyway.) +		abortOnError false +	} +} diff --git a/android/jni/CMakeLists.txt b/android/jni/CMakeLists.txt new file mode 100644 index 0000000..e291b2d --- /dev/null +++ b/android/jni/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.6) + +project(HACRAFT) + +add_subdirectory(${SDL_ROOT} SDL) + +if(${ANDROID_ABI} STREQUAL arm64-v8a) +	set(HARE_TARGET aarch64) +elseif(${ANDROID_ABI} STREQUAL x86_64) +	set(HARE_TARGET x86_64) +endif() + +set(LIBMAIN_SO ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libmain.so) + +add_custom_target(compile_main +	CC=${CMAKE_C_COMPILER} AS=${CMAKE_CURRENT_SOURCE_DIR}/as +		LDFLAGS=--target=${CMAKE_C_COMPILER_TARGET}\ -shared\ ${CMAKE_CURRENT_SOURCE_DIR}/main.c +		ASFLAGS=${CMAKE_C_COMPILER}\ ${CMAKE_C_COMPILER_TARGET} +		HARECACHE=${CMAKE_CURRENT_BINARY_DIR}/hare +		hare build -a ${HARE_TARGET} -T +android +		-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY} +		-o ${LIBMAIN_SO} +		-lc -lSDL2 -v +	DEPENDS SDL2 +	BYPRODUCTS ${LIBMAIN_SO} +	WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../.. +	USES_TERMINAL) + +add_library(main SHARED IMPORTED GLOBAL) +set_target_properties(main PROPERTIES IMPORTED_LOCATION ${LIBMAIN_SO}) +add_dependencies(main compile_main) + +add_library(dummy SHARED) +target_sources(dummy PRIVATE dummy.c) +target_link_libraries(dummy main) diff --git a/android/jni/as b/android/jni/as new file mode 100755 index 0000000..00963ee --- /dev/null +++ b/android/jni/as @@ -0,0 +1,11 @@ +#!/bin/sh + +cc="$1" +target="$2" +out="$4" +shift 4 +( +	for f in "$@"; do +		cat "$f" +	done +) | "$cc" --target="$target" -c -o "$out" -x assembler - diff --git a/android/jni/dummy.c b/android/jni/dummy.c new file mode 100644 index 0000000..698ef4b --- /dev/null +++ b/android/jni/dummy.c @@ -0,0 +1 @@ +/* nothing to C here */ diff --git a/android/jni/main.c b/android/jni/main.c new file mode 100644 index 0000000..606ef7f --- /dev/null +++ b/android/jni/main.c @@ -0,0 +1,7 @@ +void android_main(); + +int +SDL_main(int argc, char **argv) { +	android_main(); +	return 0; +} diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..e8d169c --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,13 @@ +pluginManagement { +	repositories { +		mavenCentral() +		google() +	} +} + +dependencyResolutionManagement { +	repositories { +		mavenCentral() +		google() +	} +} diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..5df0531 --- /dev/null +++ b/android/src/main/AndroidManifest.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" +	android:versionCode="1" +	android:versionName="1.0" +	android:installLocation="auto"> + +	<!-- OpenGL ES 3.2 --> +	<uses-feature android:glEsVersion="0x00030002"/> +	<!-- Touchscreen support --> +	<uses-feature +		android:name="android.hardware.touchscreen" +		android:required="false"/> +	<!-- Game controller support --> +	<uses-feature +		android:name="android.hardware.bluetooth" +		android:required="false"/> +	<uses-feature +		android:name="android.hardware.gamepad" +		android:required="false"/> +	<uses-feature +		android:name="android.hardware.usb.host" +		android:required="false"/> +	<!-- External mouse input events --> +	<uses-feature +		android:name="android.hardware.type.pc" +		android:required="false"/> + +	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> +	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="22"/> +	<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30"/> +	<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/> +	<uses-permission android:name="android.permission.VIBRATE"/> +	<uses-permission android:name="android.permission.INTERNET"/> +	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> + +	<application android:label="@string/app_name" +		android:allowBackup="true" +		android:theme="@android:style/Theme.NoTitleBar.Fullscreen" +		android:hardwareAccelerated="true"> +		<!-- android:icon="@mipmap/ic_launcher" +                        (2024 note): I removed the icon files since they were +                        just the default ones that come with SDL. --> + +		<activity android:name="MainActivity" +			android:label="@string/app_name" +			android:alwaysRetainTaskState="true" +			android:launchMode="singleInstance" +			android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation" +			android:preferMinimalPostProcessing="true" +			android:exported="true"> + +			<intent-filter> +				<action android:name="android.intent.action.MAIN"/> +				<category android:name="android.intent.category.LAUNCHER"/> +			</intent-filter> +			<intent-filter> +				<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> +			</intent-filter> + +		</activity> + +	</application> + +</manifest> diff --git a/android/src/main/java/fi/pulk/hacraft/MainActivity.java b/android/src/main/java/fi/pulk/hacraft/MainActivity.java new file mode 100644 index 0000000..f349c9c --- /dev/null +++ b/android/src/main/java/fi/pulk/hacraft/MainActivity.java @@ -0,0 +1,5 @@ +package fi.pulk.hacraft; + +import org.libsdl.app.SDLActivity; + +public class MainActivity extends SDLActivity {} diff --git a/android/src/main/res/values/colors.xml b/android/src/main/res/values/colors.xml new file mode 100644 index 0000000..3ab3e9c --- /dev/null +++ b/android/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> +    <color name="colorPrimary">#3F51B5</color> +    <color name="colorPrimaryDark">#303F9F</color> +    <color name="colorAccent">#FF4081</color> +</resources> diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml new file mode 100644 index 0000000..ab79533 --- /dev/null +++ b/android/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> +    <string name="app_name">Game</string> +</resources> diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml new file mode 100644 index 0000000..ff6c9d2 --- /dev/null +++ b/android/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ +<resources> + +    <!-- Base application theme. --> +    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> +        <!-- Customize your theme here. --> +    </style> + +</resources> diff --git a/atlas.ha b/atlas.ha new file mode 100644 index 0000000..79aadbf --- /dev/null +++ b/atlas.ha @@ -0,0 +1,337 @@ +use dejson; +use encoding::json; +use fmt; +use gl::*; +use io; +use math; +use strings; +use trace; + +let ATLAS_BLOCKS = ATLAS_EMPTY; + +fn load_atlases(assets: *Pack) void = { +	ATLAS_BLOCKS = load_atlas("minecraft:blocks", assets); +}; + +type Atlas = struct { +	sprites: ObjectRegistry, +	width: u32, +	gl_texture: uint, +}; + +type Sprite = struct { +	Object, +	texture: *Texture, +	width: u32, +	height: u32, +	x: u32, +	y: u32, +}; + +def ATLAS_EMPTY = Atlas { +	sprites = OBJREG_EMPTY, +	... +}; + +fn atlas_findsprite(atlas: *Atlas, ident: str) nullable *Sprite = +	objreg_find(&atlas.sprites, ident): nullable *Sprite; + +fn load_atlas(ident: str, assets: *Pack) Atlas = { +	trace::info(&trace::root, "loading atlas {}...", ident); +	const tr = trace::ctx(&trace::root, "load atlas {}", ident); + +	const json = match (resource_load_json( +		assets, "atlases", ident, ".json", &tr)) { +	case let json: json::value => +		yield json; +	case trace::failed => +		abort("TODO fallback"); +	}; +	defer json::finish(json); + +	const deser = dejson::newdeser(&json); +	const decl = match (deser_atlas_decl(&deser)) { +	case let x: AtlasDecl => +		yield x; +	case let err: dejson::error => +		trace::error(&tr, "deser: {}", err): void; +		abort("TODO fallback"); +	}; +	defer atlas_decl_finish(decl); + +	let sprites = newobjreg(); +	load_atlas_register_sprite(MISSINGNO, +		textures_find(MISSINGNO) as *Texture, &sprites, &tr); +	for (let i = len(decl.sources); i > 0) { +		i -= 1; +		load_atlas_search_source(&decl.sources[i], &sprites, &tr); +	}; + +	const max_cells = TEXTURES_MAX_WIDTH: u32 >> 4; +	const max_cells = max_cells * max_cells; + +	let ncells = 0u32; +	let sizes: [8][]*Sprite = [[]...]; +	defer for (let i = 0z; i < len(sizes); i += 1) { +		free(sizes[i]); +	}; +	let fits = true; +	let it = objreg_iter(&sprites); +	for (true) match (objreg_next(&it)) { +	case let spr: *Object => +		const spr = spr: *Sprite; +		const imgsize = if (spr.width > spr.height) +			spr.width else spr.height; +		const slotsize = math::bit_size_u32(imgsize: u32 - 1) - 4; +		const slotcells = 1 << (slotsize: u32 << 1); +		if (ncells + slotcells > max_cells) { +			fits = false; +			continue; +		}; +		ncells += slotcells; +		append(sizes[slotsize], spr); +	case null => break; +	}; +	if (!fits) { +		trace::error(&tr, +			"Can't fit all sprites in image (max width {})", +			TEXTURES_MAX_WIDTH): void; +	}; + +	// Reference: https://lisyarus.github.io/blog/graphics/2022/08/06/texture-packing.html +	// TODO: make extra sure this impl is correct this time... +	const gridsize: u16 = math::bit_size_u32(ncells - 1); +	const gridsize = (gridsize >> 1) + (gridsize & 1); // ceil(gridsize / 2) +	const gridsize = 1 << gridsize; +	const width = gridsize << 4; + +	let gl_texture: uint = 0; +	glGenTextures(1, &gl_texture); +	glBindTexture(GL_TEXTURE_2D, gl_texture); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, +		GL_NEAREST_MIPMAP_LINEAR: i32); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, +		GL_NEAREST: i32); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); +	glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8: i32, +		width: i32, width: i32, 0, GL_RGBA, GL_UNSIGNED_BYTE, null); + +	let pbo = 0u; +	glGenBuffers(1, &pbo); +	defer glDeleteBuffers(1, &pbo); +	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + +	let steps: [8][2]u32 = [[0, gridsize]...]; +	let steps = steps[..1]; +	let pos: [2]u32 = [0...]; +	for (let slotsize = len(sizes): u32; slotsize > 0) { +		slotsize -= 1; +		const slots = &sizes[slotsize]; +		const slotwidth = 1 << slotsize; +		if (pos[0] > steps[len(steps) - 1][0]) { +			static append(steps, [pos[0], pos[1] + 2 * slotwidth]); +		}; +		for (let i = 0z; i < len(slots); i += 1) { +			const spr = slots[i]; + +			spr.x = pos[0] << 4; +			spr.y = pos[1] << 4; + +			load_atlas_upload_sprite(spr, &tr); + +			pos[0] += slotwidth; +			if (pos[0] == gridsize) { +				pos[0] = steps[len(steps) - 1][0]; +				pos[1] += slotwidth; +				if (len(steps) != 1 && pos[1] + slotwidth +						== steps[len(steps) - 1][1]) { +					static delete(steps[len(steps) - 1]); +				}; +			}; +		}; +	}; + +	glGenerateMipmap(GL_TEXTURE_2D); + +	return Atlas { +		sprites = sprites, +		width = width, +		gl_texture = gl_texture, +	}; +}; +fn load_atlas_search_source( +	source: *AtlasDeclSource, +	sprites: *ObjectRegistry, +	tr: *trace::tracer, +) void = { +	match (*source) { +	case let source: AtlasDeclSourceDir => +		const srcpath = strings::trimsuffix(source.source, "/"); +		const srcpath = strings::concat(srcpath, "/"); +		defer free(srcpath); + +		let it = textures_iter(); +		for (true) match (textures_next(&it)) { +		case let tex: *Texture => +			const (ns, name) = ident_split(tex.name); +			if (strings::hasprefix(name, srcpath)) { +				const name = strings::trimprefix(name, srcpath); +				const ident = strings::concat( +					ns, ":", source.prefix, name); +				defer free(ident); +				load_atlas_register_sprite( +					ident, tex, sprites, tr); +			}; +		case null => break; +		}; +	case let source: AtlasDeclSourceSingle => +		match (textures_find(source.resource)) { +		case let tex: *Texture => +			load_atlas_register_sprite( +				source.sprite, tex, sprites, tr); +		case null => +			trace::error(tr, "Unknown texture {}", +				source.resource): void; +		}; +	}; +}; + +fn load_atlas_register_sprite( +	ident: str, +	tex: *Texture, +	sprites: *ObjectRegistry, +	tr: *trace::tracer, +) void = { +	const tr = trace::ctx(tr, "sprite {}", ident); + +	if (!(objreg_find(sprites, ident) is null)) { +		return; +	}; + +	const spr = alloc(Sprite { +		name = strings::dup(ident), +		texture = tex, +		width = tex.width, +		height = tex.height, +		... +	}); +	objreg_register(sprites, spr); + +	// TODO: once mipmapping works properly, there's probably no reason to +	// forbid non-16-pixel-aligned textures. +	if (spr.width == 0 || spr.height == 0 +			|| spr.width & 7 != 0 || spr.height & 7 != 0 +			|| spr.width > 2048 || spr.height > 2048) { +		trace::error(&tr, "Invalid dimensions: {}, {}", +			spr.width, spr.height): void; +		spr.texture = textures_find(MISSINGNO) as *Texture; +		spr.width = spr.texture.width; +		spr.height = spr.texture.height; +	}; +}; + +fn load_atlas_upload_sprite(spr: *Sprite, tr: *trace::tracer) void = { +	const tr = trace::ctx(tr, "sprite {}", spr.name); + +	const tex = spr.texture; +	const bufsize = tex.width * tex.height * 4; + +	for (true) { +		glBufferData(GL_PIXEL_UNPACK_BUFFER, +			bufsize: uintptr, null, GL_STREAM_DRAW); +		const pixels = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, +			0, bufsize: uintptr, GL_MAP_WRITE_BIT) as *opaque; +		texture_load(tex, pixels: *[*]u8, tex.width * 4, &tr); +		if (glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER) == GL_TRUE) { +			break; +		}; +		trace::warn(&tr, +			"glUnmapBuffer returned false; retrying upload"); +	}; + +	glTexSubImage2D(GL_TEXTURE_2D, 0, spr.x: i32, spr.y: i32, +		spr.width: i32, spr.height: i32, +		GL_RGBA, GL_UNSIGNED_BYTE, null); +}; + +type AtlasDecl = struct { +	sources: []AtlasDeclSource, +}; + +type AtlasDeclSource = (AtlasDeclSourceDir | AtlasDeclSourceSingle); +type AtlasDeclSourceDir = struct { +	source: str, +	prefix: str, +}; +type AtlasDeclSourceSingle = struct { +	resource: str, +	sprite: str, +}; + +fn atlas_decl_finish(decl: AtlasDecl) void = { +	for (let i = 0z; i < len(decl.sources); i += 1) { +		atlas_decl_source_finish(decl.sources[i]); +	}; +	free(decl.sources); +}; + +fn atlas_decl_source_finish(source: AtlasDeclSource) void = { +	match (source) { +	case let source: AtlasDeclSourceDir => +		free(source.source); +		free(source.prefix); +	case let source: AtlasDeclSourceSingle => +		free(source.resource); +		free(source.sprite); +	}; +}; + +fn deser_atlas_decl(de: *dejson::deser) (AtlasDecl | dejson::error) = { +	let success = false; + +	wassert_fields(de, "sources")?; + +	const de_sources = dejson::field(de, "sources")?; +	let nsources = dejson::length(&de_sources)?; +	let res = AtlasDecl { +		sources = alloc([], nsources), +	}; +	defer if (!success) atlas_decl_finish(res); +	for (let i = 0z; i < nsources; i += 1) { +		const de_source = dejson::index(&de_sources, i)?; + +		const srctype = dejson::field(&de_source, "type")?; +		const srctype = dejson::string(&srctype)?; +		switch (srctype) { +		case "directory" => +			const source = dejson::field(&de_source, "source")?; +			const source = dejson::string(&source)?; +			const prefix = dejson::field(&de_source, "prefix")?; +			const prefix = dejson::string(&prefix)?; +			append(res.sources, AtlasDeclSourceDir { +				source = strings::dup(source), +				prefix = strings::dup(prefix), +			}); +		case "single" => +			const resource = dejson::field(&de_source, "resource")?; +			const resource = dejson::string(&resource)?; +			const sprite = match ( +				dejson::optfield(&de_source, "sprite")?) { +			case let de_sprite: dejson::deser => +				yield dejson::string(&de_sprite)?; +			case void => +				yield resource; +			}; +			append(res.sources, AtlasDeclSourceSingle { +				resource = ident_qual(resource), +				sprite = ident_qual(sprite), +			}); +		case => +			return dejson::fail(&de_source, +				"Unknown source type {}", srctype); +		}; +	}; + +	success = true; +	return res; +}; diff --git a/blocks.ha b/blocks.ha new file mode 100644 index 0000000..d9a3048 --- /dev/null +++ b/blocks.ha @@ -0,0 +1,18 @@ +type BlockId = u32; + +let BLOCKS = IDREG_EMPTY; + +fn destroy_blocks() void = { +	idreg_clear(&BLOCKS); +}; + +fn blocks_register(ident: str) BlockId = { +	const blk = idreg_register(&BLOCKS, ident); +	bstates_handle_blocks_onregister(blk); +	return blk; +}; + +fn blocks_count() u32 = idreg_count(&BLOCKS); + +fn block_getident(blk: BlockId) str = +	idreg_getname(&BLOCKS, blk); diff --git a/bstates.ha b/bstates.ha new file mode 100644 index 0000000..bf329f2 --- /dev/null +++ b/bstates.ha @@ -0,0 +1,107 @@ +use types; +use strings; + +type BstateId = u32; +type BlockPropId = u32; + +type BlockBstates = struct { +	state0: BstateId, +	nstates: u32, +	props: [](str, []str), +	prop_moduli: []u32, +}; + +type BstateInfo = struct { +	block: BlockId, +}; + +let BLOCKS_BSTATES: []BlockBstates = []; +let BSTATES_INFO: []BstateInfo = []; + +fn bstates_handle_blocks_onregister(blk: BlockId) void = { +	append(BLOCKS_BSTATES, BlockBstates { ... }); +}; + +fn block_addprop(blk: BlockId, name: str, values: []str) BlockPropId = { +	assert(len(values) != 0, "Block property must have at least 1 value"); +	const bstates = &BLOCKS_BSTATES[blk]; +	assert(len(bstates.props) < types::U32_MAX - 1, +		"Too many block properties"); +	append(bstates.props, (strings::dup(name), strings::dupall(values))); +	return len(bstates.props): u32 - 1; +}; + +fn init_bstates() void = { +	for (let blk: BlockId = 0; blk < blocks_count(); blk += 1) { +		const bstates = &BLOCKS_BSTATES[blk]; + +		bstates.prop_moduli = alloc([], len(bstates.props)); +		let mod = 1u32; +		for (let j = 0z; j < len(bstates.props); j += 1) { +			// TODO: overflow... +			mod *= len(bstates.props[j].1): u32; +			static append(bstates.prop_moduli, mod); +		}; +		bstates.state0 = len(BSTATES_INFO): u32; +		bstates.nstates = mod; + +		assert(bstates.state0 + bstates.nstates > bstates.state0, +			"Too many blockstates"); + +		for (let j = 0u32; j < mod; j += 1) { +			append(BSTATES_INFO, BstateInfo { +				block = blk, +			}); +		}; +	}; +}; + +fn destroy_bstates() void = { +	for (let blk: BlockId = 0; blk < blocks_count(); blk += 1) { +		const bstates = &BLOCKS_BSTATES[blk]; +		for (let i = 0z; i < len(bstates.props); i += 1) { +			free(bstates.props[i].0); +			strings::freeall(bstates.props[i].1); +		}; +		free(bstates.prop_moduli); +	}; +	free(BLOCKS_BSTATES); +	free(BSTATES_INFO); +}; + +fn block_propcount(blk: BlockId) u32 = +	len(BLOCKS_BSTATES[blk].props): u32; + +fn block_propname(blk: BlockId, prop: BlockPropId) str = +	BLOCKS_BSTATES[blk].props[prop].0; + +fn block_findprop(blk: BlockId, name: str) (BlockPropId | void) = { +	for (let prop: BlockPropId = 0; +			prop < block_propcount(blk); prop += 1) { +		if (block_propname(blk, prop) == name) +			return prop; +	}; +}; + +fn block_propvalcount(blk: BlockId, prop: BlockPropId) u32 = +	len(BLOCKS_BSTATES[blk].props[prop].1): u32; + +fn block_propvalname(blk: BlockId, prop: BlockPropId, val: u32) str = +	BLOCKS_BSTATES[blk].props[prop].1[val]; + +fn block_findpropval(blk: BlockId, prop: BlockPropId, name: str) +		(u32 | void) = { +	for (let val = 0u32; val < block_propvalcount(blk, prop); val += 1) { +		if (block_propvalname(blk, prop, val) == name) +			return val; +	}; +}; + +fn bstate_getblock(bstate: BstateId) BlockId = +	BSTATES_INFO[bstate].block; + +fn bstate_getprop(bstate: BstateId, blk: BlockId, prop: BlockPropId) u32 = { +	const bstates = &BLOCKS_BSTATES[blk]; +	return (bstate - bstates.state0) % bstates.prop_moduli[prop] +		/ (if (prop == 0) 1u32 else bstates.prop_moduli[prop - 1]); +}; diff --git a/chunks.ha b/chunks.ha new file mode 100644 index 0000000..af78281 --- /dev/null +++ b/chunks.ha @@ -0,0 +1,221 @@ +use comparray; + +type Chunk = struct { +	sections: nullable *[*]Section, +}; + +type Section = struct { +	bstates: comparray::Array, +	dirty: bool, +	non_air_count: i32, + +	// render state + +	vertexbuf: uint, +	vertexcount: i32, +}; + +// XXX: the view range behaves a bit weirdly sometimes; further investigation +// needed. +def VIEW_MARGIN: i32 = 2; + +let CHUNKS: []Chunk = []; // len = VIEW_SIZE * VIEW_SIZE +let CHUNKS_POS: ChunkPos = ChunkPos { ... }; // -X,-Z corner of the rectangular view area +let CHUNKS_SIZE = 0i32; // width of the view area +let CHUNKS_MIN_Y = 0i8; // in chunks +let CHUNKS_HEIGHT = 0u8; // in chunks + +fn chunks_respawn() void = { +	const dim_type = &DIM_TYPES[DIM_TYPE]; +	CHUNKS_MIN_Y = dim_type.min_y; +	CHUNKS_HEIGHT = dim_type.height; +	setview(ChunkPos { ... }); +}; + +fn setview(center: ChunkPos) void = { +	const view_pos = ChunkPos { +		x = center.x - VIEW_DISTANCE - VIEW_MARGIN, +		z = center.z - VIEW_DISTANCE - VIEW_MARGIN, +	}; +	const view_size = VIEW_DISTANCE * 2 + VIEW_MARGIN * 2 + 1; +	let chunks = alloc([Chunk { ... }...], +		(view_size * view_size): size); + +	for (let z = 0i32; z < CHUNKS_SIZE; z += 1) +	for (let x = 0i32; x < CHUNKS_SIZE; x += 1) { +		const pos = ChunkPos { +			x = CHUNKS_POS.x + x, +			z = CHUNKS_POS.z + z, +		}; +		const chunk = getchunk(pos) as *Chunk; + +		const pos_ = ChunkPos { +			x = pos.x - view_pos.x, +			z = pos.z - view_pos.z, +		}; +		if (pos_.x >= 0 && pos_.x < view_size +				&& pos_.z >= 0 && pos_.z < view_size) { +			chunks[pos_.x + pos_.z * view_size] = *chunk; +		} else { +			chunk_destroy(pos); +		}; +	}; +	free(CHUNKS); + +	CHUNKS = chunks; +	CHUNKS_POS = view_pos; +	CHUNKS_SIZE = view_size; +}; + +fn setblock(pos: BlockPos, bstate: u16) void = { +	const spos = block_section(pos); +	const section = getsection(spos) as *Section; + +	const ref = if (section.bstates.palette_size == comparray::DIRECT) { +		yield bstate; +	} else :ref { +		const palette = comparray::get_palette(§ion.bstates); +		for (let i = 0u8; i < len(palette); i += 1) { +			if (palette[i] == bstate) +				yield :ref, i: u16; +		}; + +		comparray::grow_palette(§ion.bstates, 4096, +			section.bstates.palette_size + 1); + +		if (section.bstates.palette_size == comparray::DIRECT) { +			yield :ref, bstate; +		} else { +			const i = section.bstates.palette_size - 1; +			comparray::get_palette(§ion.bstates)[i] = bstate; +			yield :ref, i: u16; +		}; +	}; + +	const i = (pos.x & 0xf): size +		| (pos.z & 0xf): size << 4 +		| (pos.y & 0xf): size << 8; +	comparray::set(§ion.bstates, i, ref); + +	section.dirty = true; +	if (pos.x & 0xf == 0) section_make_dirty(spos.x - 1, spos.y, spos.z); +	if (pos.x & 0xf == 15) section_make_dirty(spos.x + 1, spos.y, spos.z); +	if (pos.y & 0xf == 0) section_make_dirty(spos.x, spos.y - 1, spos.z); +	if (pos.y & 0xf == 15) section_make_dirty(spos.x, spos.y + 1, spos.z); +	if (pos.z & 0xf == 0) section_make_dirty(spos.x, spos.y, spos.z - 1); +	if (pos.z & 0xf == 15) section_make_dirty(spos.x, spos.y, spos.z + 1); +}; + +fn getchunk(pos: ChunkPos) nullable *Chunk = { +	pos.x -= CHUNKS_POS.x; +	pos.z -= CHUNKS_POS.z; + +	if (pos.x < 0 || pos.x >= CHUNKS_SIZE) return null; +	if (pos.z < 0 || pos.z >= CHUNKS_SIZE) return null; + +	return &CHUNKS[pos.x + pos.z * CHUNKS_SIZE]; +}; + +fn getsection(pos: SectionPos) nullable *Section = { +	if (pos.y < CHUNKS_MIN_Y || pos.y >= CHUNKS_MIN_Y + CHUNKS_HEIGHT: i8) +		return null; + +	match (getchunk(pos.chunk)) { +	case let chunk: *Chunk => +		match (chunk.sections) { +		case let sections: *[*]Section => +			return §ions[pos.y: size - CHUNKS_MIN_Y: size]; +		case null => +			return null; +		}; +	case null => +		return null; +	}; +}; + +fn chunk_init(pos: ChunkPos) *Chunk = { +	chunk_destroy(pos); + +	let sections: []Section = alloc([], CHUNKS_HEIGHT); + +	for (let i = 0z; i < CHUNKS_HEIGHT; i += 1) { +		let bstates = comparray::new(1, 4096); +		comparray::clear(&bstates, 0); + +		static append(sections, Section { +			bstates = bstates, +			... +		}); +	}; + +	const chunk = getchunk(pos) as *Chunk; +	*chunk = Chunk { +		sections = sections: *[*]Section, +	}; + +	for (let i = 0u8; i < CHUNKS_HEIGHT; i += 1) { +		const spos = SectionPos { +			chunk = pos, +			y = i: i8 + CHUNKS_MIN_Y, +		}; +		section_make_dirty(spos.x - 1, spos.y, spos.z); +		section_make_dirty(spos.x + 1, spos.y, spos.z); +		section_make_dirty(spos.x, spos.y, spos.z - 1); +		section_make_dirty(spos.x, spos.y, spos.z + 1); +	}; + +	return chunk; +}; + +fn section_make_dirty(x: i32, y: i8, z: i32) void = { +	match (getsection(SectionPos { x = x, y = y, z = z })) { +	case let section: *Section => +		section.dirty = true; +	case null => void; +	}; +}; + +fn chunk_destroy(pos: ChunkPos) void = { +	const chunk = match (getchunk(pos)) { +	case let chunk: *Chunk => +		yield chunk; +	case null => +		return; +	}; + +	const sections = match (chunk.sections) { +	case let sections: *[*]Section => +		yield sections; +	case null => +		return; +	}; + +	for (let i = 0u8; i < CHUNKS_HEIGHT; i += 1) { +		section_destroy(§ions[i]); +	}; + +	free(sections); +	chunk.sections = null; +}; + +fn section_destroy(section: *Section) void = { +	render_chunks_section_destroy(section); +	comparray::clear(§ion.bstates, 0); +}; + +fn chunks_despawn() void = { +	for (let z = 0i32; z < CHUNKS_SIZE; z += 1) +	for (let x = 0i32; x < CHUNKS_SIZE; x += 1) { +		const pos = ChunkPos { +			x = CHUNKS_POS.x + x, +			z = CHUNKS_POS.z + z, +		}; +		chunk_destroy(pos); +	}; +	free(CHUNKS); +	CHUNKS = []; +	CHUNKS_POS = ChunkPos { ... }; +	CHUNKS_SIZE = 0; +	CHUNKS_MIN_Y = 0; +	CHUNKS_HEIGHT = 0; +}; diff --git a/client.ha b/client.ha new file mode 100644 index 0000000..d5093b3 --- /dev/null +++ b/client.ha @@ -0,0 +1,239 @@ +use gl::*; +use glm; +use io; +use mcproto; +use net; +use net::dial; +use net::ip; +use net::tcp; +use strings; +use time; +use trace; +use unix::poll; +use rt; + +def TCP_NODELAY: int = 1; // XXX: linux + +def PROTO_VER = 761i32; // TODO + +type ClientState = enum u8 { +	IDLE, +	CONNECT, +	LOGIN, +	JOIN, +	GAME, +}; + +let CLIENT_STATE = ClientState::IDLE; + +let CLIENT_ADDR = ""; +let CLIENT_USERNAME = ""; + +let CLIENT_SOCK: net::socket = -1; +// TODO: use tagged union once possible +let CLIENT_RECV: nullable *Receiver = null; +let CLIENT_RBUF: [0x1fffff]u8 = [0...]; + +fn client_connect(addr: str, username: str) void = { +	trace::info(&trace::root, "connecting to {}...", addr); + +	// TODO: async dns? +	let (addrs, port) = match (dial::resolve("tcp", addr, "minecraft")) { +	case let res: ([]ip::addr, u16) => +		yield res; +	case let err: dial::error => +		die("resolve {}: {}", addr, dial::strerror(err)); +	}; + +	// TODO: try secondary addresses +	trace::info(&trace::root, "trying {}:{}...", +		ip::string(addrs[0]), port); +	match (tcp::connect(addrs[0], port, net::sockflag::NONBLOCK)) { +	case let sock: net::socket => +		// TODO: error handling; +		// maybe don't use rt module (if there was an option) +		rt::setsockopt(sock, rt::IPPROTO_TCP, TCP_NODELAY, &1i, +			size(int): u32)!; + +		CLIENT_STATE = ClientState::CONNECT; +		CLIENT_SOCK = sock; +		CLIENT_ADDR = strings::dup(addr); +		CLIENT_USERNAME = strings::dup(username); +	case let err: net::error => +		die("connect {}: {}", addr, net::strerror(err)); +	}; +}; + +fn client_destroy() void = { +	match (io::close(CLIENT_SOCK)) { +	case void => void; +	case let err: io::error => +		trace::error(&trace::root, "failed to close socket: {}", +			io::strerror(err)): void; +	}; + +	match (CLIENT_RECV) { +	case let recv: *Receiver => +		recv_finish(CLIENT_RECV as *Receiver); +		free(CLIENT_RECV); +		CLIENT_RECV = null; +	case null => void; +	}; + +	if (CLIENT_STATE == ClientState::GAME) { +		game_destroy(); +	}; + +	free(CLIENT_ADDR); +	CLIENT_ADDR = ""; +	free(CLIENT_USERNAME); +	CLIENT_USERNAME = ""; +	CLIENT_STATE = ClientState::IDLE; +}; + +fn client_frame() void = { +	const t0 = time::now(time::clock::MONOTONIC); +	client_update_connection(); +	const t1 = time::now(time::clock::MONOTONIC); +	//trace::debug(&trace::root, "client_update_connection took {} µs", +	//	time::diff(t0, t1) / 1000); + +	if (CLIENT_STATE == ClientState::GAME) { +		game_frame(); +	}; +}; + +fn client_update_connection() void = { +	for (true) switch (CLIENT_STATE) { +	case ClientState::IDLE => +		abort(); +	case ClientState::CONNECT => +		let fds = [poll::pollfd { +			fd = CLIENT_SOCK, +			events = poll::event::POLLOUT, +			... +		}]; +		match (poll::poll(fds, 0)) { +		case let n: uint => +			if (n == 0) { +				return; +			}; +		case let err: poll::error => +			die("poll: {}", poll::strerror(err)); +		}; + +		let err: int = 0; +		rt::getsockopt(CLIENT_SOCK, rt::SOL_SOCKET, rt::SO_ERROR, +			&err, &(size(int): u32))!; +		if (err != 0) { +			die("connect {}: {}", CLIENT_ADDR, rt::strerror(err)); +		}; + +		trace::info(&trace::root, "connection established"); + +		CLIENT_RECV = alloc(newrecv(0x200000)); + +		CLIENT_STATE = ClientState::LOGIN; +		login_start(); +	case ClientState::LOGIN, +			ClientState::JOIN, +			ClientState::GAME => +		const recv = CLIENT_RECV as *Receiver; +		match (recv_poll(recv, CLIENT_SOCK, CLIENT_RBUF)) { +		case let length: size => +			let payload = CLIENT_RBUF[..length]; +			match (client_handle_packet(payload)) { +			case void => void; +			case trace::failed => +				die("invalid packet"); +			}; +		case void => +			return; +		}; +	}; +}; + +fn client_handle_packet(payload: []u8) +		(void | trace::failed) = { +	const tr = trace::ctx(&trace::root, "handle packet"); +	const dec = mcproto::Decoder { +		input = payload, +		pos = 0, +		tracer = &tr, +	}; +	const ctx = mcproto::root(&dec); +	const ctx_ = mcproto::context(&ctx, "packet id"); +	const packet_id = mcproto::decode_varint(&ctx_)?; +	switch (CLIENT_STATE) { +	case ClientState::IDLE, ClientState::CONNECT => +		abort(); +	case ClientState::LOGIN => +		login_handle_packet(&ctx, packet_id)?; +	case ClientState::JOIN, ClientState::GAME => +		switch (packet_id) { +		case 0x1f => +			const ctx_ = mcproto::context(&ctx, "0x1f keep alive"); +			handle_keep_alive(&ctx_)?; +		case 0x24 => +			if (CLIENT_STATE == ClientState::GAME) { +				game_destroy(); +				CLIENT_STATE = ClientState::JOIN; +			}; +			const ctx_ = mcproto::context(&ctx, "0x24 login"); +			handle_login(&ctx_)?; +			CLIENT_STATE = ClientState::GAME; +		case => +			if (CLIENT_STATE == ClientState::JOIN) { +				return mcproto::error(&ctx, "Login packet expected"); +			}; +			game_handle_packet(&ctx, packet_id)?; +		}; +	}; +}; + +fn network_send(packet_id: i32, payload: []u8) void = { +	match (mcproto::write_packet(CLIENT_SOCK, packet_id, payload)) { +	case void => void; +	case let err: io::error => +		die("network: error: write: {}", io::strerror(err)); +	}; +}; + +const LAYER_CLIENT_WAITING = Layer { +	blocks_input = &layer_client_waiting_blocks_input, +	input = &layer_client_waiting_input, +	is_opaque = &layer_client_waiting_is_opaque, +	render = &layer_client_waiting_render, +}; + +fn client_waiting_status() (str | void) = { +	switch (CLIENT_STATE) { +	case ClientState::CONNECT => +		return "Connecting to the server..."; +	case ClientState::LOGIN => +		return "Logging in..."; +	case ClientState::JOIN => +		return "Joining world..."; +	case ClientState::IDLE, ClientState::GAME => void; +	}; +}; + +fn layer_client_waiting_blocks_input() bool = { +	return client_waiting_status() is str; +}; + +fn layer_client_waiting_input(event: InputEvent) bool = { +	return false; +}; + +fn layer_client_waiting_is_opaque() bool = { +	return client_waiting_status() is str; +}; + +fn layer_client_waiting_render() void = { +	match (client_waiting_status()) { +	case let status: str => +		render_wait_screen(status); +	case void => void; +	}; +}; diff --git a/comparray/+test.ha b/comparray/+test.ha new file mode 100644 index 0000000..df257d3 --- /dev/null +++ b/comparray/+test.ha @@ -0,0 +1,52 @@ +use bufio; +use fmt; +use math::random; +use os; + +@test fn struct_size() void = { +	assert(size(Array) == 3 * size(*opaque)); +}; + +const TEST_SIZES: [_]u8 = [ +	CONSTANT, 2, 3, 4, 5, 6, 7, 8, 16, 17, 32, 33, 100, 200, 255, +	DIRECT, +]; +const TEST_ARRAYLEN: size = 4096; + +@test fn consistency() void = { +	let rng = random::init(42); + +	for (let i = 0z; i < len(TEST_SIZES); i += 1) { +		for (let j = i + 1; j < len(TEST_SIZES); j += 1) { +			fmt::printf("{},{} ", TEST_SIZES[i], TEST_SIZES[j])!; + +			let array = new(TEST_SIZES[i], TEST_ARRAYLEN); +			defer clear(&array, 0); + +			let palette = get_palette(&array); + +			for (let k = 0z; k < TEST_SIZES[i]; k += 1) { +				palette[k] = random::next(&rng): u16; +			}; + +			let unpacked: []u16 = alloc([], TEST_ARRAYLEN); +			defer free(unpacked); + +			for (let k = 0z; k < TEST_ARRAYLEN; k += 1) { +				const ref = +					random::u32n(&rng, TEST_SIZES[i]): u8; +				static append(unpacked, palette[ref]); +				set(&array, k, ref); +			}; + +			grow_palette(&array, TEST_ARRAYLEN, TEST_SIZES[j]); + +			for (let k = 0z; k < TEST_ARRAYLEN; k += 1) { +				assert( +					lookup(&array, get(&array, k)) +					== unpacked[k] +				); +			}; +		}; +	}; +}; diff --git a/comparray/array.ha b/comparray/array.ha new file mode 100644 index 0000000..6fa90e9 --- /dev/null +++ b/comparray/array.ha @@ -0,0 +1,210 @@ +use math; +use types; + +// premature optimization ftw! + +export def DIRECT: u8 = 0; +export def CONSTANT: u8 = 1; +export def INLINE_MAX: u8 = ((size(*opaque) * 2 - 1) / 2): u8; + +export type Array = union { +	// (2024 note): this used to use duplicate struct member names, which i guess +	// was a compiler bug and doesn't work anymore. +	struct { // direct +		palette_size: u8, // == DIRECT +		data_direct: *[*]u16, +	}, +	struct { // constant +		palette_size_const: u8, // == CONSTANT +		data_constant: u16, +	}, +	struct { // indirect inline +		palette_size_indirect_inline: u8, // <= INLINE_MAX, != DIRECT, != CONSTANT +		palette_inline: [INLINE_MAX]u16, +		data_indirect: *[*]u8, +	}, +	struct { // indirect ptr +		palette_size_indirect_ptr: u8, // > INLINE_MAX +		palette_ptr: *[*]u16, +		// data_indirect: *[*]u8, +		// (though it would result in an incorrect offset... yeah, +		// i don't know what i was thinking here at all.) +	}, +}; + +export fn new(palette_size: u8, arraylen: size) Array = { +	let array = Array { +		palette_size = palette_size, +	}; + +	if (palette_size == DIRECT) { +		array.data_direct = +			alloc([]: [0]u16, arraylen): *[*]u16; +	} else if (palette_size != CONSTANT) { +		array.data_indirect = alloc([]: [0]u8, +			indirect_size(palette_size, arraylen)): *[*]u8; +		if (palette_size > INLINE_MAX) { +			array.palette_ptr = +				alloc([]: [0]u16, palette_size): *[*]u16; +		}; +	}; + +	return array; +}; + +export fn clear(array: *Array, fill_value: u16) void = { +	if (array.palette_size == DIRECT) { +		free(array.data_direct); +	} else if (array.palette_size != CONSTANT) { +		free(array.data_indirect); +		if (array.palette_size > INLINE_MAX) +			free(array.palette_ptr); +	}; + +	array.palette_size = CONSTANT; +	array.data_constant = fill_value; +}; + +// XXX: should be @inline +export fn get(array: *Array, i: size) u16 = { +	if (array.palette_size == DIRECT) { +		return array.data_direct[i]; +	} else if (array.palette_size == CONSTANT) { +		return 0; +	} else { +		const log2nbits = palette_log2nbits(array.palette_size); +		const nbits = 1 << log2nbits; +		const valuemask = (1 << nbits) - 1; +		const log2nperbyte = 3 - log2nbits; +		const nperbyte = 1 << log2nperbyte; +		const indexlow = nperbyte - 1; + +		const byte = array.data_indirect[i >> log2nperbyte]; +		const shift = (i: u8 & indexlow) << log2nbits; +		return (byte >> shift) & valuemask; +	}; +}; + +// XXX: should be @inline +export fn set(array: *Array, i: size, ref: u16) void = { +	if (array.palette_size == DIRECT) { +		array.data_direct[i] = ref; +	} else if (array.palette_size == CONSTANT) { +		assert(ref == 0); +	} else { +		const log2nbits = palette_log2nbits(array.palette_size); +		const nbits = 1 << log2nbits; +		const valuemask = (1 << nbits) - 1; +		const log2nperbyte = 3 - log2nbits; +		const nperbyte = 1 << log2nperbyte; +		const indexlow = nperbyte - 1; + +		const byte = &array.data_indirect[i >> log2nperbyte]; +		const shift = (i: u8 & indexlow) << log2nbits; +		*byte = *byte & ~(valuemask << shift) | ref: u8 << shift; +	}; +}; + +// XXX: should be @inline +export fn get_palette(array: *Array) []u16 = { +	if (array.palette_size == DIRECT) { +		abort(); +	} else if (array.palette_size == CONSTANT) { +		return &array.data_constant: *[1]u16; +	} else if (array.palette_size <= INLINE_MAX) { +		return array.palette_inline[..array.palette_size]; +	} else { +		return array.palette_ptr[..array.palette_size]; +	}; +}; + +// XXX: should be @inline +export fn lookup(array: *Array, ref: u16) u16 = { +	if (array.palette_size == DIRECT) { +		return ref; +	}; +	return get_palette(array)[ref]; +}; + +// XXX: should be @inline +export fn indirect_size(palette_size: u8, arraylen: size) size = +	arraylen << palette_log2nbits(palette_size) >> 3; + +// XXX: should be @inline +export fn palette_log2nbits(palette_size: u8) u8 = { +	assert(palette_size != DIRECT); +	const nbits = math::bit_size_u8(palette_size - 1); +	return math::bit_size_u8(nbits - 1); +}; + +export fn grow_palette(array: *Array, arraylen: size, newsize: u8) void = { +	if (array.palette_size == newsize) return; +	assert( +		(array.palette_size - 1) < (newsize - 1), +		"new size must be >= old size" +	); + +	let newarray = *array; +	newarray.palette_size = newsize; + +	defer *array = newarray; + +	// By this point we know that the palette has grown in size, so it +	// always needs to be reallocated unless the new size is DIRECT, +	// in which case there will be no palette. + +	const palette = get_palette(array); + +	if (newsize == DIRECT) { +		void; +	} else if (newsize <= INLINE_MAX) { +		newarray.palette_inline[..len(palette)] = palette; +	} else { +		let newpalette = alloc(palette, newsize); +		newarray.palette_ptr = newpalette: *[*]u16; +	}; + +	defer if (array.palette_size > INLINE_MAX) { +		free(array.palette_ptr); +	}; + +	if (array.palette_size == CONSTANT) { +		if (newsize == DIRECT) { +			newarray.data_direct = alloc([array.data_constant...], +				arraylen): *[*]u16; +		} else { +			newarray.data_indirect = alloc([0...], +				indirect_size(newsize, arraylen)): *[*]u8; +		}; + +		return; +	}; + +	if (newsize == DIRECT) { +		newarray.data_direct = alloc([]: [0]u16, arraylen): *[*]u16; + +		for (let i = 0z; i < arraylen; i += 1) { +			newarray.data_direct[i] = palette[get(array, i)]; +		}; + +		free(array.data_indirect); +		return; +	}; + +	// We need to reallocate the data array if the number of bits per item +	// increased. + +	const log2nbits = palette_log2nbits(array.palette_size); +	const log2newnbits = palette_log2nbits(newsize); + +	if (log2nbits != log2newnbits) { +		newarray.data_indirect = alloc([]: [0]u8, +			indirect_size(newsize, arraylen)): *[*]u8; + +		for (let i = 0z; i < arraylen; i += 1) { +			set(&newarray, i, get(array, i)); +		}; + +		free(array.data_indirect); +	}; +}; diff --git a/content_blocks.ha b/content_blocks.ha new file mode 100644 index 0000000..c64af14 --- /dev/null +++ b/content_blocks.ha @@ -0,0 +1,3557 @@ +// generated by scripts/gen_blocks + +fn register_blocks() void = { +	static const p_up = "up"; +	static const p_in_wall = "in_wall"; +	static const p_slot_3_occupied = "slot_3_occupied"; +	static const p_part = "part"; +	static const p_lit = "lit"; +	static const p_short = "short"; +	static const p_face = "face"; +	static const p_distance = "distance"; +	static const p_enabled = "enabled"; +	static const p_instrument = "instrument"; +	static const p_shrieking = "shrieking"; +	static const p_sculk_sensor_phase = "sculk_sensor_phase"; +	static const p_eggs = "eggs"; +	static const p_has_bottle_2 = "has_bottle_2"; +	static const p_hanging = "hanging"; +	static const p_orientation = "orientation"; +	static const p_open = "open"; +	static const p_south = "south"; +	static const p_attached = "attached"; +	static const p_occupied = "occupied"; +	static const p_thickness = "thickness"; +	static const p_has_record = "has_record"; +	static const p_attachment = "attachment"; +	static const p_has_bottle_1 = "has_bottle_1"; +	static const p_stage = "stage"; +	static const p_power = "power"; +	static const p_axis = "axis"; +	static const p_disarmed = "disarmed"; +	static const p_has_book = "has_book"; +	static const p_inverted = "inverted"; +	static const p_honey_level = "honey_level"; +	static const p_bloom = "bloom"; +	static const p_north = "north"; +	static const p_note = "note"; +	static const p_pickles = "pickles"; +	static const p_slot_1_occupied = "slot_1_occupied"; +	static const p_charges = "charges"; +	static const p_bites = "bites"; +	static const p_shape = "shape"; +	static const p_slot_5_occupied = "slot_5_occupied"; +	static const p_persistent = "persistent"; +	static const p_layers = "layers"; +	static const p_berries = "berries"; +	static const p_facing = "facing"; +	static const p_triggered = "triggered"; +	static const p_snowy = "snowy"; +	static const p_leaves = "leaves"; +	static const p_west = "west"; +	static const p_slot_4_occupied = "slot_4_occupied"; +	static const p_conditional = "conditional"; +	static const p_slot_2_occupied = "slot_2_occupied"; +	static const p_mode = "mode"; +	static const p_moisture = "moisture"; +	static const p_delay = "delay"; +	static const p_eye = "eye"; +	static const p_extended = "extended"; +	static const p_drag = "drag"; +	static const p_slot_0_occupied = "slot_0_occupied"; +	static const p_level = "level"; +	static const p_can_summon = "can_summon"; +	static const p_type = "type"; +	static const p_rotation = "rotation"; +	static const p_east = "east"; +	static const p_tilt = "tilt"; +	static const p_candles = "candles"; +	static const p_bottom = "bottom"; +	static const p_vertical_direction = "vertical_direction"; +	static const p_half = "half"; +	static const p_powered = "powered"; +	static const p_waterlogged = "waterlogged"; +	static const p_hatch = "hatch"; +	static const p_age = "age"; +	static const p_hinge = "hinge"; +	static const p_unstable = "unstable"; +	static const p_down = "down"; +	static const p_locked = "locked"; +	static const p_has_bottle_0 = "has_bottle_0"; +	static const p_signal_fire = "signal_fire"; + +	static const v_floor_ceiling_single_wall_double_wall = ["floor", "ceiling", "single_wall", "double_wall"]; +	static const v_0_1_2_3 = ["0", "1", "2", "3"]; +	static const v_down_east_down_north_down_south_down_west_up_east_up_north_up_south_up_west_west_up_east_up_north_up_south_up = ["down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up"]; +	static const v_1_2_3_4_5_6_7 = ["1", "2", "3", "4", "5", "6", "7"]; +	static const v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"]; +	static const v_0_1_2_3_4_5 = ["0", "1", "2", "3", "4", "5"]; +	static const v_0_1_2_3_4 = ["0", "1", "2", "3", "4"]; +	static const v_normal_sticky = ["normal", "sticky"]; +	static const v_x_y_z = ["x", "y", "z"]; +	static const v_floor_wall_ceiling = ["floor", "wall", "ceiling"]; +	static const v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25"]; +	static const v_up_down = ["up", "down"]; +	static const v_0_1_2_3_4_5_6_7 = ["0", "1", "2", "3", "4", "5", "6", "7"]; +	static const v_compare_subtract = ["compare", "subtract"]; +	static const v_1_2_3_4_5_6_7_8 = ["1", "2", "3", "4", "5", "6", "7", "8"]; +	static const v_down_north_south_west_east = ["down", "north", "south", "west", "east"]; +	static const v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"]; +	static const v_tip_merge_tip_frustum_middle_base = ["tip_merge", "tip", "frustum", "middle", "base"]; +	static const v_x_z = ["x", "z"]; +	static const v_true_false = ["true", "false"]; +	static const v_none_small_large = ["none", "small", "large"]; +	static const v_0_1 = ["0", "1"]; +	static const v_single_left_right = ["single", "left", "right"]; +	static const v_none_unstable_partial_full = ["none", "unstable", "partial", "full"]; +	static const v_north_south_east_west_ascending_east_ascending_west_ascending_north_ascending_south = ["north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south"]; +	static const v_north_south_west_east = ["north", "south", "west", "east"]; +	static const v_top_bottom = ["top", "bottom"]; +	static const v_harp_basedrum_snare_hat_bass_flute_bell_guitar_chime_xylophone_iron_xylophone_cow_bell_didgeridoo_bit_banjo_pling_zombie_skeleton_creeper_dragon_wither_skeleton_piglin_custom_head = ["harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head"]; +	static const v_save_load_corner_data = ["save", "load", "corner", "data"]; +	static const v_inactive_active_cooldown = ["inactive", "active", "cooldown"]; +	static const v_up_side_none = ["up", "side", "none"]; +	static const v_top_bottom_double = ["top", "bottom", "double"]; +	static const v_upper_lower = ["upper", "lower"]; +	static const v_north_south_east_west_ascending_east_ascending_west_ascending_north_ascending_south_south_east_south_west_north_west_north_east = ["north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south", "south_east", "south_west", "north_west", "north_east"]; +	static const v_1_2_3_4 = ["1", "2", "3", "4"]; +	static const v_north_east_south_west_up_down = ["north", "east", "south", "west", "up", "down"]; +	static const v_1_2_3 = ["1", "2", "3"]; +	static const v_0_1_2_3_4_5_6 = ["0", "1", "2", "3", "4", "5", "6"]; +	static const v_0_1_2_3_4_5_6_7_8 = ["0", "1", "2", "3", "4", "5", "6", "7", "8"]; +	static const v_head_foot = ["head", "foot"]; +	static const v_left_right = ["left", "right"]; +	static const v_none_low_tall = ["none", "low", "tall"]; +	static const v_0_1_2 = ["0", "1", "2"]; +	static const v_straight_inner_left_inner_right_outer_left_outer_right = ["straight", "inner_left", "inner_right", "outer_left", "outer_right"]; + +	const blk = blocks_register("minecraft:air"); // 0 + +	const blk = blocks_register("minecraft:stone"); // 1 + +	const blk = blocks_register("minecraft:granite"); // 2 + +	const blk = blocks_register("minecraft:polished_granite"); // 3 + +	const blk = blocks_register("minecraft:diorite"); // 4 + +	const blk = blocks_register("minecraft:polished_diorite"); // 5 + +	const blk = blocks_register("minecraft:andesite"); // 6 + +	const blk = blocks_register("minecraft:polished_andesite"); // 7 + +	const blk = blocks_register("minecraft:grass_block"); // 8 +	block_addprop(blk, p_snowy, v_true_false); + +	const blk = blocks_register("minecraft:dirt"); // 10 + +	const blk = blocks_register("minecraft:coarse_dirt"); // 11 + +	const blk = blocks_register("minecraft:podzol"); // 12 +	block_addprop(blk, p_snowy, v_true_false); + +	const blk = blocks_register("minecraft:cobblestone"); // 14 + +	const blk = blocks_register("minecraft:oak_planks"); // 15 + +	const blk = blocks_register("minecraft:spruce_planks"); // 16 + +	const blk = blocks_register("minecraft:birch_planks"); // 17 + +	const blk = blocks_register("minecraft:jungle_planks"); // 18 + +	const blk = blocks_register("minecraft:acacia_planks"); // 19 + +	const blk = blocks_register("minecraft:dark_oak_planks"); // 20 + +	const blk = blocks_register("minecraft:mangrove_planks"); // 21 + +	const blk = blocks_register("minecraft:bamboo_planks"); // 22 + +	const blk = blocks_register("minecraft:bamboo_mosaic"); // 23 + +	const blk = blocks_register("minecraft:oak_sapling"); // 24 +	block_addprop(blk, p_stage, v_0_1); + +	const blk = blocks_register("minecraft:spruce_sapling"); // 26 +	block_addprop(blk, p_stage, v_0_1); + +	const blk = blocks_register("minecraft:birch_sapling"); // 28 +	block_addprop(blk, p_stage, v_0_1); + +	const blk = blocks_register("minecraft:jungle_sapling"); // 30 +	block_addprop(blk, p_stage, v_0_1); + +	const blk = blocks_register("minecraft:acacia_sapling"); // 32 +	block_addprop(blk, p_stage, v_0_1); + +	const blk = blocks_register("minecraft:dark_oak_sapling"); // 34 +	block_addprop(blk, p_stage, v_0_1); + +	const blk = blocks_register("minecraft:mangrove_propagule"); // 36 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_stage, v_0_1); +	block_addprop(blk, p_hanging, v_true_false); +	block_addprop(blk, p_age, v_0_1_2_3_4); + +	const blk = blocks_register("minecraft:bedrock"); // 76 + +	const blk = blocks_register("minecraft:water"); // 77 +	block_addprop(blk, p_level, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:lava"); // 93 +	block_addprop(blk, p_level, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:sand"); // 109 + +	const blk = blocks_register("minecraft:red_sand"); // 110 + +	const blk = blocks_register("minecraft:gravel"); // 111 + +	const blk = blocks_register("minecraft:gold_ore"); // 112 + +	const blk = blocks_register("minecraft:deepslate_gold_ore"); // 113 + +	const blk = blocks_register("minecraft:iron_ore"); // 114 + +	const blk = blocks_register("minecraft:deepslate_iron_ore"); // 115 + +	const blk = blocks_register("minecraft:coal_ore"); // 116 + +	const blk = blocks_register("minecraft:deepslate_coal_ore"); // 117 + +	const blk = blocks_register("minecraft:nether_gold_ore"); // 118 + +	const blk = blocks_register("minecraft:oak_log"); // 119 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:spruce_log"); // 122 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:birch_log"); // 125 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:jungle_log"); // 128 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:acacia_log"); // 131 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:dark_oak_log"); // 134 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:mangrove_log"); // 137 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:mangrove_roots"); // 140 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:muddy_mangrove_roots"); // 142 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:bamboo_block"); // 145 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_spruce_log"); // 148 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_birch_log"); // 151 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_jungle_log"); // 154 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_acacia_log"); // 157 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_dark_oak_log"); // 160 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_oak_log"); // 163 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_mangrove_log"); // 166 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_bamboo_block"); // 169 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:oak_wood"); // 172 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:spruce_wood"); // 175 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:birch_wood"); // 178 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:jungle_wood"); // 181 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:acacia_wood"); // 184 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:dark_oak_wood"); // 187 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:mangrove_wood"); // 190 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_oak_wood"); // 193 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_spruce_wood"); // 196 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_birch_wood"); // 199 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_jungle_wood"); // 202 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_acacia_wood"); // 205 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_dark_oak_wood"); // 208 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_mangrove_wood"); // 211 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:oak_leaves"); // 214 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:spruce_leaves"); // 242 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:birch_leaves"); // 270 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:jungle_leaves"); // 298 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:acacia_leaves"); // 326 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:dark_oak_leaves"); // 354 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:mangrove_leaves"); // 382 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:azalea_leaves"); // 410 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:flowering_azalea_leaves"); // 438 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_persistent, v_true_false); +	block_addprop(blk, p_distance, v_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:sponge"); // 466 + +	const blk = blocks_register("minecraft:wet_sponge"); // 467 + +	const blk = blocks_register("minecraft:glass"); // 468 + +	const blk = blocks_register("minecraft:lapis_ore"); // 469 + +	const blk = blocks_register("minecraft:deepslate_lapis_ore"); // 470 + +	const blk = blocks_register("minecraft:lapis_block"); // 471 + +	const blk = blocks_register("minecraft:dispenser"); // 472 +	block_addprop(blk, p_triggered, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:sandstone"); // 484 + +	const blk = blocks_register("minecraft:chiseled_sandstone"); // 485 + +	const blk = blocks_register("minecraft:cut_sandstone"); // 486 + +	const blk = blocks_register("minecraft:note_block"); // 487 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_note, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24); +	block_addprop(blk, p_instrument, v_harp_basedrum_snare_hat_bass_flute_bell_guitar_chime_xylophone_iron_xylophone_cow_bell_didgeridoo_bit_banjo_pling_zombie_skeleton_creeper_dragon_wither_skeleton_piglin_custom_head); + +	const blk = blocks_register("minecraft:white_bed"); // 1637 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:orange_bed"); // 1653 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:magenta_bed"); // 1669 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:light_blue_bed"); // 1685 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:yellow_bed"); // 1701 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:lime_bed"); // 1717 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:pink_bed"); // 1733 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:gray_bed"); // 1749 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:light_gray_bed"); // 1765 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:cyan_bed"); // 1781 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:purple_bed"); // 1797 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:blue_bed"); // 1813 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:brown_bed"); // 1829 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:green_bed"); // 1845 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:red_bed"); // 1861 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:black_bed"); // 1877 +	block_addprop(blk, p_part, v_head_foot); +	block_addprop(blk, p_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:powered_rail"); // 1893 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_north_south_east_west_ascending_east_ascending_west_ascending_north_ascending_south); +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:detector_rail"); // 1917 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_north_south_east_west_ascending_east_ascending_west_ascending_north_ascending_south); +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:sticky_piston"); // 1941 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); +	block_addprop(blk, p_extended, v_true_false); + +	const blk = blocks_register("minecraft:cobweb"); // 1953 + +	const blk = blocks_register("minecraft:grass"); // 1954 + +	const blk = blocks_register("minecraft:fern"); // 1955 + +	const blk = blocks_register("minecraft:dead_bush"); // 1956 + +	const blk = blocks_register("minecraft:seagrass"); // 1957 + +	const blk = blocks_register("minecraft:tall_seagrass"); // 1958 +	block_addprop(blk, p_half, v_upper_lower); + +	const blk = blocks_register("minecraft:piston"); // 1960 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); +	block_addprop(blk, p_extended, v_true_false); + +	const blk = blocks_register("minecraft:piston_head"); // 1972 +	block_addprop(blk, p_type, v_normal_sticky); +	block_addprop(blk, p_short, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:white_wool"); // 1996 + +	const blk = blocks_register("minecraft:orange_wool"); // 1997 + +	const blk = blocks_register("minecraft:magenta_wool"); // 1998 + +	const blk = blocks_register("minecraft:light_blue_wool"); // 1999 + +	const blk = blocks_register("minecraft:yellow_wool"); // 2000 + +	const blk = blocks_register("minecraft:lime_wool"); // 2001 + +	const blk = blocks_register("minecraft:pink_wool"); // 2002 + +	const blk = blocks_register("minecraft:gray_wool"); // 2003 + +	const blk = blocks_register("minecraft:light_gray_wool"); // 2004 + +	const blk = blocks_register("minecraft:cyan_wool"); // 2005 + +	const blk = blocks_register("minecraft:purple_wool"); // 2006 + +	const blk = blocks_register("minecraft:blue_wool"); // 2007 + +	const blk = blocks_register("minecraft:brown_wool"); // 2008 + +	const blk = blocks_register("minecraft:green_wool"); // 2009 + +	const blk = blocks_register("minecraft:red_wool"); // 2010 + +	const blk = blocks_register("minecraft:black_wool"); // 2011 + +	const blk = blocks_register("minecraft:moving_piston"); // 2012 +	block_addprop(blk, p_type, v_normal_sticky); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:dandelion"); // 2024 + +	const blk = blocks_register("minecraft:poppy"); // 2025 + +	const blk = blocks_register("minecraft:blue_orchid"); // 2026 + +	const blk = blocks_register("minecraft:allium"); // 2027 + +	const blk = blocks_register("minecraft:azure_bluet"); // 2028 + +	const blk = blocks_register("minecraft:red_tulip"); // 2029 + +	const blk = blocks_register("minecraft:orange_tulip"); // 2030 + +	const blk = blocks_register("minecraft:white_tulip"); // 2031 + +	const blk = blocks_register("minecraft:pink_tulip"); // 2032 + +	const blk = blocks_register("minecraft:oxeye_daisy"); // 2033 + +	const blk = blocks_register("minecraft:cornflower"); // 2034 + +	const blk = blocks_register("minecraft:wither_rose"); // 2035 + +	const blk = blocks_register("minecraft:lily_of_the_valley"); // 2036 + +	const blk = blocks_register("minecraft:brown_mushroom"); // 2037 + +	const blk = blocks_register("minecraft:red_mushroom"); // 2038 + +	const blk = blocks_register("minecraft:gold_block"); // 2039 + +	const blk = blocks_register("minecraft:iron_block"); // 2040 + +	const blk = blocks_register("minecraft:bricks"); // 2041 + +	const blk = blocks_register("minecraft:tnt"); // 2042 +	block_addprop(blk, p_unstable, v_true_false); + +	const blk = blocks_register("minecraft:bookshelf"); // 2044 + +	const blk = blocks_register("minecraft:chiseled_bookshelf"); // 2045 +	block_addprop(blk, p_slot_5_occupied, v_true_false); +	block_addprop(blk, p_slot_4_occupied, v_true_false); +	block_addprop(blk, p_slot_3_occupied, v_true_false); +	block_addprop(blk, p_slot_2_occupied, v_true_false); +	block_addprop(blk, p_slot_1_occupied, v_true_false); +	block_addprop(blk, p_slot_0_occupied, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mossy_cobblestone"); // 2301 + +	const blk = blocks_register("minecraft:obsidian"); // 2302 + +	const blk = blocks_register("minecraft:torch"); // 2303 + +	const blk = blocks_register("minecraft:wall_torch"); // 2304 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:fire"); // 2308 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:soul_fire"); // 2820 + +	const blk = blocks_register("minecraft:spawner"); // 2821 + +	const blk = blocks_register("minecraft:oak_stairs"); // 2822 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:chest"); // 2902 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_single_left_right); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:redstone_wire"); // 2926 +	block_addprop(blk, p_west, v_up_side_none); +	block_addprop(blk, p_south, v_up_side_none); +	block_addprop(blk, p_power, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_north, v_up_side_none); +	block_addprop(blk, p_east, v_up_side_none); + +	const blk = blocks_register("minecraft:diamond_ore"); // 4222 + +	const blk = blocks_register("minecraft:deepslate_diamond_ore"); // 4223 + +	const blk = blocks_register("minecraft:diamond_block"); // 4224 + +	const blk = blocks_register("minecraft:crafting_table"); // 4225 + +	const blk = blocks_register("minecraft:wheat"); // 4226 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:farmland"); // 4234 +	block_addprop(blk, p_moisture, v_0_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:furnace"); // 4242 +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:oak_sign"); // 4250 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:spruce_sign"); // 4282 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:birch_sign"); // 4314 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:acacia_sign"); // 4346 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:jungle_sign"); // 4378 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:dark_oak_sign"); // 4410 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:mangrove_sign"); // 4442 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:bamboo_sign"); // 4474 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:oak_door"); // 4506 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:ladder"); // 4570 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:rail"); // 4578 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_north_south_east_west_ascending_east_ascending_west_ascending_north_ascending_south_south_east_south_west_north_west_north_east); + +	const blk = blocks_register("minecraft:cobblestone_stairs"); // 4598 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:oak_wall_sign"); // 4678 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:spruce_wall_sign"); // 4686 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:birch_wall_sign"); // 4694 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:acacia_wall_sign"); // 4702 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:jungle_wall_sign"); // 4710 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dark_oak_wall_sign"); // 4718 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mangrove_wall_sign"); // 4726 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bamboo_wall_sign"); // 4734 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:oak_hanging_sign"); // 4742 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:spruce_hanging_sign"); // 4806 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:birch_hanging_sign"); // 4870 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:acacia_hanging_sign"); // 4934 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:jungle_hanging_sign"); // 4998 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:dark_oak_hanging_sign"); // 5062 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:crimson_hanging_sign"); // 5126 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:warped_hanging_sign"); // 5190 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:mangrove_hanging_sign"); // 5254 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:bamboo_hanging_sign"); // 5318 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:oak_wall_hanging_sign"); // 5382 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:spruce_wall_hanging_sign"); // 5390 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:birch_wall_hanging_sign"); // 5398 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:acacia_wall_hanging_sign"); // 5406 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:jungle_wall_hanging_sign"); // 5414 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dark_oak_wall_hanging_sign"); // 5422 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mangrove_wall_hanging_sign"); // 5430 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:crimson_wall_hanging_sign"); // 5438 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:warped_wall_hanging_sign"); // 5446 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bamboo_wall_hanging_sign"); // 5454 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:lever"); // 5462 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:stone_pressure_plate"); // 5486 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:iron_door"); // 5488 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:oak_pressure_plate"); // 5552 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:spruce_pressure_plate"); // 5554 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:birch_pressure_plate"); // 5556 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:jungle_pressure_plate"); // 5558 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:acacia_pressure_plate"); // 5560 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:dark_oak_pressure_plate"); // 5562 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:mangrove_pressure_plate"); // 5564 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:bamboo_pressure_plate"); // 5566 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:redstone_ore"); // 5568 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:deepslate_redstone_ore"); // 5570 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:redstone_torch"); // 5572 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:redstone_wall_torch"); // 5574 +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:stone_button"); // 5582 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:snow"); // 5606 +	block_addprop(blk, p_layers, v_1_2_3_4_5_6_7_8); + +	const blk = blocks_register("minecraft:ice"); // 5614 + +	const blk = blocks_register("minecraft:snow_block"); // 5615 + +	const blk = blocks_register("minecraft:cactus"); // 5616 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:clay"); // 5632 + +	const blk = blocks_register("minecraft:sugar_cane"); // 5633 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:jukebox"); // 5649 +	block_addprop(blk, p_has_record, v_true_false); + +	const blk = blocks_register("minecraft:oak_fence"); // 5651 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:pumpkin"); // 5683 + +	const blk = blocks_register("minecraft:netherrack"); // 5684 + +	const blk = blocks_register("minecraft:soul_sand"); // 5685 + +	const blk = blocks_register("minecraft:soul_soil"); // 5686 + +	const blk = blocks_register("minecraft:basalt"); // 5687 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:polished_basalt"); // 5690 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:soul_torch"); // 5693 + +	const blk = blocks_register("minecraft:soul_wall_torch"); // 5694 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:glowstone"); // 5698 + +	const blk = blocks_register("minecraft:nether_portal"); // 5699 +	block_addprop(blk, p_axis, v_x_z); + +	const blk = blocks_register("minecraft:carved_pumpkin"); // 5701 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:jack_o_lantern"); // 5705 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:cake"); // 5709 +	block_addprop(blk, p_bites, v_0_1_2_3_4_5_6); + +	const blk = blocks_register("minecraft:repeater"); // 5716 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_locked, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_delay, v_1_2_3_4); + +	const blk = blocks_register("minecraft:white_stained_glass"); // 5780 + +	const blk = blocks_register("minecraft:orange_stained_glass"); // 5781 + +	const blk = blocks_register("minecraft:magenta_stained_glass"); // 5782 + +	const blk = blocks_register("minecraft:light_blue_stained_glass"); // 5783 + +	const blk = blocks_register("minecraft:yellow_stained_glass"); // 5784 + +	const blk = blocks_register("minecraft:lime_stained_glass"); // 5785 + +	const blk = blocks_register("minecraft:pink_stained_glass"); // 5786 + +	const blk = blocks_register("minecraft:gray_stained_glass"); // 5787 + +	const blk = blocks_register("minecraft:light_gray_stained_glass"); // 5788 + +	const blk = blocks_register("minecraft:cyan_stained_glass"); // 5789 + +	const blk = blocks_register("minecraft:purple_stained_glass"); // 5790 + +	const blk = blocks_register("minecraft:blue_stained_glass"); // 5791 + +	const blk = blocks_register("minecraft:brown_stained_glass"); // 5792 + +	const blk = blocks_register("minecraft:green_stained_glass"); // 5793 + +	const blk = blocks_register("minecraft:red_stained_glass"); // 5794 + +	const blk = blocks_register("minecraft:black_stained_glass"); // 5795 + +	const blk = blocks_register("minecraft:oak_trapdoor"); // 5796 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:spruce_trapdoor"); // 5860 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:birch_trapdoor"); // 5924 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:jungle_trapdoor"); // 5988 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:acacia_trapdoor"); // 6052 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dark_oak_trapdoor"); // 6116 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mangrove_trapdoor"); // 6180 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bamboo_trapdoor"); // 6244 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:stone_bricks"); // 6308 + +	const blk = blocks_register("minecraft:mossy_stone_bricks"); // 6309 + +	const blk = blocks_register("minecraft:cracked_stone_bricks"); // 6310 + +	const blk = blocks_register("minecraft:chiseled_stone_bricks"); // 6311 + +	const blk = blocks_register("minecraft:packed_mud"); // 6312 + +	const blk = blocks_register("minecraft:mud_bricks"); // 6313 + +	const blk = blocks_register("minecraft:infested_stone"); // 6314 + +	const blk = blocks_register("minecraft:infested_cobblestone"); // 6315 + +	const blk = blocks_register("minecraft:infested_stone_bricks"); // 6316 + +	const blk = blocks_register("minecraft:infested_mossy_stone_bricks"); // 6317 + +	const blk = blocks_register("minecraft:infested_cracked_stone_bricks"); // 6318 + +	const blk = blocks_register("minecraft:infested_chiseled_stone_bricks"); // 6319 + +	const blk = blocks_register("minecraft:brown_mushroom_block"); // 6320 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); +	block_addprop(blk, p_down, v_true_false); + +	const blk = blocks_register("minecraft:red_mushroom_block"); // 6384 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); +	block_addprop(blk, p_down, v_true_false); + +	const blk = blocks_register("minecraft:mushroom_stem"); // 6448 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); +	block_addprop(blk, p_down, v_true_false); + +	const blk = blocks_register("minecraft:iron_bars"); // 6512 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:chain"); // 6544 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:glass_pane"); // 6550 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:melon"); // 6582 + +	const blk = blocks_register("minecraft:attached_pumpkin_stem"); // 6583 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:attached_melon_stem"); // 6587 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:pumpkin_stem"); // 6591 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:melon_stem"); // 6599 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:vine"); // 6607 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:glow_lichen"); // 6639 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); +	block_addprop(blk, p_down, v_true_false); + +	const blk = blocks_register("minecraft:oak_fence_gate"); // 6767 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:brick_stairs"); // 6799 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:stone_brick_stairs"); // 6879 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mud_brick_stairs"); // 6959 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mycelium"); // 7039 +	block_addprop(blk, p_snowy, v_true_false); + +	const blk = blocks_register("minecraft:lily_pad"); // 7041 + +	const blk = blocks_register("minecraft:nether_bricks"); // 7042 + +	const blk = blocks_register("minecraft:nether_brick_fence"); // 7043 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:nether_brick_stairs"); // 7075 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:nether_wart"); // 7155 +	block_addprop(blk, p_age, v_0_1_2_3); + +	const blk = blocks_register("minecraft:enchanting_table"); // 7159 + +	const blk = blocks_register("minecraft:brewing_stand"); // 7160 +	block_addprop(blk, p_has_bottle_2, v_true_false); +	block_addprop(blk, p_has_bottle_1, v_true_false); +	block_addprop(blk, p_has_bottle_0, v_true_false); + +	const blk = blocks_register("minecraft:cauldron"); // 7168 + +	const blk = blocks_register("minecraft:water_cauldron"); // 7169 +	block_addprop(blk, p_level, v_1_2_3); + +	const blk = blocks_register("minecraft:lava_cauldron"); // 7172 + +	const blk = blocks_register("minecraft:powder_snow_cauldron"); // 7173 +	block_addprop(blk, p_level, v_1_2_3); + +	const blk = blocks_register("minecraft:end_portal"); // 7176 + +	const blk = blocks_register("minecraft:end_portal_frame"); // 7177 +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_eye, v_true_false); + +	const blk = blocks_register("minecraft:end_stone"); // 7185 + +	const blk = blocks_register("minecraft:dragon_egg"); // 7186 + +	const blk = blocks_register("minecraft:redstone_lamp"); // 7187 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:cocoa"); // 7189 +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_age, v_0_1_2); + +	const blk = blocks_register("minecraft:sandstone_stairs"); // 7201 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:emerald_ore"); // 7281 + +	const blk = blocks_register("minecraft:deepslate_emerald_ore"); // 7282 + +	const blk = blocks_register("minecraft:ender_chest"); // 7283 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:tripwire_hook"); // 7291 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:tripwire"); // 7307 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); +	block_addprop(blk, p_disarmed, v_true_false); +	block_addprop(blk, p_attached, v_true_false); + +	const blk = blocks_register("minecraft:emerald_block"); // 7435 + +	const blk = blocks_register("minecraft:spruce_stairs"); // 7436 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:birch_stairs"); // 7516 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:jungle_stairs"); // 7596 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:command_block"); // 7676 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); +	block_addprop(blk, p_conditional, v_true_false); + +	const blk = blocks_register("minecraft:beacon"); // 7688 + +	const blk = blocks_register("minecraft:cobblestone_wall"); // 7689 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:mossy_cobblestone_wall"); // 8013 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:flower_pot"); // 8337 + +	const blk = blocks_register("minecraft:potted_oak_sapling"); // 8338 + +	const blk = blocks_register("minecraft:potted_spruce_sapling"); // 8339 + +	const blk = blocks_register("minecraft:potted_birch_sapling"); // 8340 + +	const blk = blocks_register("minecraft:potted_jungle_sapling"); // 8341 + +	const blk = blocks_register("minecraft:potted_acacia_sapling"); // 8342 + +	const blk = blocks_register("minecraft:potted_dark_oak_sapling"); // 8343 + +	const blk = blocks_register("minecraft:potted_mangrove_propagule"); // 8344 + +	const blk = blocks_register("minecraft:potted_fern"); // 8345 + +	const blk = blocks_register("minecraft:potted_dandelion"); // 8346 + +	const blk = blocks_register("minecraft:potted_poppy"); // 8347 + +	const blk = blocks_register("minecraft:potted_blue_orchid"); // 8348 + +	const blk = blocks_register("minecraft:potted_allium"); // 8349 + +	const blk = blocks_register("minecraft:potted_azure_bluet"); // 8350 + +	const blk = blocks_register("minecraft:potted_red_tulip"); // 8351 + +	const blk = blocks_register("minecraft:potted_orange_tulip"); // 8352 + +	const blk = blocks_register("minecraft:potted_white_tulip"); // 8353 + +	const blk = blocks_register("minecraft:potted_pink_tulip"); // 8354 + +	const blk = blocks_register("minecraft:potted_oxeye_daisy"); // 8355 + +	const blk = blocks_register("minecraft:potted_cornflower"); // 8356 + +	const blk = blocks_register("minecraft:potted_lily_of_the_valley"); // 8357 + +	const blk = blocks_register("minecraft:potted_wither_rose"); // 8358 + +	const blk = blocks_register("minecraft:potted_red_mushroom"); // 8359 + +	const blk = blocks_register("minecraft:potted_brown_mushroom"); // 8360 + +	const blk = blocks_register("minecraft:potted_dead_bush"); // 8361 + +	const blk = blocks_register("minecraft:potted_cactus"); // 8362 + +	const blk = blocks_register("minecraft:carrots"); // 8363 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:potatoes"); // 8371 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7); + +	const blk = blocks_register("minecraft:oak_button"); // 8379 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:spruce_button"); // 8403 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:birch_button"); // 8427 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:jungle_button"); // 8451 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:acacia_button"); // 8475 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:dark_oak_button"); // 8499 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:mangrove_button"); // 8523 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:bamboo_button"); // 8547 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:skeleton_skull"); // 8571 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:skeleton_wall_skull"); // 8587 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:wither_skeleton_skull"); // 8591 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:wither_skeleton_wall_skull"); // 8607 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:zombie_head"); // 8611 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:zombie_wall_head"); // 8627 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:player_head"); // 8631 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:player_wall_head"); // 8647 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:creeper_head"); // 8651 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:creeper_wall_head"); // 8667 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dragon_head"); // 8671 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:dragon_wall_head"); // 8687 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:piglin_head"); // 8691 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:piglin_wall_head"); // 8707 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:anvil"); // 8711 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:chipped_anvil"); // 8715 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:damaged_anvil"); // 8719 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:trapped_chest"); // 8723 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_single_left_right); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:light_weighted_pressure_plate"); // 8747 +	block_addprop(blk, p_power, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:heavy_weighted_pressure_plate"); // 8763 +	block_addprop(blk, p_power, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:comparator"); // 8779 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_mode, v_compare_subtract); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:daylight_detector"); // 8795 +	block_addprop(blk, p_power, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); +	block_addprop(blk, p_inverted, v_true_false); + +	const blk = blocks_register("minecraft:redstone_block"); // 8827 + +	const blk = blocks_register("minecraft:nether_quartz_ore"); // 8828 + +	const blk = blocks_register("minecraft:hopper"); // 8829 +	block_addprop(blk, p_facing, v_down_north_south_west_east); +	block_addprop(blk, p_enabled, v_true_false); + +	const blk = blocks_register("minecraft:quartz_block"); // 8839 + +	const blk = blocks_register("minecraft:chiseled_quartz_block"); // 8840 + +	const blk = blocks_register("minecraft:quartz_pillar"); // 8841 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:quartz_stairs"); // 8844 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:activator_rail"); // 8924 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_north_south_east_west_ascending_east_ascending_west_ascending_north_ascending_south); +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:dropper"); // 8948 +	block_addprop(blk, p_triggered, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:white_terracotta"); // 8960 + +	const blk = blocks_register("minecraft:orange_terracotta"); // 8961 + +	const blk = blocks_register("minecraft:magenta_terracotta"); // 8962 + +	const blk = blocks_register("minecraft:light_blue_terracotta"); // 8963 + +	const blk = blocks_register("minecraft:yellow_terracotta"); // 8964 + +	const blk = blocks_register("minecraft:lime_terracotta"); // 8965 + +	const blk = blocks_register("minecraft:pink_terracotta"); // 8966 + +	const blk = blocks_register("minecraft:gray_terracotta"); // 8967 + +	const blk = blocks_register("minecraft:light_gray_terracotta"); // 8968 + +	const blk = blocks_register("minecraft:cyan_terracotta"); // 8969 + +	const blk = blocks_register("minecraft:purple_terracotta"); // 8970 + +	const blk = blocks_register("minecraft:blue_terracotta"); // 8971 + +	const blk = blocks_register("minecraft:brown_terracotta"); // 8972 + +	const blk = blocks_register("minecraft:green_terracotta"); // 8973 + +	const blk = blocks_register("minecraft:red_terracotta"); // 8974 + +	const blk = blocks_register("minecraft:black_terracotta"); // 8975 + +	const blk = blocks_register("minecraft:white_stained_glass_pane"); // 8976 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:orange_stained_glass_pane"); // 9008 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:magenta_stained_glass_pane"); // 9040 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:light_blue_stained_glass_pane"); // 9072 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:yellow_stained_glass_pane"); // 9104 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:lime_stained_glass_pane"); // 9136 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:pink_stained_glass_pane"); // 9168 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:gray_stained_glass_pane"); // 9200 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:light_gray_stained_glass_pane"); // 9232 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:cyan_stained_glass_pane"); // 9264 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:purple_stained_glass_pane"); // 9296 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:blue_stained_glass_pane"); // 9328 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:brown_stained_glass_pane"); // 9360 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:green_stained_glass_pane"); // 9392 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:red_stained_glass_pane"); // 9424 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:black_stained_glass_pane"); // 9456 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:acacia_stairs"); // 9488 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dark_oak_stairs"); // 9568 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mangrove_stairs"); // 9648 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bamboo_stairs"); // 9728 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bamboo_mosaic_stairs"); // 9808 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:slime_block"); // 9888 + +	const blk = blocks_register("minecraft:barrier"); // 9889 + +	const blk = blocks_register("minecraft:light"); // 9890 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_level, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:iron_trapdoor"); // 9922 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:prismarine"); // 9986 + +	const blk = blocks_register("minecraft:prismarine_bricks"); // 9987 + +	const blk = blocks_register("minecraft:dark_prismarine"); // 9988 + +	const blk = blocks_register("minecraft:prismarine_stairs"); // 9989 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:prismarine_brick_stairs"); // 10069 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dark_prismarine_stairs"); // 10149 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:prismarine_slab"); // 10229 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:prismarine_brick_slab"); // 10235 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:dark_prismarine_slab"); // 10241 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:sea_lantern"); // 10247 + +	const blk = blocks_register("minecraft:hay_block"); // 10248 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:white_carpet"); // 10251 + +	const blk = blocks_register("minecraft:orange_carpet"); // 10252 + +	const blk = blocks_register("minecraft:magenta_carpet"); // 10253 + +	const blk = blocks_register("minecraft:light_blue_carpet"); // 10254 + +	const blk = blocks_register("minecraft:yellow_carpet"); // 10255 + +	const blk = blocks_register("minecraft:lime_carpet"); // 10256 + +	const blk = blocks_register("minecraft:pink_carpet"); // 10257 + +	const blk = blocks_register("minecraft:gray_carpet"); // 10258 + +	const blk = blocks_register("minecraft:light_gray_carpet"); // 10259 + +	const blk = blocks_register("minecraft:cyan_carpet"); // 10260 + +	const blk = blocks_register("minecraft:purple_carpet"); // 10261 + +	const blk = blocks_register("minecraft:blue_carpet"); // 10262 + +	const blk = blocks_register("minecraft:brown_carpet"); // 10263 + +	const blk = blocks_register("minecraft:green_carpet"); // 10264 + +	const blk = blocks_register("minecraft:red_carpet"); // 10265 + +	const blk = blocks_register("minecraft:black_carpet"); // 10266 + +	const blk = blocks_register("minecraft:terracotta"); // 10267 + +	const blk = blocks_register("minecraft:coal_block"); // 10268 + +	const blk = blocks_register("minecraft:packed_ice"); // 10269 + +	const blk = blocks_register("minecraft:sunflower"); // 10270 +	block_addprop(blk, p_half, v_upper_lower); + +	const blk = blocks_register("minecraft:lilac"); // 10272 +	block_addprop(blk, p_half, v_upper_lower); + +	const blk = blocks_register("minecraft:rose_bush"); // 10274 +	block_addprop(blk, p_half, v_upper_lower); + +	const blk = blocks_register("minecraft:peony"); // 10276 +	block_addprop(blk, p_half, v_upper_lower); + +	const blk = blocks_register("minecraft:tall_grass"); // 10278 +	block_addprop(blk, p_half, v_upper_lower); + +	const blk = blocks_register("minecraft:large_fern"); // 10280 +	block_addprop(blk, p_half, v_upper_lower); + +	const blk = blocks_register("minecraft:white_banner"); // 10282 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:orange_banner"); // 10298 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:magenta_banner"); // 10314 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:light_blue_banner"); // 10330 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:yellow_banner"); // 10346 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:lime_banner"); // 10362 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:pink_banner"); // 10378 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:gray_banner"); // 10394 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:light_gray_banner"); // 10410 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:cyan_banner"); // 10426 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:purple_banner"); // 10442 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:blue_banner"); // 10458 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:brown_banner"); // 10474 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:green_banner"); // 10490 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:red_banner"); // 10506 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:black_banner"); // 10522 +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:white_wall_banner"); // 10538 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:orange_wall_banner"); // 10542 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:magenta_wall_banner"); // 10546 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:light_blue_wall_banner"); // 10550 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:yellow_wall_banner"); // 10554 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:lime_wall_banner"); // 10558 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:pink_wall_banner"); // 10562 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:gray_wall_banner"); // 10566 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:light_gray_wall_banner"); // 10570 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:cyan_wall_banner"); // 10574 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:purple_wall_banner"); // 10578 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:blue_wall_banner"); // 10582 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:brown_wall_banner"); // 10586 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:green_wall_banner"); // 10590 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:red_wall_banner"); // 10594 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:black_wall_banner"); // 10598 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:red_sandstone"); // 10602 + +	const blk = blocks_register("minecraft:chiseled_red_sandstone"); // 10603 + +	const blk = blocks_register("minecraft:cut_red_sandstone"); // 10604 + +	const blk = blocks_register("minecraft:red_sandstone_stairs"); // 10605 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:oak_slab"); // 10685 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:spruce_slab"); // 10691 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:birch_slab"); // 10697 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:jungle_slab"); // 10703 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:acacia_slab"); // 10709 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:dark_oak_slab"); // 10715 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:mangrove_slab"); // 10721 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:bamboo_slab"); // 10727 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:bamboo_mosaic_slab"); // 10733 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:stone_slab"); // 10739 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:smooth_stone_slab"); // 10745 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:sandstone_slab"); // 10751 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:cut_sandstone_slab"); // 10757 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:petrified_oak_slab"); // 10763 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:cobblestone_slab"); // 10769 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:brick_slab"); // 10775 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:stone_brick_slab"); // 10781 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:mud_brick_slab"); // 10787 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:nether_brick_slab"); // 10793 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:quartz_slab"); // 10799 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:red_sandstone_slab"); // 10805 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:cut_red_sandstone_slab"); // 10811 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:purpur_slab"); // 10817 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:smooth_stone"); // 10823 + +	const blk = blocks_register("minecraft:smooth_sandstone"); // 10824 + +	const blk = blocks_register("minecraft:smooth_quartz"); // 10825 + +	const blk = blocks_register("minecraft:smooth_red_sandstone"); // 10826 + +	const blk = blocks_register("minecraft:spruce_fence_gate"); // 10827 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:birch_fence_gate"); // 10859 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:jungle_fence_gate"); // 10891 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:acacia_fence_gate"); // 10923 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dark_oak_fence_gate"); // 10955 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mangrove_fence_gate"); // 10987 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bamboo_fence_gate"); // 11019 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:spruce_fence"); // 11051 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:birch_fence"); // 11083 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:jungle_fence"); // 11115 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:acacia_fence"); // 11147 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:dark_oak_fence"); // 11179 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:mangrove_fence"); // 11211 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:bamboo_fence"); // 11243 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:spruce_door"); // 11275 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:birch_door"); // 11339 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:jungle_door"); // 11403 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:acacia_door"); // 11467 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dark_oak_door"); // 11531 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mangrove_door"); // 11595 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bamboo_door"); // 11659 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:end_rod"); // 11723 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:chorus_plant"); // 11729 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); +	block_addprop(blk, p_down, v_true_false); + +	const blk = blocks_register("minecraft:chorus_flower"); // 11793 +	block_addprop(blk, p_age, v_0_1_2_3_4_5); + +	const blk = blocks_register("minecraft:purpur_block"); // 11799 + +	const blk = blocks_register("minecraft:purpur_pillar"); // 11800 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:purpur_stairs"); // 11803 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:end_stone_bricks"); // 11883 + +	const blk = blocks_register("minecraft:beetroots"); // 11884 +	block_addprop(blk, p_age, v_0_1_2_3); + +	const blk = blocks_register("minecraft:dirt_path"); // 11888 + +	const blk = blocks_register("minecraft:end_gateway"); // 11889 + +	const blk = blocks_register("minecraft:repeating_command_block"); // 11890 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); +	block_addprop(blk, p_conditional, v_true_false); + +	const blk = blocks_register("minecraft:chain_command_block"); // 11902 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); +	block_addprop(blk, p_conditional, v_true_false); + +	const blk = blocks_register("minecraft:frosted_ice"); // 11914 +	block_addprop(blk, p_age, v_0_1_2_3); + +	const blk = blocks_register("minecraft:magma_block"); // 11918 + +	const blk = blocks_register("minecraft:nether_wart_block"); // 11919 + +	const blk = blocks_register("minecraft:red_nether_bricks"); // 11920 + +	const blk = blocks_register("minecraft:bone_block"); // 11921 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:structure_void"); // 11924 + +	const blk = blocks_register("minecraft:observer"); // 11925 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:shulker_box"); // 11937 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:white_shulker_box"); // 11943 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:orange_shulker_box"); // 11949 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:magenta_shulker_box"); // 11955 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:light_blue_shulker_box"); // 11961 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:yellow_shulker_box"); // 11967 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:lime_shulker_box"); // 11973 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:pink_shulker_box"); // 11979 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:gray_shulker_box"); // 11985 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:light_gray_shulker_box"); // 11991 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:cyan_shulker_box"); // 11997 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:purple_shulker_box"); // 12003 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:blue_shulker_box"); // 12009 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:brown_shulker_box"); // 12015 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:green_shulker_box"); // 12021 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:red_shulker_box"); // 12027 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:black_shulker_box"); // 12033 +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:white_glazed_terracotta"); // 12039 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:orange_glazed_terracotta"); // 12043 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:magenta_glazed_terracotta"); // 12047 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:light_blue_glazed_terracotta"); // 12051 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:yellow_glazed_terracotta"); // 12055 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:lime_glazed_terracotta"); // 12059 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:pink_glazed_terracotta"); // 12063 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:gray_glazed_terracotta"); // 12067 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:light_gray_glazed_terracotta"); // 12071 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:cyan_glazed_terracotta"); // 12075 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:purple_glazed_terracotta"); // 12079 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:blue_glazed_terracotta"); // 12083 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:brown_glazed_terracotta"); // 12087 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:green_glazed_terracotta"); // 12091 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:red_glazed_terracotta"); // 12095 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:black_glazed_terracotta"); // 12099 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:white_concrete"); // 12103 + +	const blk = blocks_register("minecraft:orange_concrete"); // 12104 + +	const blk = blocks_register("minecraft:magenta_concrete"); // 12105 + +	const blk = blocks_register("minecraft:light_blue_concrete"); // 12106 + +	const blk = blocks_register("minecraft:yellow_concrete"); // 12107 + +	const blk = blocks_register("minecraft:lime_concrete"); // 12108 + +	const blk = blocks_register("minecraft:pink_concrete"); // 12109 + +	const blk = blocks_register("minecraft:gray_concrete"); // 12110 + +	const blk = blocks_register("minecraft:light_gray_concrete"); // 12111 + +	const blk = blocks_register("minecraft:cyan_concrete"); // 12112 + +	const blk = blocks_register("minecraft:purple_concrete"); // 12113 + +	const blk = blocks_register("minecraft:blue_concrete"); // 12114 + +	const blk = blocks_register("minecraft:brown_concrete"); // 12115 + +	const blk = blocks_register("minecraft:green_concrete"); // 12116 + +	const blk = blocks_register("minecraft:red_concrete"); // 12117 + +	const blk = blocks_register("minecraft:black_concrete"); // 12118 + +	const blk = blocks_register("minecraft:white_concrete_powder"); // 12119 + +	const blk = blocks_register("minecraft:orange_concrete_powder"); // 12120 + +	const blk = blocks_register("minecraft:magenta_concrete_powder"); // 12121 + +	const blk = blocks_register("minecraft:light_blue_concrete_powder"); // 12122 + +	const blk = blocks_register("minecraft:yellow_concrete_powder"); // 12123 + +	const blk = blocks_register("minecraft:lime_concrete_powder"); // 12124 + +	const blk = blocks_register("minecraft:pink_concrete_powder"); // 12125 + +	const blk = blocks_register("minecraft:gray_concrete_powder"); // 12126 + +	const blk = blocks_register("minecraft:light_gray_concrete_powder"); // 12127 + +	const blk = blocks_register("minecraft:cyan_concrete_powder"); // 12128 + +	const blk = blocks_register("minecraft:purple_concrete_powder"); // 12129 + +	const blk = blocks_register("minecraft:blue_concrete_powder"); // 12130 + +	const blk = blocks_register("minecraft:brown_concrete_powder"); // 12131 + +	const blk = blocks_register("minecraft:green_concrete_powder"); // 12132 + +	const blk = blocks_register("minecraft:red_concrete_powder"); // 12133 + +	const blk = blocks_register("minecraft:black_concrete_powder"); // 12134 + +	const blk = blocks_register("minecraft:kelp"); // 12135 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25); + +	const blk = blocks_register("minecraft:kelp_plant"); // 12161 + +	const blk = blocks_register("minecraft:dried_kelp_block"); // 12162 + +	const blk = blocks_register("minecraft:turtle_egg"); // 12163 +	block_addprop(blk, p_hatch, v_0_1_2); +	block_addprop(blk, p_eggs, v_1_2_3_4); + +	const blk = blocks_register("minecraft:dead_tube_coral_block"); // 12175 + +	const blk = blocks_register("minecraft:dead_brain_coral_block"); // 12176 + +	const blk = blocks_register("minecraft:dead_bubble_coral_block"); // 12177 + +	const blk = blocks_register("minecraft:dead_fire_coral_block"); // 12178 + +	const blk = blocks_register("minecraft:dead_horn_coral_block"); // 12179 + +	const blk = blocks_register("minecraft:tube_coral_block"); // 12180 + +	const blk = blocks_register("minecraft:brain_coral_block"); // 12181 + +	const blk = blocks_register("minecraft:bubble_coral_block"); // 12182 + +	const blk = blocks_register("minecraft:fire_coral_block"); // 12183 + +	const blk = blocks_register("minecraft:horn_coral_block"); // 12184 + +	const blk = blocks_register("minecraft:dead_tube_coral"); // 12185 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_brain_coral"); // 12187 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_bubble_coral"); // 12189 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_fire_coral"); // 12191 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_horn_coral"); // 12193 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:tube_coral"); // 12195 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:brain_coral"); // 12197 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:bubble_coral"); // 12199 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:fire_coral"); // 12201 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:horn_coral"); // 12203 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_tube_coral_fan"); // 12205 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_brain_coral_fan"); // 12207 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_bubble_coral_fan"); // 12209 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_fire_coral_fan"); // 12211 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_horn_coral_fan"); // 12213 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:tube_coral_fan"); // 12215 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:brain_coral_fan"); // 12217 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:bubble_coral_fan"); // 12219 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:fire_coral_fan"); // 12221 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:horn_coral_fan"); // 12223 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:dead_tube_coral_wall_fan"); // 12225 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dead_brain_coral_wall_fan"); // 12233 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dead_bubble_coral_wall_fan"); // 12241 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dead_fire_coral_wall_fan"); // 12249 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:dead_horn_coral_wall_fan"); // 12257 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:tube_coral_wall_fan"); // 12265 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:brain_coral_wall_fan"); // 12273 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bubble_coral_wall_fan"); // 12281 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:fire_coral_wall_fan"); // 12289 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:horn_coral_wall_fan"); // 12297 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:sea_pickle"); // 12305 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_pickles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:blue_ice"); // 12313 + +	const blk = blocks_register("minecraft:conduit"); // 12314 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:bamboo_sapling"); // 12316 + +	const blk = blocks_register("minecraft:bamboo"); // 12317 +	block_addprop(blk, p_stage, v_0_1); +	block_addprop(blk, p_leaves, v_none_small_large); +	block_addprop(blk, p_age, v_0_1); + +	const blk = blocks_register("minecraft:potted_bamboo"); // 12329 + +	const blk = blocks_register("minecraft:void_air"); // 12330 + +	const blk = blocks_register("minecraft:cave_air"); // 12331 + +	const blk = blocks_register("minecraft:bubble_column"); // 12332 +	block_addprop(blk, p_drag, v_true_false); + +	const blk = blocks_register("minecraft:polished_granite_stairs"); // 12334 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:smooth_red_sandstone_stairs"); // 12414 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mossy_stone_brick_stairs"); // 12494 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:polished_diorite_stairs"); // 12574 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:mossy_cobblestone_stairs"); // 12654 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:end_stone_brick_stairs"); // 12734 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:stone_stairs"); // 12814 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:smooth_sandstone_stairs"); // 12894 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:smooth_quartz_stairs"); // 12974 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:granite_stairs"); // 13054 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:andesite_stairs"); // 13134 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:red_nether_brick_stairs"); // 13214 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:polished_andesite_stairs"); // 13294 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:diorite_stairs"); // 13374 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:polished_granite_slab"); // 13454 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:smooth_red_sandstone_slab"); // 13460 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:mossy_stone_brick_slab"); // 13466 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:polished_diorite_slab"); // 13472 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:mossy_cobblestone_slab"); // 13478 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:end_stone_brick_slab"); // 13484 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:smooth_sandstone_slab"); // 13490 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:smooth_quartz_slab"); // 13496 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:granite_slab"); // 13502 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:andesite_slab"); // 13508 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:red_nether_brick_slab"); // 13514 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:polished_andesite_slab"); // 13520 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:diorite_slab"); // 13526 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:brick_wall"); // 13532 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:prismarine_wall"); // 13856 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:red_sandstone_wall"); // 14180 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:mossy_stone_brick_wall"); // 14504 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:granite_wall"); // 14828 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:stone_brick_wall"); // 15152 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:mud_brick_wall"); // 15476 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:nether_brick_wall"); // 15800 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:andesite_wall"); // 16124 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:red_nether_brick_wall"); // 16448 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:sandstone_wall"); // 16772 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:end_stone_brick_wall"); // 17096 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:diorite_wall"); // 17420 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:scaffolding"); // 17744 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_distance, v_0_1_2_3_4_5_6_7); +	block_addprop(blk, p_bottom, v_true_false); + +	const blk = blocks_register("minecraft:loom"); // 17776 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:barrel"); // 17780 +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:smoker"); // 17792 +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:blast_furnace"); // 17800 +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:cartography_table"); // 17808 + +	const blk = blocks_register("minecraft:fletching_table"); // 17809 + +	const blk = blocks_register("minecraft:grindstone"); // 17810 +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:lectern"); // 17822 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_has_book, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:smithing_table"); // 17838 + +	const blk = blocks_register("minecraft:stonecutter"); // 17839 +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:bell"); // 17843 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_attachment, v_floor_ceiling_single_wall_double_wall); + +	const blk = blocks_register("minecraft:lantern"); // 17875 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_hanging, v_true_false); + +	const blk = blocks_register("minecraft:soul_lantern"); // 17879 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_hanging, v_true_false); + +	const blk = blocks_register("minecraft:campfire"); // 17883 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_signal_fire, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:soul_campfire"); // 17915 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_signal_fire, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:sweet_berry_bush"); // 17947 +	block_addprop(blk, p_age, v_0_1_2_3); + +	const blk = blocks_register("minecraft:warped_stem"); // 17951 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_warped_stem"); // 17954 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:warped_hyphae"); // 17957 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_warped_hyphae"); // 17960 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:warped_nylium"); // 17963 + +	const blk = blocks_register("minecraft:warped_fungus"); // 17964 + +	const blk = blocks_register("minecraft:warped_wart_block"); // 17965 + +	const blk = blocks_register("minecraft:warped_roots"); // 17966 + +	const blk = blocks_register("minecraft:nether_sprouts"); // 17967 + +	const blk = blocks_register("minecraft:crimson_stem"); // 17968 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_crimson_stem"); // 17971 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:crimson_hyphae"); // 17974 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:stripped_crimson_hyphae"); // 17977 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:crimson_nylium"); // 17980 + +	const blk = blocks_register("minecraft:crimson_fungus"); // 17981 + +	const blk = blocks_register("minecraft:shroomlight"); // 17982 + +	const blk = blocks_register("minecraft:weeping_vines"); // 17983 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25); + +	const blk = blocks_register("minecraft:weeping_vines_plant"); // 18009 + +	const blk = blocks_register("minecraft:twisting_vines"); // 18010 +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25); + +	const blk = blocks_register("minecraft:twisting_vines_plant"); // 18036 + +	const blk = blocks_register("minecraft:crimson_roots"); // 18037 + +	const blk = blocks_register("minecraft:crimson_planks"); // 18038 + +	const blk = blocks_register("minecraft:warped_planks"); // 18039 + +	const blk = blocks_register("minecraft:crimson_slab"); // 18040 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:warped_slab"); // 18046 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:crimson_pressure_plate"); // 18052 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:warped_pressure_plate"); // 18054 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:crimson_fence"); // 18056 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:warped_fence"); // 18088 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); + +	const blk = blocks_register("minecraft:crimson_trapdoor"); // 18120 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:warped_trapdoor"); // 18184 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:crimson_fence_gate"); // 18248 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:warped_fence_gate"); // 18280 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_in_wall, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:crimson_stairs"); // 18312 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:warped_stairs"); // 18392 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:crimson_button"); // 18472 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:warped_button"); // 18496 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:crimson_door"); // 18520 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:warped_door"); // 18584 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_open, v_true_false); +	block_addprop(blk, p_hinge, v_left_right); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:crimson_sign"); // 18648 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:warped_sign"); // 18680 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_rotation, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:crimson_wall_sign"); // 18712 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:warped_wall_sign"); // 18720 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:structure_block"); // 18728 +	block_addprop(blk, p_mode, v_save_load_corner_data); + +	const blk = blocks_register("minecraft:jigsaw"); // 18732 +	block_addprop(blk, p_orientation, v_down_east_down_north_down_south_down_west_up_east_up_north_up_south_up_west_west_up_east_up_north_up_south_up); + +	const blk = blocks_register("minecraft:composter"); // 18744 +	block_addprop(blk, p_level, v_0_1_2_3_4_5_6_7_8); + +	const blk = blocks_register("minecraft:target"); // 18753 +	block_addprop(blk, p_power, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:bee_nest"); // 18769 +	block_addprop(blk, p_honey_level, v_0_1_2_3_4_5); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:beehive"); // 18793 +	block_addprop(blk, p_honey_level, v_0_1_2_3_4_5); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:honey_block"); // 18817 + +	const blk = blocks_register("minecraft:honeycomb_block"); // 18818 + +	const blk = blocks_register("minecraft:netherite_block"); // 18819 + +	const blk = blocks_register("minecraft:ancient_debris"); // 18820 + +	const blk = blocks_register("minecraft:crying_obsidian"); // 18821 + +	const blk = blocks_register("minecraft:respawn_anchor"); // 18822 +	block_addprop(blk, p_charges, v_0_1_2_3_4); + +	const blk = blocks_register("minecraft:potted_crimson_fungus"); // 18827 + +	const blk = blocks_register("minecraft:potted_warped_fungus"); // 18828 + +	const blk = blocks_register("minecraft:potted_crimson_roots"); // 18829 + +	const blk = blocks_register("minecraft:potted_warped_roots"); // 18830 + +	const blk = blocks_register("minecraft:lodestone"); // 18831 + +	const blk = blocks_register("minecraft:blackstone"); // 18832 + +	const blk = blocks_register("minecraft:blackstone_stairs"); // 18833 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:blackstone_wall"); // 18913 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:blackstone_slab"); // 19237 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:polished_blackstone"); // 19243 + +	const blk = blocks_register("minecraft:polished_blackstone_bricks"); // 19244 + +	const blk = blocks_register("minecraft:cracked_polished_blackstone_bricks"); // 19245 + +	const blk = blocks_register("minecraft:chiseled_polished_blackstone"); // 19246 + +	const blk = blocks_register("minecraft:polished_blackstone_brick_slab"); // 19247 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:polished_blackstone_brick_stairs"); // 19253 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:polished_blackstone_brick_wall"); // 19333 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:gilded_blackstone"); // 19657 + +	const blk = blocks_register("minecraft:polished_blackstone_stairs"); // 19658 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:polished_blackstone_slab"); // 19738 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:polished_blackstone_pressure_plate"); // 19744 +	block_addprop(blk, p_powered, v_true_false); + +	const blk = blocks_register("minecraft:polished_blackstone_button"); // 19746 +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); +	block_addprop(blk, p_face, v_floor_wall_ceiling); + +	const blk = blocks_register("minecraft:polished_blackstone_wall"); // 19770 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:chiseled_nether_bricks"); // 20094 + +	const blk = blocks_register("minecraft:cracked_nether_bricks"); // 20095 + +	const blk = blocks_register("minecraft:quartz_bricks"); // 20096 + +	const blk = blocks_register("minecraft:candle"); // 20097 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:white_candle"); // 20113 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:orange_candle"); // 20129 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:magenta_candle"); // 20145 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:light_blue_candle"); // 20161 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:yellow_candle"); // 20177 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:lime_candle"); // 20193 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:pink_candle"); // 20209 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:gray_candle"); // 20225 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:light_gray_candle"); // 20241 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:cyan_candle"); // 20257 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:purple_candle"); // 20273 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:blue_candle"); // 20289 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:brown_candle"); // 20305 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:green_candle"); // 20321 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:red_candle"); // 20337 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:black_candle"); // 20353 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_lit, v_true_false); +	block_addprop(blk, p_candles, v_1_2_3_4); + +	const blk = blocks_register("minecraft:candle_cake"); // 20369 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:white_candle_cake"); // 20371 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:orange_candle_cake"); // 20373 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:magenta_candle_cake"); // 20375 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:light_blue_candle_cake"); // 20377 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:yellow_candle_cake"); // 20379 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:lime_candle_cake"); // 20381 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:pink_candle_cake"); // 20383 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:gray_candle_cake"); // 20385 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:light_gray_candle_cake"); // 20387 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:cyan_candle_cake"); // 20389 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:purple_candle_cake"); // 20391 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:blue_candle_cake"); // 20393 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:brown_candle_cake"); // 20395 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:green_candle_cake"); // 20397 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:red_candle_cake"); // 20399 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:black_candle_cake"); // 20401 +	block_addprop(blk, p_lit, v_true_false); + +	const blk = blocks_register("minecraft:amethyst_block"); // 20403 + +	const blk = blocks_register("minecraft:budding_amethyst"); // 20404 + +	const blk = blocks_register("minecraft:amethyst_cluster"); // 20405 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:large_amethyst_bud"); // 20417 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:medium_amethyst_bud"); // 20429 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:small_amethyst_bud"); // 20441 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:tuff"); // 20453 + +	const blk = blocks_register("minecraft:calcite"); // 20454 + +	const blk = blocks_register("minecraft:tinted_glass"); // 20455 + +	const blk = blocks_register("minecraft:powder_snow"); // 20456 + +	const blk = blocks_register("minecraft:sculk_sensor"); // 20457 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_sculk_sensor_phase, v_inactive_active_cooldown); +	block_addprop(blk, p_power, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15); + +	const blk = blocks_register("minecraft:sculk"); // 20553 + +	const blk = blocks_register("minecraft:sculk_vein"); // 20554 +	block_addprop(blk, p_west, v_true_false); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_true_false); +	block_addprop(blk, p_north, v_true_false); +	block_addprop(blk, p_east, v_true_false); +	block_addprop(blk, p_down, v_true_false); + +	const blk = blocks_register("minecraft:sculk_catalyst"); // 20682 +	block_addprop(blk, p_bloom, v_true_false); + +	const blk = blocks_register("minecraft:sculk_shrieker"); // 20684 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shrieking, v_true_false); +	block_addprop(blk, p_can_summon, v_true_false); + +	const blk = blocks_register("minecraft:oxidized_copper"); // 20692 + +	const blk = blocks_register("minecraft:weathered_copper"); // 20693 + +	const blk = blocks_register("minecraft:exposed_copper"); // 20694 + +	const blk = blocks_register("minecraft:copper_block"); // 20695 + +	const blk = blocks_register("minecraft:copper_ore"); // 20696 + +	const blk = blocks_register("minecraft:deepslate_copper_ore"); // 20697 + +	const blk = blocks_register("minecraft:oxidized_cut_copper"); // 20698 + +	const blk = blocks_register("minecraft:weathered_cut_copper"); // 20699 + +	const blk = blocks_register("minecraft:exposed_cut_copper"); // 20700 + +	const blk = blocks_register("minecraft:cut_copper"); // 20701 + +	const blk = blocks_register("minecraft:oxidized_cut_copper_stairs"); // 20702 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:weathered_cut_copper_stairs"); // 20782 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:exposed_cut_copper_stairs"); // 20862 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:cut_copper_stairs"); // 20942 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:oxidized_cut_copper_slab"); // 21022 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:weathered_cut_copper_slab"); // 21028 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:exposed_cut_copper_slab"); // 21034 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:cut_copper_slab"); // 21040 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:waxed_copper_block"); // 21046 + +	const blk = blocks_register("minecraft:waxed_weathered_copper"); // 21047 + +	const blk = blocks_register("minecraft:waxed_exposed_copper"); // 21048 + +	const blk = blocks_register("minecraft:waxed_oxidized_copper"); // 21049 + +	const blk = blocks_register("minecraft:waxed_oxidized_cut_copper"); // 21050 + +	const blk = blocks_register("minecraft:waxed_weathered_cut_copper"); // 21051 + +	const blk = blocks_register("minecraft:waxed_exposed_cut_copper"); // 21052 + +	const blk = blocks_register("minecraft:waxed_cut_copper"); // 21053 + +	const blk = blocks_register("minecraft:waxed_oxidized_cut_copper_stairs"); // 21054 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:waxed_weathered_cut_copper_stairs"); // 21134 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:waxed_exposed_cut_copper_stairs"); // 21214 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:waxed_cut_copper_stairs"); // 21294 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:waxed_oxidized_cut_copper_slab"); // 21374 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:waxed_weathered_cut_copper_slab"); // 21380 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:waxed_exposed_cut_copper_slab"); // 21386 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:waxed_cut_copper_slab"); // 21392 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:lightning_rod"); // 21398 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_powered, v_true_false); +	block_addprop(blk, p_facing, v_north_east_south_west_up_down); + +	const blk = blocks_register("minecraft:pointed_dripstone"); // 21422 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_vertical_direction, v_up_down); +	block_addprop(blk, p_thickness, v_tip_merge_tip_frustum_middle_base); + +	const blk = blocks_register("minecraft:dripstone_block"); // 21442 + +	const blk = blocks_register("minecraft:cave_vines"); // 21443 +	block_addprop(blk, p_berries, v_true_false); +	block_addprop(blk, p_age, v_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25); + +	const blk = blocks_register("minecraft:cave_vines_plant"); // 21495 +	block_addprop(blk, p_berries, v_true_false); + +	const blk = blocks_register("minecraft:spore_blossom"); // 21497 + +	const blk = blocks_register("minecraft:azalea"); // 21498 + +	const blk = blocks_register("minecraft:flowering_azalea"); // 21499 + +	const blk = blocks_register("minecraft:moss_carpet"); // 21500 + +	const blk = blocks_register("minecraft:moss_block"); // 21501 + +	const blk = blocks_register("minecraft:big_dripleaf"); // 21502 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_tilt, v_none_unstable_partial_full); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:big_dripleaf_stem"); // 21534 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:small_dripleaf"); // 21542 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_half, v_upper_lower); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:hanging_roots"); // 21558 +	block_addprop(blk, p_waterlogged, v_true_false); + +	const blk = blocks_register("minecraft:rooted_dirt"); // 21560 + +	const blk = blocks_register("minecraft:mud"); // 21561 + +	const blk = blocks_register("minecraft:deepslate"); // 21562 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:cobbled_deepslate"); // 21565 + +	const blk = blocks_register("minecraft:cobbled_deepslate_stairs"); // 21566 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:cobbled_deepslate_slab"); // 21646 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:cobbled_deepslate_wall"); // 21652 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:polished_deepslate"); // 21976 + +	const blk = blocks_register("minecraft:polished_deepslate_stairs"); // 21977 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:polished_deepslate_slab"); // 22057 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:polished_deepslate_wall"); // 22063 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:deepslate_tiles"); // 22387 + +	const blk = blocks_register("minecraft:deepslate_tile_stairs"); // 22388 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:deepslate_tile_slab"); // 22468 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:deepslate_tile_wall"); // 22474 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:deepslate_bricks"); // 22798 + +	const blk = blocks_register("minecraft:deepslate_brick_stairs"); // 22799 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_shape, v_straight_inner_left_inner_right_outer_left_outer_right); +	block_addprop(blk, p_half, v_top_bottom); +	block_addprop(blk, p_facing, v_north_south_west_east); + +	const blk = blocks_register("minecraft:deepslate_brick_slab"); // 22879 +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_type, v_top_bottom_double); + +	const blk = blocks_register("minecraft:deepslate_brick_wall"); // 22885 +	block_addprop(blk, p_west, v_none_low_tall); +	block_addprop(blk, p_waterlogged, v_true_false); +	block_addprop(blk, p_up, v_true_false); +	block_addprop(blk, p_south, v_none_low_tall); +	block_addprop(blk, p_north, v_none_low_tall); +	block_addprop(blk, p_east, v_none_low_tall); + +	const blk = blocks_register("minecraft:chiseled_deepslate"); // 23209 + +	const blk = blocks_register("minecraft:cracked_deepslate_bricks"); // 23210 + +	const blk = blocks_register("minecraft:cracked_deepslate_tiles"); // 23211 + +	const blk = blocks_register("minecraft:infested_deepslate"); // 23212 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:smooth_basalt"); // 23215 + +	const blk = blocks_register("minecraft:raw_iron_block"); // 23216 + +	const blk = blocks_register("minecraft:raw_copper_block"); // 23217 + +	const blk = blocks_register("minecraft:raw_gold_block"); // 23218 + +	const blk = blocks_register("minecraft:potted_azalea_bush"); // 23219 + +	const blk = blocks_register("minecraft:potted_flowering_azalea_bush"); // 23220 + +	const blk = blocks_register("minecraft:ochre_froglight"); // 23221 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:verdant_froglight"); // 23224 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:pearlescent_froglight"); // 23227 +	block_addprop(blk, p_axis, v_x_y_z); + +	const blk = blocks_register("minecraft:frogspawn"); // 23230 + +	const blk = blocks_register("minecraft:reinforced_deepslate"); // 23231 +}; diff --git a/control.ha b/control.ha new file mode 100644 index 0000000..ee1f22d --- /dev/null +++ b/control.ha @@ -0,0 +1,71 @@ +use sdl2::*; + +type ControlKey = struct { +	key: Key, +	pressed: bool, +}; + +let CONTROL_KEY_FORWARD = ControlKey { key = KEY_W, ... }; +let CONTROL_KEY_BACKWARD = ControlKey { key = KEY_S, ... }; +let CONTROL_KEY_LEFT = ControlKey { key = KEY_A, ... }; +let CONTROL_KEY_RIGHT = ControlKey { key = KEY_D, ... }; +let CONTROL_KEY_JUMP = ControlKey { key = KEY_SPACE, ... }; +let CONTROL_KEY_SNEAK = ControlKey { key = KEY_LSHIFT, ... }; + +const CONTROL_KEYS = [ +	&CONTROL_KEY_FORWARD, +	&CONTROL_KEY_BACKWARD, +	&CONTROL_KEY_LEFT, +	&CONTROL_KEY_RIGHT, +	&CONTROL_KEY_JUMP, +	&CONTROL_KEY_SNEAK, +]; + +fn control_input(event: InputEvent) void = { +	match (event) { +	case CancelEvent => +		for (let i = 0z; i < len(CONTROL_KEYS); i += 1) { +			CONTROL_KEYS[i].pressed = false; +		}; +	case let event: KeyEvent => +		const pressed = switch (event.status) { +		case ButtonStatus::DOWN, ButtonStatus::HELD => +			yield true; +		case ButtonStatus::UP => +			yield false; +		}; +		for (let i = 0z; i < len(CONTROL_KEYS); i += 1) { +			if (CONTROL_KEYS[i].key == event.key) { +				CONTROL_KEYS[i].pressed = pressed; +			}; +		}; +	case => void; +	}; +}; + +type Control = struct { +	yaw: f32, +	pitch: f32, +	walk: f32, +	strafe: f32, +	jump: bool, +	sneak: bool, +}; + +def MOUSE_SENSITIVITY = 0.115f32; + +fn control_frame() void = { +	let mx = 0, my = 0; +	SDL_GetRelativeMouseState(&mx, &my); + +	player_control(&Control { +		yaw = mx: f32 * MOUSE_SENSITIVITY, +		pitch = my: f32 * MOUSE_SENSITIVITY, +		walk = (if (CONTROL_KEY_FORWARD.pressed) 1.0f32 else 0.0f32) +			- (if (CONTROL_KEY_BACKWARD.pressed) 1.0f32 else 0.0f32), +		strafe = (if (CONTROL_KEY_LEFT.pressed) 1.0f32 else 0.0f32) +			- (if (CONTROL_KEY_RIGHT.pressed) 1.0f32 else 0.0f32), +		jump = CONTROL_KEY_JUMP.pressed, +		sneak = CONTROL_KEY_SNEAK.pressed, +	}); +}; diff --git a/death.ha b/death.ha new file mode 100644 index 0000000..a446a26 --- /dev/null +++ b/death.ha @@ -0,0 +1,163 @@ +use glm; +use mcproto; +use strings; +use time; + +def DEATH_RESPAWN_DELAY = time::SECOND; + +let DEATH_SHOWN = false; +let DEATH_MESSAGE = ""; +let DEATH_SHOWN_SINCE = time::instant { ... }; +let DEATH_CAN_RESPAWN = false; +let DEATH_RESPAWNING = false; + +fn death_show(message: str) void = { +	death_close(); + +	DEATH_SHOWN = true; +	DEATH_MESSAGE = strings::dup(message); +	DEATH_SHOWN_SINCE = frame_timestamp(); +}; + +fn death_close() void = { +	DEATH_SHOWN = false; +	free(DEATH_MESSAGE); +	DEATH_MESSAGE = ""; +	DEATH_SHOWN_SINCE = time::instant { ... }; +	DEATH_CAN_RESPAWN = false; +	DEATH_RESPAWNING = false; +}; + +fn death_frame() void = { +	if (!DEATH_SHOWN && PLAYER_HEALTH <= 0.0) { +		death_show(""); +	}; + +	if (!DEATH_SHOWN) { +		return; +	}; + +	if (!DEATH_CAN_RESPAWN && !DEATH_RESPAWNING) { +		const t = time::diff(DEATH_SHOWN_SINCE, frame_timestamp()); +		if (t > DEATH_RESPAWN_DELAY) { +			DEATH_CAN_RESPAWN = true; +		}; +	}; +}; + +fn death_respawn() void = { +	DEATH_RESPAWNING = true; +	DEATH_CAN_RESPAWN = false; + +	let out: []u8 = []; +	defer free(out); +	mcproto::encode_varint(&out, 0); +	network_send(0x06, out); +}; + +const LAYER_DEATH = Layer { +	blocks_input = &layer_death_blocks_input, +	input = &layer_death_input, +	is_opaque = &layer_death_is_opaque, +	render = &layer_death_render, +}; + +fn layer_death_blocks_input() bool = { +	return DEATH_SHOWN; +}; + +fn layer_death_input(event: InputEvent) bool = { +	if (!DEATH_SHOWN) { +		return false; +	}; + +	match (event) { +	case let event: KeyEvent => +		switch (event.key) { +		case KEY_SPACE => +			if (event.status == ButtonStatus::DOWN +					&& DEATH_CAN_RESPAWN) { +				death_respawn(); +			}; +		case => void; +		}; +	case => void; +	}; + +	return true; +}; + +fn layer_death_is_opaque() bool = { +	return false; +}; + +fn layer_death_render() void = { +	if (!DEATH_SHOWN) { +		return; +	}; + +	let (width, height) = drawable_size(); +	let gui_width = width / gui_scale(); +	let gui_height = height / gui_scale(); + +	const font = fonts_find("minecraft:default") as *Font; + +	const text = "You died!"; +	const metrics = font_measure(font, text); +	let text_trans = glm::m4_new_ident(); +	glm::translate(&text_trans, &[ +		-metrics.width / 2.0, +		0.0, +		0.0]); +	glm::scale(&text_trans, &[2.0f32, 2.0, 1.0]); +	glm::translate(&text_trans, &[ +		gui_width: f32 / 2.0, +		60.0, +		0.0]); +	const text_trans = glm::m4_mul(gui_proj(), &text_trans); +	render_text_shadow(text, font, &text_trans, [255...]); + +	const text = DEATH_MESSAGE; +	const metrics = font_measure(font, text); +	let text_trans = glm::m4_new_ident(); +	glm::translate(&text_trans, &[ +		(gui_width: f32 - metrics.width) / 2.0, +		85.0, +		0.0]); +	const text_trans = glm::m4_mul(gui_proj(), &text_trans); +	render_text_shadow(text, font, &text_trans, [255...]); + +	const text = "Score: blah"; +	const metrics = font_measure(font, text); +	let text_trans = glm::m4_new_ident(); +	glm::translate(&text_trans, &[ +		(gui_width: f32 - metrics.width) / 2.0, +		100.0, +		0.0]); +	const text_trans = glm::m4_mul(gui_proj(), &text_trans); +	render_text_shadow(text, font, &text_trans, [255...]); + +	if (DEATH_CAN_RESPAWN) { +		const text = "Press SPACE to respawn"; +		const metrics = font_measure(font, text); +		let text_trans = glm::m4_new_ident(); +		glm::translate(&text_trans, &[ +			(gui_width: f32 - metrics.width) / 2.0, +			gui_height: f32 / 4.0 + 72.0, +			0.0]); +		const text_trans = glm::m4_mul(gui_proj(), &text_trans); +		render_text_shadow(text, font, &text_trans, [255...]); +	}; + +	if (DEATH_RESPAWNING) { +		const text = "Respawning..."; +		const metrics = font_measure(font, text); +		let text_trans = glm::m4_new_ident(); +		glm::translate(&text_trans, &[ +			(gui_width: f32 - metrics.width) / 2.0, +			gui_height: f32 / 4.0 + 72.0, +			0.0]); +		const text_trans = glm::m4_mul(gui_proj(), &text_trans); +		render_text_shadow(text, font, &text_trans, [255...]); +	}; +}; diff --git a/dejson/dejson.ha b/dejson/dejson.ha new file mode 100644 index 0000000..74e2752 --- /dev/null +++ b/dejson/dejson.ha @@ -0,0 +1,286 @@ +use ascii; +use encoding::json; +use fmt; +use io; +use math; +use memio; +use strings; +use types; + +export type deser = struct { +	val: *json::value, +	link: ((*deser, (str | size)) | void), +}; + +export type error = !str; + +export fn newdeser(val: *json::value) deser = +	deser { val = val, link = void }; + +export fn fail(de: *deser, fmt: str, args: fmt::field...) error = { +	let path: [](str | size) = []; +	defer free(path); +	for (let de_ = de; true) match (de_.link) { +	case let link: (*deser, (str | size)) => +		append(path, link.1); +		de_ = link.0; +	case void => break; +	}; + +	let err = memio::dynamic(); + +	if (len(path) == 0 || !(path[len(path) - 1] is str)) { +		memio::concat(&err, ".")!; +	}; +	for (let i = len(path); i > 0) { +		i -= 1; +		match (path[i]) { +		case let s: str => +			memio::concat(&err, ".")!; +			printfield(&err, s)!; +		case let n: size => +			fmt::fprintf(&err, "[{}]", n)!; +		}; +	}; + +	memio::concat(&err, ": ")!; +	fmt::fprintf(&err, fmt, args...)!; + +	return memio::string(&err)!; +}; + +export fn printfield(out: io::handle, s: str) (void | io::error) = { +	let valid = true; +	let first = true; +	let it = strings::iter(s); +	for (true) match (strings::next(&it)) { +	case let ch: rune => +		if (!ascii::isalpha(ch) && ch != '_' +				&& (first || !ascii::isdigit(ch))) { +			json::dump(out, s)?; +			return; +		}; +		first = false; +	case done => break; +	}; +	memio::concat(out, s)?; +	return; +}; + +export fn strfield(s: str) str = { +	let out = memio::dynamic(); +	printfield(&out, s)!; +	return memio::string(&out)!; +}; + +export fn typename(val: *json::value) str = { +	match (*val) { +	case f64 => +		return "number"; +	case str => +		return "string"; +	case bool => +		return "boolean"; +	case json::_null => +		return "null"; +	case []json::value => +		return "array"; +	case json::object => +		return "object"; +	}; +}; + +export fn optfield(de: *deser, name: str) (deser | void | error) = { +	const obj = object(de)?; +	match (json::get(obj, name)) { +	case let val: *json::value => +		return deser { +			val = val, +			link = (de, name), +		}; +	case void => void; +	}; +}; + +export fn field(de: *deser, name: str) (deser | error) = { +	match (optfield(de, name)) { +	case let de_field: deser => +		return de_field; +	case void => +		let fieldname = strfield(name); +		defer free(fieldname); +		return fail(de, "Field {} is required but missing", fieldname); +	}; +}; + +export fn index(de: *deser, i: size) (deser | error) = { +	const arr = array(de)?; +	if (i < len(arr)) { +		return deser { +			val = &arr[i], +			link = (de, i), +		}; +	} else { +		return fail(de, "Array index {} is required but missing", i); +	}; +}; + +export fn length(de: *deser) (size | error) = +	len(array(de)?); + +export fn assert_length(de: *deser, n: size) (void | error) = { +	if (length(de)? != n) +		return fail(de, "Array has {} elements, {} expected", +			length(de)?, n); +}; + +export fn count(de: *deser) (size | error) = +	json::count(object(de)?); + +export fn assert_fields(de: *deser, names: str...) (void | error) = { +	const obj = object(de)?; +	let err = memio::dynamic(); +	defer io::close(&err)!; +	let n = 0z; +	let it = json::iter(obj); +	for :fields (true) { +		match (json::next(&it)) { +		case let entry: (const str, const *json::value) => +			for (let i = 0z; i < len(names); i += 1) { +				if (entry.0 == names[i]) { +					continue :fields; +				}; +			}; +			if (n != 0) { +				memio::concat(&err, ", ")!; +			}; +			printfield(&err, entry.0)!; +			n += 1; +		case void => break; +		}; +	}; +	switch (n) { +	case 0 => +		return; +	case 1 => +		return fail(de, "Unknown field {}", memio::string(&err)!); +	case => +		return fail(de, "Unknown fields {}", memio::string(&err)!); +	}; +}; + +export type iterator = struct { +	iter: json::iterator, +	deser: *deser, +}; + +export fn iter(de: *deser) (iterator | error) = { +	const obj = object(de)?; +	return iterator { +		iter = json::iter(obj), +		deser = de, +	}; +}; + +export fn next(it: *iterator) ((str, deser) | void) = { +	match (json::next(&it.iter)) { +	case let entry: (const str, const *json::value) => +		return (entry.0, deser { +			val = entry.1, +			link = (it.deser, entry.0), +		}); +	case void => void; +	}; +}; + +export fn object(de: *deser) (*json::object | error) = { +	if (*de.val is json::object) { +		return &(de.val: *struct { t: int, val: json::object }).val; +	} else { +		return fail(de, "Expected object, found {}", typename(de.val)); +	}; +}; + +export fn array(de: *deser) ([]json::value | error) = { +	match (*de.val) { +	case let val: []json::value => +		return val; +	case => +		return fail(de, "Expected array, found {}", typename(de.val)); +	}; +}; + +export fn string(de: *deser) (str | error) = { +	match (*de.val) { +	case let val: str => +		return val; +	case => +		return fail(de, "Expected string, found {}", typename(de.val)); +	}; +}; + +export fn boolean(de: *deser) (bool | error) = { +	match (*de.val) { +	case let val: bool => +		return val; +	case => +		return fail(de, "Expected boolean, found {}", typename(de.val)); +	}; +}; + +export fn number(de: *deser) (f64 | error) = { +	match (*de.val) { +	case let val: f64 => +		return val; +	case => +		return fail(de, "Expected number, found {}", typename(de.val)); +	}; +}; + +export fn number_frange(de: *deser, a: f64, b: f64) (f64 | error) = { +	const val = number(de)?; +	if (val < a || val > b) +		return fail(de, "Number {} is outside the allowed range [{},{}]", +			val, a, b); +	return val; +}; + +export fn number_irange(de: *deser, a: i64, b: i64) (i64 | error) = { +	const val = number(de)?; +	if (math::absf64(val) > 9007199254740991.0) +		return fail(de, +			"Number {} is too large to be safely converted from f64 to an integer", +			val); +	const (ival, frac) = math::modfracf64(val); +	if (frac != 0.0) +		return fail(de, "Number {} is not an integer", val); +	const ival = ival: i64; +	if (ival < a || ival > b) +		return fail(de, "Number {} is outside the allowed range [{},{}]", +			val, a, b); +	return ival; +}; + +export fn number_u8(de: *deser) (u8 | error) = +	number_irange(de, 0, types::U8_MAX: i64)?: u8; + +export fn number_u16(de: *deser) (u16 | error) = +	number_irange(de, 0, types::U16_MAX: i64)?: u16; + +export fn number_u32(de: *deser) (u32 | error) = +	number_irange(de, 0, types::U32_MAX: i64)?: u32; + +export fn number_u64(de: *deser) (u64 | error) = +	number_irange(de, 0, types::I64_MAX)?: u64; + +export fn number_i8(de: *deser) (i8 | error) = +	number_irange(de, types::I8_MIN, types::I8_MAX)?: i8; + +export fn number_i16(de: *deser) (i16 | error) = +	number_irange(de, types::I16_MIN, types::I16_MAX)?: i16; + +export fn number_i32(de: *deser) (i32 | error) = +	number_irange(de, types::I32_MIN, types::I32_MAX)?: i32; + +export fn number_i64(de: *deser) (i64 | error) = +	number_irange(de, types::I64_MIN, types::I64_MAX); diff --git a/encoding/json/+test/lexer.ha b/encoding/json/+test/lexer.ha new file mode 100644 index 0000000..b4c098e --- /dev/null +++ b/encoding/json/+test/lexer.ha @@ -0,0 +1,62 @@ +use io; +use memio; +use strings; + +@test fn lex() void = { +	const cases: [_](str, []token) = [ +		("true", [true]), +		("false", [false]), +		("null", [_null]), +		("1234", [1234.0]), +		("12.34", [12.34]), +		("12.34e5", [12.34e5]), +		("12.34E5", [12.34e5]), +		("12.34e+5", [12.34e5]), +		("12.34e-5", [12.34e-5]), +		("12e5", [12.0e5]), +		("-1234", [-1234.0]), +		(`"hello world"`, ["hello world"]), +		(`"\"\\\/\b\f\n\r\t\u0020"`, ["\"\\/\b\f\n\r\t\u0020"]), +		("[ null, null ]", [arraystart, _null, comma, _null, arrayend]), +	]; + +	for (let i = 0z; i < len(cases); i += 1) { +		const src = strings::toutf8(cases[i].0); +		const src = memio::fixed(src); +		const lexer = newlexer(&src); +		defer close(&lexer); + +		for (let j = 0z; j < len(cases[i].1); j += 1) { +			const want = cases[i].1[j]; +			const have = lex(&lexer)! as token; +			assert(tokeq(want, have)); +		}; + +		assert(lex(&lexer) is io::EOF); +	}; +}; + +fn tokeq(want: token, have: token) bool = { +	match (want) { +	case _null => +		return have is _null; +	case comma => +		return have is comma; +	case colon => +		return have is colon; +	case arraystart => +		return have is arraystart; +	case arrayend => +		return have is arrayend; +	case objstart => +		return have is objstart; +	case objend => +		return have is objend; +	case let b: bool => +		return have as bool == b; +	case let f: f64 => +		return have as f64 == f; +	case let s: str => +		return have as str == s; +	}; +}; diff --git a/encoding/json/+test/test_load.ha b/encoding/json/+test/test_load.ha new file mode 100644 index 0000000..bf53777 --- /dev/null +++ b/encoding/json/+test/test_load.ha @@ -0,0 +1,164 @@ +use fmt; + +fn roundtrip(input: str, expected: value) void = { +	const val = loadstr(input)!; +	defer finish(val); +	assert(equal(val, expected)); +	const s = dumpstr(val); +	defer free(s); +	const val = loadstr(s)!; +	defer finish(val); +	assert(equal(val, expected)); +}; + +fn errassert(input: str, expected_loc: (uint, uint)) void = { +	const loc = loadstr(input) as invalid; +	if (loc.0 != expected_loc.0 || loc.1 != expected_loc.1) { +		fmt::errorfln("=== JSON:\n{}", input)!; +		fmt::errorfln("=== expected error location:\n({}, {})", +			expected_loc.0, expected_loc.1)!; +		fmt::errorfln("=== actual error location:\n({}, {})", +			loc.0, loc.1)!; +		abort(); +	}; +}; + +@test fn load() void = { +	let obj = newobject(); +	defer finish(obj); +	let obj2 = newobject(); +	defer finish(obj2); + +	roundtrip(`1234`, 1234.0); +	roundtrip(`[]`, []); +	roundtrip(`[1, 2, 3, null]`, [1.0, 2.0, 3.0, _null]); +	roundtrip(`{}`, obj); +	set(&obj, "hello", "world"); +	set(&obj, "answer", 42.0); +	roundtrip(`{ "hello": "world", "answer": 42 }`, obj); +	reset(&obj); +	roundtrip(`[[]   ]`, [[]]); +	roundtrip(`[""]`, [""]); +	roundtrip(`["a"]`, ["a"]); +	roundtrip(`[false]`, [false]); +	roundtrip(`[null, 1, "1", {}]`, [_null, 1.0, "1", obj]); +	roundtrip(`[null]`, [_null]); +	roundtrip("[1\n]", [1.0]); +	roundtrip(`[1,null,null,null,2]`, [1.0, _null, _null, _null, 2.0]); +	set(&obj, "", 0.0); +	roundtrip(`{"":0}`, obj); +	reset(&obj); +	set(&obj, "foo\0bar", 42.0); +	roundtrip(`{"foo\u0000bar": 42}`, obj); +	reset(&obj); +	set(&obj, "min", -1.0e+28); +	set(&obj, "max", 1.0e+28); +	roundtrip(`{"min": -1.0e+28, "max": 1.0e+28}`, obj); +	reset(&obj); +	set(&obj, "id", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); +	set(&obj2, "id", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); +	set(&obj, "x", [obj2]); +	roundtrip(`{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}`, obj); +	reset(&obj); +	reset(&obj2); +	set(&obj, "a", []); +	roundtrip(`{"a":[]}`, obj); +	roundtrip("{\n" `"a": []` "\n}", obj); +	reset(&obj); +	roundtrip(`"\u0060\u012a\u12AB"`, "\u0060\u012a\u12AB"); +	roundtrip(`"\"\\\/\b\f\n\r\t"`, "\"\\/\b\f\n\r\t"); +	roundtrip(`"\\u0000"`, `\u0000`); +	roundtrip(`"\""`, `"`); +	roundtrip(`"a/*b*/c/*d//e"`, "a/*b*/c/*d//e"); +	roundtrip(`"\\a"`, `\a`); +	roundtrip(`"\\n"`, `\n`); +	roundtrip(`"\u0012"`, "\u0012"); +	roundtrip(`[ "asd"]`, ["asd"]); +	roundtrip(`"new\u000Aline"`, "new\nline"); +	roundtrip(`"\u0000"`, "\0"); +	roundtrip(`"\u002c"`, "\u002c"); +	roundtrip(`"asd "`, "asd "); +	roundtrip(`" "`, " "); +	roundtrip(`"\u0821"`, "\u0821"); +	roundtrip(`"\u0123"`, "\u0123"); +	roundtrip(`"\u0061\u30af\u30EA\u30b9"`, "\u0061\u30af\u30EA\u30b9"); +	roundtrip(`"\uA66D"`, "\uA66D"); +	roundtrip(`"\u005C"`, `\`); +	roundtrip(`"\u0022"`, `"`); +	roundtrip(`""`, ""); +	roundtrip(` [] `, []); + +	errassert(`[1,,]`, (1, 4)); +	errassert(`[1 true]`, (1, 7)); +	errassert(`["": 1]`, (1, 4)); +	errassert(`[,1]`, (1, 2)); +	errassert(`[1,,2]`, (1, 4)); +	errassert(`["",]`, (1, 5)); +	errassert(`["x"`, (1, 5)); +	errassert(`[x`, (1, 2)); +	errassert(`[3[4]]`, (1, 3)); +	errassert(`[1:2]`, (1, 3)); +	errassert(`[,]`, (1, 2)); +	errassert(`[-]`, (1, 3)); +	errassert(`[   , ""]`, (1, 5)); +	errassert("[\"a\",\n4\n,1,", (3, 4)); +	errassert(`[1,]`, (1, 4)); +	errassert("[\"\va\"\\f", (1, 3)); +	errassert(`[*]`, (1, 2)); +	errassert(`[1,`, (1, 4)); +	errassert("[1,\n1\n,1", (3, 3)); +	errassert(`[{}`, (1, 4)); +	errassert(`["x", truth]`, (1, 11)); +	errassert(`{[: "x"}`, (1, 2)); +	errassert(`{"x", null}`, (1, 5)); +	errassert(`{"x"::"b"}`, (1, 6)); +	errassert(`{"a":"a" 123}`, (1, 12)); +	errassert(`{"a" b}`, (1, 6)); +	errassert(`{:"b"}`, (1, 2)); +	errassert(`{"a" "b"}`, (1, 8)); +	errassert(`{"a":`, (1, 6)); +	errassert(`{"a"`, (1, 5)); +	errassert(`{1:1}`, (1, 2)); +	errassert(`{9999E9999:1}`, (1, 10)); +	errassert(`{null:null,null:null}`, (1, 5)); +	errassert(`{"id":0,,,,,}`, (1, 9)); +	errassert(`{'a':0}`, (1, 2)); +	errassert(`{"id":0,}`, (1, 9)); +	errassert(`{"a":"b",,"c":"d"}`, (1, 10)); +	errassert(`{true: false}`, (1, 5)); +	errassert(`{"a":"a`, (1, 8)); +	errassert(`{ "foo" : "bar", "a" }`, (1, 22)); +	errassert(` `, (1, 2)); +	errassert(`<null>`, (1, 1)); +	errassert(`["asd]`, (1, 7)); +	errassert(`True`, (1, 4)); +	errassert(`]`, (1, 1)); +	errassert(`}`, (1, 1)); +	errassert(`{"x": true,`, (1, 12)); +	errassert(`[`, (1, 2)); +	errassert(`{`, (1, 2)); +	errassert(``, (1, 1)); +	errassert("\0", (1, 1)); +	errassert(`{"":`, (1, 5)); +	errassert(`['`, (1, 2)); +	errassert(`["`, (1, 3)); +	errassert(`[,`, (1, 2)); +	errassert(`[{`, (1, 3)); +	errassert(`{[`, (1, 2)); +	errassert(`{]`, (1, 2)); +	errassert(`[}`, (1, 2)); +	errassert(`{'`, (1, 2)); +	errassert(`{"`, (1, 3)); +	errassert(`{,`, (1, 2)); +	errassert(`["\{["\{["\{["\{`, (1, 4)); +	errassert(`*`, (1, 1)); +	errassert(`\u000A""`, (1, 1)); +	errassert("\f", (1, 1)); +}; + +@test fn nestlimit() void = { +	const s = `{ "foo": [[[{"bar": ["baz"]}]]] }`; +	const val = loadstr(s, 6: nestlimit)!; +	finish(val); +	assert(loadstr(s, 5: nestlimit) is limitreached); +}; diff --git a/encoding/json/+test/test_value.ha b/encoding/json/+test/test_value.ha new file mode 100644 index 0000000..eca7dcf --- /dev/null +++ b/encoding/json/+test/test_value.ha @@ -0,0 +1,49 @@ +// License: MPL-2.0 +// (c) 2022 Drew DeVault <sir@cmpwn.com> + +@test fn object() void = { +	let obj = newobject(); +	defer finish(obj); + +	set(&obj, "hello", "world"); +	set(&obj, "foo", "bar"); +	set(&obj, "the answer", 42.0); + +	// XXX: Match overhaul? +	assert(*(get(&obj, "hello") as *value) as str == "world"); +	assert(*(get(&obj, "foo") as *value) as str == "bar"); +	assert(*(get(&obj, "the answer") as *value) as f64 == 42.0); +	assert(get(&obj, "nonexistent") is void); + +	del(&obj, "hello"); +	assert(get(&obj, "hello") is void); +}; + +@test fn iterator() void = { +	let obj = newobject(); +	defer finish(obj); + +	set(&obj, "hello", "world"); +	set(&obj, "foo", "bar"); +	set(&obj, "the answer", 42.0); + +	let it = iter(&obj); +	assert(next(&it) is (const str, const *value)); +	assert(next(&it) is (const str, const *value)); +	assert(next(&it) is (const str, const *value)); +	assert(next(&it) is void); +}; + +@test fn equal() void = { +	let a = newobject(); +	defer finish(a); +	set(&a, "a", 42.0); +	set(&a, "A", "hello"); + +	let b = newobject(); +	defer finish(b); +	set(&b, "A", "hello"); +	set(&b, "a", 42.0); + +	assert(equal(a, b)); +}; diff --git a/encoding/json/COPYING b/encoding/json/COPYING new file mode 100644 index 0000000..c257317 --- /dev/null +++ b/encoding/json/COPYING @@ -0,0 +1,367 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" +    means each individual or legal entity that creates, contributes to +    the creation of, or owns Covered Software. + +1.2. "Contributor Version" +    means the combination of the Contributions of others (if any) used +    by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" +    means Covered Software of a particular Contributor. + +1.4. "Covered Software" +    means Source Code Form to which the initial Contributor has attached +    the notice in Exhibit A, the Executable Form of such Source Code +    Form, and Modifications of such Source Code Form, in each case +    including portions thereof. + +1.5. "Incompatible With Secondary Licenses" +    means + +    (a) that the initial Contributor has attached the notice described +        in Exhibit B to the Covered Software; or + +    (b) that the Covered Software was made available under the terms of +        version 1.1 or earlier of the License, but not also under the +        terms of a Secondary License. + +1.6. "Executable Form" +    means any form of the work other than Source Code Form. + +1.7. "Larger Work" +    means a work that combines Covered Software with other material, in  +    a separate file or files, that is not Covered Software. + +1.8. "License" +    means this document. + +1.9. "Licensable" +    means having the right to grant, to the maximum extent possible, +    whether at the time of the initial grant or subsequently, any and +    all of the rights conveyed by this License. + +1.10. "Modifications" +    means any of the following: + +    (a) any file in Source Code Form that results from an addition to, +        deletion from, or modification of the contents of Covered +        Software; or + +    (b) any new file in Source Code Form that contains any Covered +        Software. + +1.11. "Patent Claims" of a Contributor +    means any patent claim(s), including without limitation, method, +    process, and apparatus claims, in any patent Licensable by such +    Contributor that would be infringed, but for the grant of the +    License, by the making, using, selling, offering for sale, having +    made, import, or transfer of either its Contributions or its +    Contributor Version. + +1.12. "Secondary License" +    means either the GNU General Public License, Version 2.0, the GNU +    Lesser General Public License, Version 2.1, the GNU Affero General +    Public License, Version 3.0, or any later versions of those +    licenses. + +1.13. "Source Code Form" +    means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") +    means an individual or a legal entity exercising rights under this +    License. For legal entities, "You" includes any entity that +    controls, is controlled by, or is under common control with You. For +    purposes of this definition, "control" means (a) the power, direct +    or indirect, to cause the direction or management of such entity, +    whether by contract or otherwise, or (b) ownership of more than +    fifty percent (50%) of the outstanding shares or beneficial +    ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) +    Licensable by such Contributor to use, reproduce, make available, +    modify, display, perform, distribute, and otherwise exploit its +    Contributions, either on an unmodified basis, with Modifications, or +    as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer +    for sale, have made, import, and otherwise transfer either its +    Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; +    or + +(b) for infringements caused by: (i) Your and any other third party's +    modifications of Covered Software, or (ii) the combination of its +    Contributions with other software (except as part of its Contributor +    Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of +    its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code +    Form, as described in Section 3.1, and You must inform recipients of +    the Executable Form how they can obtain a copy of such Source Code +    Form by reasonable means in a timely manner, at a charge no more +    than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this +    License, or sublicense it under different terms, provided that the +    license for the Executable Form does not attempt to limit or alter +    the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +*                                                                      * +*  6. Disclaimer of Warranty                                           * +*  -------------------------                                           * +*                                                                      * +*  Covered Software is provided under this License on an "as is"       * +*  basis, without warranty of any kind, either expressed, implied, or  * +*  statutory, including, without limitation, warranties that the       * +*  Covered Software is free of defects, merchantable, fit for a        * +*  particular purpose or non-infringing. The entire risk as to the     * +*  quality and performance of the Covered Software is with You.        * +*  Should any Covered Software prove defective in any respect, You     * +*  (not any Contributor) assume the cost of any necessary servicing,   * +*  repair, or correction. This disclaimer of warranty constitutes an   * +*  essential part of this License. No use of any Covered Software is   * +*  authorized under this License except under this disclaimer.         * +*                                                                      * +************************************************************************ + +************************************************************************ +*                                                                      * +*  7. Limitation of Liability                                          * +*  --------------------------                                          * +*                                                                      * +*  Under no circumstances and under no legal theory, whether tort      * +*  (including negligence), contract, or otherwise, shall any           * +*  Contributor, or anyone who distributes Covered Software as          * +*  permitted above, be liable to You for any direct, indirect,         * +*  special, incidental, or consequential damages of any character      * +*  including, without limitation, damages for lost profits, loss of    * +*  goodwill, work stoppage, computer failure or malfunction, or any    * +*  and all other commercial damages or losses, even if such party      * +*  shall have been informed of the possibility of such damages. This   * +*  limitation of liability shall not apply to liability for death or   * +*  personal injury resulting from such party's negligence to the       * +*  extent applicable law prohibits such limitation. Some               * +*  jurisdictions do not allow the exclusion or limitation of           * +*  incidental or consequential damages, so this exclusion and          * +*  limitation may not apply to You.                                    * +*                                                                      * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + +  This Source Code Form is subject to the terms of the Mozilla Public +  License, v. 2.0. If a copy of the MPL was not distributed with this +  file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. diff --git a/encoding/json/README b/encoding/json/README new file mode 100644 index 0000000..fa917d5 --- /dev/null +++ b/encoding/json/README @@ -0,0 +1,15 @@ +This module provides an implementation of the JavaScript Object Notation (JSON) +format, as defined by RFC 8259. Note that several other, incompatible +specifications exist. This implementation does not include any extensions; only +features which are strictly required by the spec are implemented. + +A lexer for JSON values is provided, which may be initialized with [[lex]] and +provides tokens via [[next]], and which uses a relatively small amount of memory +and provides relatively few guarantees regarding the compliance of the input with +the JSON grammar. + +Additionally, the [[value]] type is provided to store any value JSON value, as +well as helpers like [[newobject]], [[get]], and [[set]]. One can load a JSON +value from an input stream into a heap-allocated [[value]] via [[load]], which +enforces all of JSON's grammar constraints and returns an object which must be +freed with [[finish]]. diff --git a/encoding/json/dump.ha b/encoding/json/dump.ha new file mode 100644 index 0000000..7e7dd8d --- /dev/null +++ b/encoding/json/dump.ha @@ -0,0 +1,81 @@ +// License: MPL-2.0 +// (c) 2022 Sebastian <sebastian@sebsite.pw> +use fmt; +use io; +use strings; +use memio; + +// Dumps a [[value]] into an [[io::handle]] as a string without any additional +// formatting. +export fn dump(out: io::handle, val: value) (size | io::error) = { +	let z = 0z; +	match (val) { +	case let v: (f64 | bool) => +		z += fmt::fprint(out, v)?; +	case let s: str => +		z += fmt::fprint(out, `"`)?; +		let it = strings::iter(s); +		for (const r => strings::next(&it)) { +			switch (r) { +			case '\b' => +				z += fmt::fprint(out, `\b`)?; +			case '\f' => +				z += fmt::fprint(out, `\f`)?; +			case '\n' => +				z += fmt::fprint(out, `\n`)?; +			case '\r' => +				z += fmt::fprint(out, `\r`)?; +			case '\t' => +				z += fmt::fprint(out, `\t`)?; +			case '\"' => +				z += fmt::fprint(out, `\"`)?; +			case '\\' => +				z += fmt::fprint(out, `\\`)?; +			case => +				if (iscntrl(r)) { +					z += fmt::fprintf(out, `\u{:.4x}`, +						r: u32)?; +				} else { +					z += fmt::fprint(out, r)?; +				}; +			}; +		}; +		z += fmt::fprint(out, `"`)?; +	case _null => +		z += fmt::fprint(out, "null")?; +	case let a: []value => +		z += fmt::fprint(out, "[")?; +		for (let i = 0z; i < len(a); i += 1) { +			z += dump(out, a[i])?; +			if (i < len(a) - 1) { +				z += fmt::fprint(out, ",")?; +			}; +		}; +		z += fmt::fprint(out, "]")?; +	case let o: object => +		z += fmt::fprint(out, "{")?; +		let comma = false; +		let it = iter(&o); +		for (true) match (next(&it)) { +		case void => break; +		case let pair: (const str, const *value) => +			if (comma) { +				z += fmt::fprint(out, ",")?; +			}; +			comma = true; +			z += dump(out, pair.0)?; +			z += fmt::fprint(out, ":")?; +			z += dump(out, *pair.1)?; +		}; +		z += fmt::fprint(out, "}")?; +	}; +	return z; +}; + +// Dumps a [[value]] into a string without any additional formatting. The caller +// must free the return value. +export fn dumpstr(val: value) str = { +	let s = memio::dynamic(); +	dump(&s, val)!; +	return memio::string(&s)!; +}; diff --git a/encoding/json/lex.ha b/encoding/json/lex.ha new file mode 100644 index 0000000..7b9bf12 --- /dev/null +++ b/encoding/json/lex.ha @@ -0,0 +1,417 @@ +// License: MPL-2.0 +// (c) 2022 Drew DeVault <sir@cmpwn.com> +use ascii; +use bufio; +use encoding::utf8; +use io; +use os; +use strconv; +use strings; +use memio; + +export type lexer = struct { +	src: io::handle, +	strbuf: memio::stream, +	un: (token | void), +	rb: (rune | void), +	loc: (uint, uint), +	prevloc: (uint, uint), +	nextloc: (uint, uint), +	prevrloc: (uint, uint), +}; + +// Creates a new JSON lexer. The caller may obtain tokens with [[lex]] and +// should pass the result to [[close]] when they're done with it. +export fn newlexer(src: io::handle) lexer = lexer { +	src = src, +	strbuf = memio::dynamic(), +	un = void, +	rb = void, +	loc = (1, 0), +	... +}; + +// Frees state associated with a JSON lexer. +export fn close(lex: *lexer) void = { +	io::close(&lex.strbuf)!; +}; + +// Returns the next token from a JSON lexer. The return value is borrowed from +// the lexer and will be overwritten on subsequent calls. +export fn lex(lex: *lexer) (token | io::EOF | error) = { +	match (lex.un) { +	case void => +		lex.prevloc = lex.loc; +	case let tok: token => +		lex.un = void; +		lex.prevloc = lex.loc; +		lex.loc = lex.nextloc; +		return tok; +	}; + +	const rn = match (nextrunews(lex)?) { +	case io::EOF => +		return io::EOF; +	case let rn: rune => +		yield rn; +	}; + +	switch (rn) { +	case '[' => +		return arraystart; +	case ']' => +		return arrayend; +	case '{' => +		return objstart; +	case '}' => +		return objend; +	case ',' => +		return comma; +	case ':' => +		return colon; +	case '"' => +		return scan_str(lex)?; +	case => +		yield; +	}; + +	if (ascii::isdigit(rn) || rn == '-') { +		unget(lex, rn); +		return scan_number(lex)?; +	}; + +	if (!ascii::isalpha(rn)) { +		return lex.loc: invalid; +	}; + +	unget(lex, rn); +	const word = scan_word(lex)?; +	switch (word) { +	case "true" => +		return true; +	case "false" => +		return false; +	case "null" => +		return _null; +	case => +		return lex.loc: invalid; +	}; +}; + +// "Unlexes" a token from the lexer, such that the next call to [[lex]] will +// return that token again. Only one token can be unlexed at a time, otherwise +// the program will abort. +export fn unlex(lex: *lexer, tok: token) void = { +	assert(lex.un is void, "encoding::json::unlex called twice in a row"); +	lex.un = tok; +	lex.nextloc = lex.loc; +	lex.loc = lex.prevloc; +}; + +// Scans until encountering a non-alphabetical character, returning the +// resulting word. +fn scan_word(lex: *lexer) (str | error) = { +	memio::reset(&lex.strbuf); + +	for (true) { +		const rn = match (nextrune(lex)?) { +		case let rn: rune => +			yield rn; +		case io::EOF => +			break; +		}; +		if (!ascii::isalpha(rn)) { +			unget(lex, rn); +			break; +		}; +		memio::appendrune(&lex.strbuf, rn)!; +	}; + +	return memio::string(&lex.strbuf)!; +}; + +type numstate = enum { +	SIGN, +	START, +	ZERO, +	INTEGER, +	FRACSTART, +	FRACTION, +	EXPSIGN, +	EXPSTART, +	EXPONENT, +}; + +fn scan_number(lex: *lexer) (token | error) = { +	memio::reset(&lex.strbuf); + +	let state = numstate::SIGN; +	for (true) { +		const rn = match (nextrune(lex)?) { +		case let rn: rune => +			yield rn; +		case io::EOF => +			break; +		}; + +		switch (state) { +		case numstate::SIGN => +			state = numstate::START; +			if (rn != '-') { +				unget(lex, rn); +				continue; +			}; +		case numstate::START => +			switch (rn) { +			case '0' => +				state = numstate::ZERO; +			case => +				if (!ascii::isdigit(rn)) { +					return lex.loc: invalid; +				}; +				state = numstate::INTEGER; +			}; +		case numstate::ZERO => +			switch (rn) { +			case '.' => +				state = numstate::FRACSTART; +			case 'e', 'E' => +				state = numstate::EXPSIGN; +			case => +				if (ascii::isdigit(rn)) { +					return lex.loc: invalid; +				}; +				unget(lex, rn); +				break; +			}; +		case numstate::INTEGER => +			switch (rn) { +			case '.' => +				state = numstate::FRACSTART; +			case 'e', 'E' => +				state = numstate::EXPSIGN; +			case => +				if (!ascii::isdigit(rn)) { +					unget(lex, rn); +					break; +				}; +			}; +		case numstate::FRACSTART => +			if (!ascii::isdigit(rn)) { +				return lex.loc: invalid; +			}; +			state = numstate::FRACTION; +		case numstate::FRACTION => +			switch (rn) { +			case 'e', 'E' => +				state = numstate::EXPSIGN; +			case => +				if (!ascii::isdigit(rn)) { +					unget(lex, rn); +					break; +				}; +			}; +		case numstate::EXPSIGN => +			state = numstate::EXPSTART; +			if (rn != '+' && rn != '-') { +				unget(lex, rn); +				continue; +			}; +		case numstate::EXPSTART => +			if (!ascii::isdigit(rn)) { +				return lex.loc: invalid; +			}; +			state = numstate::EXPONENT; +		case numstate::EXPONENT => +			if (!ascii::isdigit(rn)) { +				unget(lex, rn); +				break; +			}; +		}; + +		memio::appendrune(&lex.strbuf, rn)!; +	}; + +	match (strconv::stof64(memio::string(&lex.strbuf)!)) { +	case let f: f64 => +		return f; +	case => +		return lex.loc: invalid; +	}; +}; + +fn scan_str(lex: *lexer) (token | error) = { +	memio::reset(&lex.strbuf); + +	for (true) { +		const rn = match (nextrune(lex)?) { +		case let rn: rune => +			yield rn; +		case io::EOF => +			lex.loc.1 += 1; +			return lex.loc: invalid; +		}; + +		switch (rn) { +		case '"' => +			break; +		case '\\' => +			const rn = scan_escape(lex)?; +			memio::appendrune(&lex.strbuf, rn)!; +		case => +			if (iscntrl(rn)) { +				return lex.loc: invalid; +			}; +			memio::appendrune(&lex.strbuf, rn)!; +		}; +	}; + +	return memio::string(&lex.strbuf)!; +}; + +fn scan_escape(lex: *lexer) (rune | error) = { +	const rn = match (nextrune(lex)?) { +	case let rn: rune => +		yield rn; +	case io::EOF => +		return lex.loc: invalid; +	}; + +	switch (rn) { +	case '\"' => +		return '\"'; +	case '\\' => +		return '\\'; +	case '/' => +		return '/'; +	case 'b' => +		return '\b'; +	case 'f' => +		return '\f'; +	case 'n' => +		return '\n'; +	case 'r' => +		return '\r'; +	case 't' => +		return '\t'; +	case 'u' => +		const u = scan_escape_codepoint(lex)?; + +		if (u >= 0xd800 && u <= 0xdfff) { +			if (u >= 0xdc00) { +				return lex.loc: invalid; +			}; + +			const rn = match (nextrune(lex)?) { +			case let rn: rune => +				yield rn; +			case io::EOF => +				return lex.loc: invalid; +			}; +			if (rn != '\\') { +				return lex.loc: invalid; +			}; +			const rn = match (nextrune(lex)?) { +			case let rn: rune => +				yield rn; +			case io::EOF => +				return lex.loc: invalid; +			}; +			if (rn != 'u') { +				return lex.loc: invalid; +			}; + +			const v = scan_escape_codepoint(lex)?; +			if (v < 0xdc00 || v > 0xdfff) { +				return lex.loc: invalid; +			}; + +			const hi = u: u32 & 0x03ff; +			const lo = v: u32 & 0x03ff; +			return ((hi >> 10 | lo) + 0x10000): rune; +		}; + +		return u: u32: rune; +	case => +		return lex.loc: invalid; +	}; +}; + +fn scan_escape_codepoint(lex: *lexer) (u16 | error) = { +	let buf: [4]u8 = [0...]; +	match (io::readall(lex.src, buf)?) { +	case io::EOF => +		return lex.loc: invalid; +	case size => +		yield; +	}; +	const s = match (strings::fromutf8(buf)) { +	case let s: str => +		yield s; +	case => +		return lex.loc: invalid; +	}; +	match (strconv::stou16(s, strconv::base::HEX)) { +	case let u: u16 => +		lex.loc.1 += 4; +		return u; +	case => +		return lex.loc: invalid; +	}; +}; + +// Gets the next rune from the lexer. +fn nextrune(lex: *lexer) (rune | io::EOF | error) = { +	if (lex.rb is rune) { +		lex.prevrloc = lex.loc; +		const r = lex.rb as rune; +		lex.rb = void; +		if (r == '\n') { +			lex.loc = (lex.loc.0 + 1, 0); +		} else { +			lex.loc.1 += 1; +		}; +		return r; +	}; +	match (bufio::read_rune(lex.src)) { +	case let err: io::error => +		return err; +	case utf8::invalid => +		return lex.loc: invalid; +	case io::EOF => +		return io::EOF; +	case let rn: rune => +		lex.prevrloc = lex.loc; +		if (rn == '\n') { +			lex.loc = (lex.loc.0 + 1, 0); +		} else { +			lex.loc.1 += 1; +		}; +		return rn; +	}; +}; + +// Like nextrune but skips whitespace. +fn nextrunews(lex: *lexer) (rune | io::EOF | error) = { +	for (true) { +		match (nextrune(lex)?) { +		case let rn: rune => +			if (isspace(rn)) { +				continue; +			}; +			return rn; +		case io::EOF => +			return io::EOF; +		}; +	}; +}; + +fn unget(lex: *lexer, r: rune) void = { +	assert(lex.rb is void); +	lex.rb = r; +	lex.loc = lex.prevrloc; +}; + +fn iscntrl(r: rune) bool = r: u32 < 0x20; + +fn isspace(r: rune) bool = ascii::isspace(r) && r != '\f'; diff --git a/encoding/json/load.ha b/encoding/json/load.ha new file mode 100644 index 0000000..8dc2b56 --- /dev/null +++ b/encoding/json/load.ha @@ -0,0 +1,148 @@ +use memio; +use io; +use strings; +use types; + +// Options for [[load]]. +export type load_option = nestlimit; + +// The maximum number of nested objects or arrays that can be entered before +// erroring out. +export type nestlimit = uint; + +// Parses a JSON value from the given [[io::handle]], returning the value or an +// error. The return value is allocated on the heap; use [[finish]] to free it +// up when you're done using it. +// +// By default, this function assumes non-antagonistic inputs, and does not limit +// recursion depth or memory usage. You may want to set a custom [[nestlimit]], +// or incorporate an [[io::limitreader]] or similar. Alternatively, you can use +// the JSON lexer ([[lex]]) directly if dealing with potentially malicious +// inputs. +export fn load(src: io::handle, opts: load_option...) (value | error) = { +	let limit = types::UINT_MAX; +	for (let i = 0z; i < len(opts); i += 1) { +		limit = opts[i]: nestlimit: uint; +	}; +	const lex = newlexer(src); +	defer close(&lex); +	return _load(&lex, 0, limit); +}; + +// Parses a JSON value from the given string, returning the value or an error. +// The return value is allocated on the heap; use [[finish]] to free it up when +// you're done using it. +// +// See the documentation for [[load]] for information on dealing with +// potentially malicious inputs. +export fn loadstr(input: str, opts: load_option...) (value | error) = { +	let src = memio::fixed(strings::toutf8(input)); +	return load(&src, opts...); +}; + +fn _load(lexer: *lexer, level: uint, limit: uint) (value | error) = { +	const tok = mustscan(lexer)?; +	match (tok) { +	case _null => +		return _null; +	case let b: bool => +		return b; +	case let f: f64 => +		return f; +	case let s: str => +		return strings::dup(s); +	case arraystart => +		if (level == limit) { +			return limitreached; +		}; +		return _load_array(lexer, level + 1, limit); +	case objstart => +		if (level == limit) { +			return limitreached; +		}; +		return _load_obj(lexer, level + 1, limit); +	case (arrayend | objend | colon | comma) => +		return lexer.loc: invalid; +	}; +}; + +fn _load_array(lexer: *lexer, level: uint, limit: uint) (value | error) = { +	let success = false; +	let array: []value = []; +	defer if (!success) finish(array); +	let tok = mustscan(lexer)?; +	match (tok) { +	case arrayend => +		success = true; +		return array; +	case => +		unlex(lexer, tok); +	}; + +	for (true) { +		append(array, _load(lexer, level, limit)?); + +		tok = mustscan(lexer)?; +		match (tok) { +		case comma => void; +		case arrayend => break; +		case => +			return lexer.loc: invalid; +		}; +	}; +	success = true; +	return array; +}; + +fn _load_obj(lexer: *lexer, level: uint, limit: uint) (value | error) = { +	let success = false; +	let obj = newobject(); +	defer if (!success) finish(obj); +	let tok = mustscan(lexer)?; +	match (tok) { +	case objend => +		success = true; +		return obj; +	case => +		unlex(lexer, tok); +	}; + +	for (true) { +		let tok = mustscan(lexer)?; +		const key = match (tok) { +		case let s: str => +			yield strings::dup(s); +		case => +			return lexer.loc: invalid; +		}; +		defer free(key); + +		tok = mustscan(lexer)?; +		if (!(tok is colon)) { +			return lexer.loc: invalid; +		}; + +		put(&obj, key, _load(lexer, level, limit)?); + +		tok = mustscan(lexer)?; +		match (tok) { +		case comma => void; +		case objend => break; +		case => +			return lexer.loc: invalid; +		}; +	}; + +	success = true; +	return obj; +}; + +fn mustscan(lexer: *lexer) (token | error) = { +	match (lex(lexer)?) { +	case io::EOF => +		lexer.loc.1 += 1; +		return lexer.loc: invalid; +	case let tok: token => +		return tok; +	}; +}; diff --git a/encoding/json/path/path.ha b/encoding/json/path/path.ha new file mode 100644 index 0000000..819e9f5 --- /dev/null +++ b/encoding/json/path/path.ha @@ -0,0 +1,26 @@ +// A compiled JSONPath query. +export type query = []segment; + +export type segment_type = enum { +	CHILD, +	DESCENDANT, +}; + +export type segment = struct { +	stype: segment_type, +	selector: selector, +}; + +export type selector = (str | wild | index | slice | filter); + +export type wild = void; + +export type index = int; + +export type slice = struct { +	start: (int | void), +	end: (int | void), +	step: (int | void), +}; + +export type filter = void; // TODO diff --git a/encoding/json/types.ha b/encoding/json/types.ha new file mode 100644 index 0000000..1e1b433 --- /dev/null +++ b/encoding/json/types.ha @@ -0,0 +1,50 @@ +// License: MPL-2.0 +// (c) 2022 Drew DeVault <sir@cmpwn.com> +use fmt; +use io; + +// An invalid JSON token was encountered at this location (line, column). +export type invalid = !(uint, uint); + +// The maximum nesting limit was reached. +export type limitreached = !void; + +// A tagged union of all possible errors returned from this module. +export type error = !(invalid | limitreached | io::error); + +// The JSON null value. +export type _null = void; + +// The '[' token, signaling the start of a JSON array. +export type arraystart = void; + +// The ']' token, signaling the end of a JSON array. +export type arrayend = void; + +// The '{' token, signaling the start of a JSON object. +export type objstart = void; + +// The '}' token, signaling the end of a JSON object. +export type objend = void; + +// The ':' token. +export type colon = void; + +// The ',' token. +export type comma = void; + +// All tokens which can be returned from the JSON tokenizer. +export type token = (arraystart | arrayend | objstart | +	objend | colon | comma | str | f64 | bool | _null); + +// Converts an [[error]] into a human-friendly string. +export fn strerror(err: error) const str = { +	static let buf: [53]u8 = [0...]; +	match (err) { +	case let err: invalid => +		return fmt::bsprintf(buf, +			"{}:{}: Invalid JSON token encountered", err.0, err.1); +	case let err: io::error => +		return io::strerror(err); +	}; +}; diff --git a/encoding/json/value.ha b/encoding/json/value.ha new file mode 100644 index 0000000..fe68688 --- /dev/null +++ b/encoding/json/value.ha @@ -0,0 +1,217 @@ +// License: MPL-2.0 +// (c) 2022 Drew DeVault <sir@cmpwn.com> +use hash::fnv; +use htab; +use strings; + +export type object = struct { +	table: htab::table, +}; + +// A JSON value. +export type value = (f64 | str | bool | _null | []value | object); + +type entry = (str, value); + +fn htab_eq(ctx: *opaque, ent: *opaque) bool = +	*(ctx: *str) == (ent: *entry).0; + +fn _get(obj: *object, hash: u64, key: str) nullable *entry = +	htab::get(&obj.table, hash, &htab_eq, &key, size(entry)): +		nullable *entry; + +// Initializes a new (empty) JSON object. Call [[finish]] to free associated +// resources when you're done using it. +export fn newobject() object = { +	return object { +		table = htab::new(0, size(entry)), +	}; +}; + +// Gets a value from a JSON object. The return value is borrowed from the +// object. +export fn get(obj: *object, key: str) (*value | void) = { +	const hash = fnv::string(key); +	match (_get(obj, hash, key)) { +	case let ent: *entry => +		return &ent.1; +	case null => +		return void; +	}; +}; + +// Sets a value in a JSON object. The key and value will be duplicated. +export fn set(obj: *object, key: const str, val: const value) void = { +	put(obj, key, dup(val)); +}; + +// Sets a value in a JSON object. The key will be duplicated. The object will +// assume ownership over the value, without duplicating it. +export fn put(obj: *object, key: const str, val: const value) void = { +	const hash = fnv::string(key); +	match (_get(obj, hash, key)) { +	case let ent: *entry => +		finish(ent.1); +		ent.1 = val; +	case null => +		const ent = htab::add(&obj.table, hash, size(entry)): *entry; +		*ent = (strings::dup(key), val); +	}; +}; + +// Deletes values from a JSON object, if they are present. +export fn del(obj: *object, keys: const str...) void = { +	for (let i = 0z; i < len(keys); i += 1) { +		match (take(obj, keys[i])) { +		case let val: value => +			finish(val); +		case void => void; +		}; +	}; +}; + +// Deletes a key from a JSON object, returning its previous value, if any. +// The caller is responsible for freeing the value. +export fn take(obj: *object, key: const str) (value | void) = { +	const hash = fnv::string(key); +	match (_get(obj, hash, key)) { +	case let ent: *entry => +		free(ent.0); +		const val = ent.1; +		htab::del(&obj.table, ent, size(entry)); +		return val; +	case null => void; +	}; +}; + +// Clears all values from a JSON object, leaving it empty. +export fn reset(obj: *object) void = { +	let it = iter(obj); +	for (true) match (next(&it)) { +	case void => +		break; +	case let v: (const str, const *value) => +		del(obj, v.0); +	}; +}; + +// Returns the number of key/value pairs in a JSON object. +export fn count(obj: *object) size = { +	return htab::count(&obj.table); +}; + +export type iterator = struct { +	iter: htab::iterator, +}; + +// Creates an iterator that enumerates over the key/value pairs in an +// [[object]]. +export fn iter(obj: *object) iterator = { +	return iterator { iter = htab::iter(&obj.table) }; +}; + +// Returns the next key/value pair from this iterator, or void if none remain. +export fn next(iter: *iterator) ((const str, const *value) | void) = { +	match (htab::next(&iter.iter, size(entry))) { +	case let ent: *opaque => +		const ent = ent: *entry; +		return (ent.0, &ent.1); +	case null => void; +	}; +}; + +// Duplicates a JSON value. The caller must pass the return value to [[finish]] +// to free associated resources when they're done using it. +export fn dup(val: value) value = { +	match (val) { +	case let s: str => +		return strings::dup(s); +	case let v: []value => +		let new: []value = alloc([], len(v)); +		for (let i = 0z; i < len(v); i += 1) { +			append(new, dup(v[i])); +		}; +		return new; +	case let o: object => +		let new = newobject(); +		const i = iter(&o); +		for (true) { +			const pair = match (next(&i)) { +			case void => +				break; +			case let pair: (const str, const *value) => +				yield pair; +			}; +			set(&new, pair.0, *pair.1); +		}; +		return new; +	case => +		return val; +	}; +}; + +// Checks two JSON values for equality. +export fn equal(a: value, b: value) bool = { +	match (a) { +	case _null => +		return b is _null; +	case let a: bool => +		return b is bool && a == b as bool; +	case let a: f64 => +		return b is f64 && a == b as f64; +	case let a: str => +		return b is str && a == b as str; +	case let a: []value => +		if (!(b is []value)) return false; +		const b = b as []value; +		if (len(a) != len(b)) return false; +		for (let i = 0z; i < len(a); i += 1) { +			if (!equal(a[i], b[i])) { +				return false; +			}; +		}; +		return true; +	case let a: object => +		if (!(b is object)) return false; +		let b = b as object; +		if (count(&a) != count(&b)) { +			return false; +		}; +		let a = iter(&a); +		for (true) match (next(&a)) { +		case let a: (const str, const *value) => +			match (get(&b, a.0)) { +			case let b: *value => +				if (!equal(*a.1, *b)) { +					return false; +				}; +			case void => return false; +			}; +		case void => break; +		}; +		return true; +	}; +}; + +// Frees state associated with a JSON value. +export fn finish(val: value) void = { +	match (val) { +	case let s: str => +		free(s); +	case let v: []value => +		for (let i = 0z; i < len(v); i += 1) { +			finish(v[i]); +		}; +		free(v); +	case let o: object => +		let i = iter(&o); +		for (true) match (next(&i)) { +		case let ent: (const str, const *value) => +			free(ent.0); +			finish(*ent.1); +		case void => break; +		}; +		htab::finish(&o.table); +	case => void; +	}; +}; diff --git a/fonts.ha b/fonts.ha new file mode 100644 index 0000000..faa05f8 --- /dev/null +++ b/fonts.ha @@ -0,0 +1,491 @@ +use dejson; +use encoding::json; +use gl::*; +use glm; +use math; +use sort; +use strings; +use trace; + +type Font = struct { +	Object, +	glyphs: []Glyph, +}; + +type Glyph = struct { +	char: rune, +	scale: f32, +	ascent: f32, +	advance: f32, +	width: u8, +	height: u8, +	x: u16, +	y: u16, +	gl_texture: uint, +	tex_width: u32, +	tex_height: u32, +}; + +let FONTS = OBJREG_EMPTY; + +fn fonts_find(ident: str) nullable *Font = +	objreg_find(&FONTS, ident): nullable *Font; + +type FontsIter = struct { +	inner: ObjectRegistryIterator, +}; + +fn fonts_iter() FontsIter = +	FontsIter { inner = objreg_iter(&FONTS) }; + +fn fonts_next(it: *FontsIter) nullable *Font = +	objreg_next(&it.inner): nullable *Font; + +fn load_fonts(assets: *Pack) void = { +	const tr = &trace::root; +	trace::info(tr, "loading fonts..."); + +	const results = resource_search(assets, "font", ".json"); +	for (let i = 0z; i < len(results); i += 1) { +		const (ident, ext) = results[i]; +		const tr = trace::ctx(tr, "load font {}", ident); + +		const font = alloc(Font { +			name = strings::dup(ident), +			glyphs = [], +		}); +		objreg_register(&FONTS, font); + +		const json = resource_load_json( +			assets, "font", ident, ".json", &tr); +		const json = match (json) { +		case let json: json::value => +			yield json; +		case trace::failed => +			continue; +		}; +		defer json::finish(json); + +		const deser = dejson::newdeser(&json); +		const decl = deser_font_decl(&deser); +		const decl = match (decl) { +		case let decl: FontDecl => +			yield decl; +		case let err: dejson::error => +			defer free(err); +			trace::error(&tr, "deser: {}", err): void; +			continue; +		}; + +		font_load(font, &decl, &tr); +	}; +}; + +fn font_load(font: *Font, decl: *FontDecl, tr: *trace::tracer) void = { +	for (let i = 0z; i < len(decl.providers); i += 1) { +		match (decl.providers[i]) { +		case let provider: FontDeclProviderBitmap => +			font_load_bitmap(font, &provider, tr): void; +		case FontDeclProviderLegacyUnicode => +			void; +		case let provider: FontDeclProviderSpace => +			font_load_space(font, &provider); +		}; +	}; + +	sort::sort(font.glyphs, size(Glyph), &glyph_cmpfunc); + +	let dedup: []Glyph = []; +	for (let i = 0z; i < len(font.glyphs); i += 1) { +		if (i == len(font.glyphs) - 1 || font.glyphs[i].char +				!= font.glyphs[i + 1].char) { +			append(dedup, font.glyphs[i]); +		}; +	}; +	free(font.glyphs); +	font.glyphs = dedup; +}; + +fn font_load_bitmap( +	font: *Font, +	provider: *FontDeclProviderBitmap, +	tr: *trace::tracer, +) (void | trace::failed) = { +	const tr = trace::ctx(tr, "bitmap {}", provider.file); + +	// TODO: arghhhhh +	const ident = strings::trimsuffix(provider.file, ".png"); +	const tex = match (textures_find(ident)) { +	case let tex: *Texture => +		yield tex; +	case null => +		return trace::error(&tr, "Unknown texture"); +	}; +	const gl_texture = texture_upload(tex, &tr); +	if (tex.width % provider.ncolumns != 0 +			|| tex.height & provider.nrows != 0) { +		return trace::error(&tr, +			"Texture dimensions {},{} not divisible by glyph grid dimensions {},{}", +			tex.width, tex.height, +			provider.ncolumns, provider.nrows); +	}; + +	const glyph_width = tex.width / provider.ncolumns; +	if (glyph_width: u8 != glyph_width) { +		return trace::error(&tr, "Glyph width {} exceeds limit of 255", +			glyph_width); +	}; +	const glyph_width = glyph_width: u8; +	const glyph_height = tex.height / provider.nrows; +	if (glyph_height: u8 != glyph_height) { +		return trace::error(&tr, "Glyph height {} exceeds limit of 255", +			glyph_height); +	}; +	const glyph_height = glyph_height: u8; +	const scale = provider.height: f32 / glyph_height: f32; +	const tex_po2width = 1 << math::bit_size_u32(tex.width - 1): u32; +	const tex_po2height = 1 << math::bit_size_u32(tex.height - 1): u32; + +	for (let y = 0u16; y < provider.nrows; y += 1) { +		for (let x = 0u16; x < provider.ncolumns; x += 1) { +			const ch = provider.chars[x + y * provider.ncolumns]; +			if (ch == '\0' || ch == ' ') { +				continue; +			}; +			const visual_width = 8i32; // TODO: fake value for now ._. +			const advance = visual_width: f32 * scale; +			// It's how Mojang does it *shrug*. +			const advance = math::truncf64(advance + 0.5): f32 + 1.0; +			append(font.glyphs, Glyph { +				char = ch, +				scale = scale, +				ascent = provider.ascent: f32, +				advance = advance, +				width = glyph_width, +				height = glyph_height, +				x = x * glyph_width, +				y = y * glyph_height, +				gl_texture = gl_texture, +				tex_width = tex_po2width, +				tex_height = tex_po2height, +			}); +		}; +	}; +}; + +fn font_load_space(font: *Font, provider: *FontDeclProviderSpace) void = { +	for (let i = 0z; i < len(provider.advances); i += 1) { +		const (ch, advance) = provider.advances[i]; +		append(font.glyphs, Glyph { +			char = ch, +			scale = 0.0, +			ascent = 0.0, +			advance = advance, +			width = 0, +			height = 0, +			x = 0, +			y = 0, +			gl_texture = 0, +			tex_width = 0, +			tex_height = 0, +		}); +	}; +}; + +fn font_find_glyph(font: *Font, ch: rune) nullable *Glyph = { +	const key = Glyph { +		char = ch, +		... +	}; +	match (sort::search(font.glyphs, size(Glyph), &key, &glyph_cmpfunc)) { +	case let i: size => +		return &font.glyphs[i]; +	case void => +		return null; +	}; +}; + +fn glyph_cmpfunc(a: const *opaque, b: const *opaque) int = { +	let a = a: *Glyph; +	let b = b: *Glyph; +	return if (a.char: u32 < b.char: u32) -1 +		else if (a.char: u32 > b.char: u32) 1 +		else 0; +}; + +def TEXT_BASELINE_OFFSET = 7.0f32; + +type TextMetrics = struct { +	width: f32, +	ymin: f32, +	ymax: f32, +}; + +fn font_measure(font: *Font, text: str) TextMetrics = { +	let res = TextMetrics { ... }; +	let x = 0f32; + +	let it = strings::iter(text); +	for (true) match (strings::next(&it)) { +	case let ch: rune => +		const glyph = match (font_find_glyph(font, ch)) { +		case let glyph: *Glyph => +			yield glyph; +		case null => +			continue; +		}; + +		if (x + glyph.width: f32 * glyph.scale > res.width) { +			res.width = x + glyph.width: f32 * glyph.scale; +		}; +		if (-glyph.ascent < res.ymin) { +			res.ymin = -glyph.ascent; +		}; +		if (glyph.height: f32 * glyph.scale +				- glyph.ascent > res.ymax) { +			res.ymax = glyph.height: f32 * glyph.scale +				- glyph.ascent; +		}; + +		x += glyph.advance; +	case done => break; +	}; + +	res.ymin += TEXT_BASELINE_OFFSET; +	res.ymax += TEXT_BASELINE_OFFSET; + +	return res; +}; + +fn render_text_shadow(text: str, font: *Font, trans: *glm::m4, color: [4]u8) +		void = { +	let shadow_trans = glm::translation_make(&[1.0f32, 1.0, 0.0]); +	shadow_trans = glm::m4_mul(trans, &shadow_trans); +	render_text(text, font, &shadow_trans, +		[color[0] >> 2, color[1] >> 2, color[2] >> 2, color[3]]); +	render_text(text, font, trans, color); +}; + +fn render_text(text: str, font: *Font, trans: *glm::m4, color: [4]u8) void = { +	// TODO: being very latin-centric here... + +	glEnable(GL_BLEND); +	glBlendEquation(GL_FUNC_ADD); +	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +	let x = 0f32; + +	let it = strings::iter(text); +	for (true) match (strings::next(&it)) { +	case let ch: rune => +		const glyph = match (font_find_glyph(font, ch)) { +		case let glyph: *Glyph => +			yield glyph; +		case null => +			continue; +		}; + +		if (glyph.gl_texture != 0) { +			render_rect_textured(trans, +				x, TEXT_BASELINE_OFFSET - glyph.ascent, +				glyph.width: f32 * glyph.scale, +				glyph.height: f32 * glyph.scale, +				color, +				glyph.x: f32, glyph.y: f32, +				glyph.width: f32, glyph.height: f32, +				glyph.gl_texture, +				glyph.tex_width, glyph.tex_height); +		}; + +		x += glyph.advance; +	case done => break; +	}; +}; + +type FontDecl = struct { +	providers: []FontDeclProvider, +}; + +type FontDeclProvider = ( +	FontDeclProviderBitmap | +	FontDeclProviderLegacyUnicode | +	FontDeclProviderSpace); + +// TODO: it might be necessary to work with grapheme clusters instead of code +// points here... + +type FontDeclProviderBitmap = struct { +	file: str, +	height: i32, +	ascent: i32, +	chars: []rune, // len = ncolumns * nrows +	ncolumns: u32, +	nrows: u32, +}; + +type FontDeclProviderLegacyUnicode = void; + +type FontDeclProviderSpace = struct { +	advances: [](rune, f32), +}; + +fn font_decl_provider_finish(provider: *FontDeclProvider) void = { +	match (*provider) { +	case let provider: FontDeclProviderBitmap => +		free(provider.file); +		free(provider.chars); +	case FontDeclProviderLegacyUnicode => +		void; +	case let provider: FontDeclProviderSpace => +		free(provider.advances); +	}; +}; + +fn deser_font_decl(de: *dejson::deser) (FontDecl | dejson::error) = { +	wassert_fields(de, "providers")?; +	let success = false; + +	const de_providers = dejson::field(de, "providers")?; +	const nproviders = dejson::length(&de_providers)?; +	let providers: []FontDeclProvider = alloc([], nproviders); +	defer if (!success) free(providers); +	defer if (!success) for (let i = 0z; i < len(providers); i += 1) { +		font_decl_provider_finish(&providers[i]); +	}; +	for (let i = 0z; i < nproviders; i += 1) { +		const de_provider = dejson::index(&de_providers, i)?; +		const de_typ = dejson::field(&de_provider, "type")?; +		const typ = dejson::string(&de_typ)?; +		append(providers, switch (typ) { +		case "bitmap" => +			yield deser_font_decl_provider_bitmap(&de_provider)?; +		case "legacy_unicode" => +			yield deser_font_decl_provider_legacy_unicode( +				&de_provider)?; +		case "space" => +			yield deser_font_decl_provider_space(&de_provider)?; +		case => +			const typename = dejson::strfield(typ); +			defer free(typename); +			return dejson::fail(&de_typ, "Unknown type {}", typename); +		}); +	}; + +	success = true; +	return FontDecl { +		providers = providers, +	}; +}; + +fn deser_font_decl_provider_bitmap(de: *dejson::deser) +		(FontDeclProviderBitmap | dejson::error) = { +	wassert_fields(de, "type", "file", "height", "ascent", "chars")?; +	let success = false; + +	const de_file = dejson::field(de, "file")?; +	const file = strings::dup(dejson::string(&de_file)?); +	defer if (!success) free(file); + +	const de_height = dejson::optfield(de, "height")?; +	const height = match (de_height) { +	case let de_height: dejson::deser => +		yield dejson::number_i32(&de_height)?; +	case void => +		yield 8i32; +	}; + +	const de_ascent = dejson::optfield(de, "ascent")?; +	const ascent = match (de_ascent) { +	case let de_ascent: dejson::deser => +		yield dejson::number_i32(&de_ascent)?; +	case void => +		yield 0i32; +	}; + +	let chars: []rune = []; +	defer if (!success) free(chars); +	const de_chars = dejson::field(de, "chars")?; +	const nrows = dejson::length(&de_chars)?; +	if (nrows: u32 != nrows) { +		return dejson::fail(&de_chars, "Too many rows"); +	}; +	const nrows = nrows: u32; +	let ncolumns = 0z; +	for (let i = 0z; i < nrows; i += 1) { +		const de_row = dejson::index(&de_chars, i)?; +		const row = dejson::string(&de_row)?; + +		let ncolumns_ = 0z; +		let it = strings::iter(row); +		for (true) match (strings::next(&it)) { +		case let ch: rune => +			append(chars, ch); +			ncolumns_ += 1; +		case done => break; +		}; + +		if (i != 0 && ncolumns_ != ncolumns) { +			return dejson::fail(&de_row, +				"Row length {} is inconsistent with previous rows (was {})", +				ncolumns_, ncolumns); +		}; +		ncolumns = ncolumns_; +	}; +	if (len(chars) == 0) { +		return dejson::fail(&de_chars, +			"Bitmap provider declares no characters"); +	}; +	if (ncolumns: u32 != ncolumns) { +		return dejson::fail(&de_chars, "Too many rows"); +	}; +	let ncolumns = ncolumns: u32; + +	success = true; +	return FontDeclProviderBitmap { +		file = file, +		height = height, +		ascent = ascent, +		chars = chars, +		ncolumns = ncolumns, +		nrows = nrows, +	}; +}; + +fn deser_font_decl_provider_legacy_unicode(de: *dejson::deser) +		(FontDeclProviderLegacyUnicode | dejson::error) = { +	// TODO: probably just remove this when updating to 1.20. +	return FontDeclProviderLegacyUnicode; +}; + +fn deser_font_decl_provider_space(de: *dejson::deser) +		(FontDeclProviderSpace | dejson::error) = { +	wassert_fields(de, "type", "advances")?; +	let success = false; + +	const de_advances = dejson::field(de, "advances")?; +	let advances: [](rune, f32) = alloc([], dejson::count(&de_advances)?); +	defer if (!success) free(advances); +	const it = dejson::iter(&de_advances)?; +	for (true) match (dejson::next(&it)) { +	case let entry: (str, dejson::deser) => +		let it = strings::iter(entry.0); +		const ch = match (strings::next(&it)) { +		case let ch: rune => +			yield ch; +		case done => +			return dejson::fail(&entry.1, +				"Empty field name not allowed"); +		}; +		if (strings::next(&it) is rune) { +			return dejson::fail(&entry.1, +				"Field name must be a single code point"); +		}; +		append(advances, (ch, dejson::number(&entry.1)?: f32)); +	case void => break; +	}; + +	success = true; +	return FontDeclProviderSpace { +		advances = advances, +	}; +}; @@ -0,0 +1,238 @@ +use fmt; +use gl::*; +use glm; +use mcproto; +use time; + +type Gamemode = enum u8 { +	SURVIVAL = 0, +	CREATIVE = 1, +	ADVENTURE = 2, +	SPECTATOR = 3, +	COUNT, +}; + +fn strgamemode(gamemode: Gamemode) str = { +	switch (gamemode) { +	case Gamemode::SURVIVAL => +		return "survival"; +	case Gamemode::CREATIVE => +		return "creative"; +	case Gamemode::ADVENTURE => +		return "adventure"; +	case Gamemode::SPECTATOR => +		return "spectator"; +	case => +		abort("unknown gamemode"); +	}; +}; + +let GAMEMODE = Gamemode::SURVIVAL; +let DIM_TYPE = 0z; +let VIEW_DISTANCE = 0i32; + +let LOADING_READY = false; +let LOADING_RECEIVED_SPAWN_POSITION = false; + +def TICK_INTERVAL = time::SECOND / 20; +def TICK_MAX_PER_FRAME = 40u64; + +let TICK_EPOCH = time::instant { ... }; +let TICK_REAL_TIME_COUNT = 0u64; +let TICK_COUNT = 0u64; + +type DimType = struct { +	name: str, +	min_y: i8, // in chunks +	height: u8, // in chunks +}; + +let DIM_TYPES: []DimType = []; + +fn game_init() void = { +	TICK_EPOCH = frame_timestamp(); + +	let out: []u8 = []; +	defer free(out); +	mcproto::encode_string(&out, "en_US"); +	append(out, 40); +	mcproto::encode_varint(&out, 0); +	mcproto::encode_bool(&out, true); +	append(out, 0); +	mcproto::encode_varint(&out, 1); +	mcproto::encode_bool(&out, false); +	mcproto::encode_bool(&out, true); +	network_send(0x07, out); + +	game_respawn(); +}; + +fn game_respawn() void = { +	chunks_respawn(); +}; + +fn game_despawn() void = { +	death_close(); +	chunks_despawn(); + +	LOADING_READY = false; +	LOADING_RECEIVED_SPAWN_POSITION = false; + +	player_despawn(); +}; + +fn game_destroy() void = { +	game_despawn(); +	VIEW_DISTANCE = 0; +	TICK_REAL_TIME_COUNT = 0; +	TICK_COUNT = 0; +}; + +fn game_frame() void = { +	if (!LOADING_READY && loading_is_ready()) { +		LOADING_READY = true; +	}; + +	death_frame(); +	control_frame(); + +	const ts = frame_timestamp(); +	const ticks = (time::diff(TICK_EPOCH, ts) / TICK_INTERVAL): u64; +	const frame_ticks = ticks - TICK_REAL_TIME_COUNT; +	const frame_ticks = if (frame_ticks < TICK_MAX_PER_FRAME) +		frame_ticks else TICK_MAX_PER_FRAME; +	TICK_REAL_TIME_COUNT = ticks; +	for (let i = 0u64; i < frame_ticks; i += 1) { +		TICK_COUNT += 1; +		game_tick(); +	}; + +	render_chunks_frame(); +}; + +fn game_tick() void = { +	player_tick(); +}; + +fn loading_is_ready() bool = { +	if (!LOADING_RECEIVED_SPAWN_POSITION) { +		return false; +	}; +	if (GAMEMODE == Gamemode::SPECTATOR || DEATH_SHOWN) { +		return true; +	}; +	const min_y = CHUNKS_MIN_Y: f32 * 16.0; +	const max_y = min_y + CHUNKS_HEIGHT: f32 * 16.0 + 1.0; +	if (PLAYER_POS[1] < min_y || PLAYER_POS[1] >= max_y) { +		return true; +	}; +	const player_chunk_pos = ChunkPos { +		x = PLAYER_POS[0]: i32 >> 4, +		z = PLAYER_POS[2]: i32 >> 4, +	}; +	if (getchunk(player_chunk_pos) is *Chunk) { +		// TODO: query render status. infeasible at the moment due to +		// dumb chunk update order. +		return true; +	}; +	return false; +}; + +const LAYER_GAME = Layer { +	blocks_input = &layer_game_blocks_input, +	input = &layer_game_input, +	is_opaque = &layer_game_is_opaque, +	render = &layer_game_render, +}; + +fn layer_game_blocks_input() bool = { +	return true; +}; + +fn layer_game_input(event: InputEvent) bool = { +	control_input(event); +	return true; +}; + +fn layer_game_is_opaque() bool = { +	return true; +}; + +fn layer_game_render() void = { +	if (CLIENT_STATE != ClientState::GAME) { +		return; +	}; + +	const fovy = 70.0f32; + +	let (width, height) = drawable_size(); +	glViewport(0, 0, width: i32, height: i32); + +	let view = glm::m4_new_ident(); +	glm::translate(&view, &({ +		let neg_pos = PLAYER_POS; +		neg_pos = glm::v3_sub(&neg_pos, &[ +			CHUNKS_POS.x: f32 * 16.0, +			0.0, +			CHUNKS_POS.z: f32 * 16.0, +		]); +		glm::v3_negate(&neg_pos); +		yield neg_pos; +	})); +	// the angle here should be negated, as the view transform is the +	// inverse of the camera transform, except for, contrary to mathematical +	// convention, Minecraft's "yaw" is positive-clockwise (as seen from +	// above), so we get two negations. +	glm::rotate(&view, glm::rad(PLAYER_YAW), &glm::v3_new(0.0, 1.0, 0.0)); +	// then we need to rotate by 180°, since a yaw of 0 means the player is +	// looking towards the +Z direction, but forward in view space is +	// actually -Z. +	glm::scale(&view, &glm::v3_new(-1.0, 1.0, -1.0)); +	// whether or not pitch goes against convention too is dependent on your +	// perspective, but since we've already rotated by 180° about Y, in our +	// case it does. +	glm::rotate(&view, glm::rad(PLAYER_PITCH), &glm::v3_new(1.0, 0.0, 0.0)); + +	glClearColor(0.033, 0.01, 1.0, 1.0); +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +	let projection = glm::m4_new_zero(); +	glm::perspective(&projection, +		glm::rad(fovy), width: f32 / height: f32, +		0.1, 4096.0, +	); + +	const view_proj = glm::m4_mul(&projection, &view); + +	glEnable(GL_CULL_FACE); +	glEnable(GL_DEPTH_TEST); +	glDisable(GL_BLEND); + +	render_chunks_render(&view_proj); +}; + +const LAYER_GAME_WAITING = Layer { +	blocks_input = &layer_game_waiting_blocks_input, +	input = &layer_game_waiting_input, +	is_opaque = &layer_game_waiting_is_opaque, +	render = &layer_game_waiting_render, +}; + +fn layer_game_waiting_blocks_input() bool = { +	return CLIENT_STATE == ClientState::GAME && !LOADING_READY; +}; + +fn layer_game_waiting_input(event: InputEvent) bool = { +	return false; +}; + +fn layer_game_waiting_is_opaque() bool = { +	return CLIENT_STATE == ClientState::GAME && !LOADING_READY; +}; + +fn layer_game_waiting_render() void = { +	if (CLIENT_STATE != ClientState::GAME || LOADING_READY) { +		return; +	}; + +	render_wait_screen("Loading terrain..."); +}; diff --git a/gl/gl.ha b/gl/gl.ha new file mode 100644 index 0000000..0d50ada --- /dev/null +++ b/gl/gl.ha @@ -0,0 +1,6059 @@ +use types; +use types::c::{char}; + +// Types +export type gl_enum = uint; +export type gl_bitfield = uint; + +export type GLDEBUGPROC = nullable *fn( +	source: gl_enum, +	type_: gl_enum, +	id: uint, +	severity: gl_enum, +	length: i32, +	message: nullable *const char, +	userParam: nullable *opaque +) void; +export type GLDEBUGPROCARB = nullable *fn( +	source: gl_enum, +	type_: gl_enum, +	id: uint, +	severity: gl_enum, +	length: i32, +	message: nullable *const char, +	userParam: nullable *opaque +) void; +export type GLDEBUGPROCKHR = nullable *fn( +	source: gl_enum, +	type_: gl_enum, +	id: uint, +	severity: gl_enum, +	length: i32, +	message: nullable *const char, +	userParam: nullable *opaque +) void; +export type GLDEBUGPROCAMD = nullable *fn( +	id: uint, +	category: gl_enum, +	severity: gl_enum, +	length: i32, +	message: nullable *const char, +	userParam: nullable *opaque +) void; +export type GLVULKANPROCNV = nullable *fn() void; + +// Constants +export def GL_3DC_XY_AMD: uint = 0x87FA; +export def GL_3DC_X_AMD: uint = 0x87F9; +export def GL_ACCUM_ADJACENT_PAIRS_NV: uint = 0x90AD; +export def GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: uint = 0x92D9; +export def GL_ACTIVE_ATTRIBUTES: uint = 0x8B89; +export def GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: uint = 0x8B8A; +export def GL_ACTIVE_PROGRAM: uint = 0x8259; +export def GL_ACTIVE_PROGRAM_EXT: uint = 0x8259; +export def GL_ACTIVE_RESOURCES: uint = 0x92F5; +export def GL_ACTIVE_TEXTURE: uint = 0x84E0; +export def GL_ACTIVE_UNIFORMS: uint = 0x8B86; +export def GL_ACTIVE_UNIFORM_BLOCKS: uint = 0x8A36; +export def GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: uint = 0x8A35; +export def GL_ACTIVE_UNIFORM_MAX_LENGTH: uint = 0x8B87; +export def GL_ACTIVE_VARIABLES: uint = 0x9305; +export def GL_ADJACENT_PAIRS_NV: uint = 0x90AE; +export def GL_AFFINE_2D_NV: uint = 0x9092; +export def GL_AFFINE_3D_NV: uint = 0x9094; +export def GL_ALIASED_LINE_WIDTH_RANGE: uint = 0x846E; +export def GL_ALIASED_POINT_SIZE_RANGE: uint = 0x846D; +export def GL_ALL_BARRIER_BITS: uint = 0xFFFFFFFF; +export def GL_ALL_COMPLETED_NV: uint = 0x84F2; +export def GL_ALL_SHADER_BITS: uint = 0xFFFFFFFF; +export def GL_ALL_SHADER_BITS_EXT: uint = 0xFFFFFFFF; +export def GL_ALPHA: uint = 0x1906; +export def GL_ALPHA16F_EXT: uint = 0x881C; +export def GL_ALPHA32F_EXT: uint = 0x8816; +export def GL_ALPHA8_EXT: uint = 0x803C; +export def GL_ALPHA8_OES: uint = 0x803C; +export def GL_ALPHA_BITS: uint = 0x0D55; +export def GL_ALPHA_TEST_FUNC_QCOM: uint = 0x0BC1; +export def GL_ALPHA_TEST_QCOM: uint = 0x0BC0; +export def GL_ALPHA_TEST_REF_QCOM: uint = 0x0BC2; +export def GL_ALREADY_SIGNALED: uint = 0x911A; +export def GL_ALREADY_SIGNALED_APPLE: uint = 0x911A; +export def GL_ALWAYS: uint = 0x0207; +export def GL_ANY_SAMPLES_PASSED: uint = 0x8C2F; +export def GL_ANY_SAMPLES_PASSED_CONSERVATIVE: uint = 0x8D6A; +export def GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: uint = 0x8D6A; +export def GL_ANY_SAMPLES_PASSED_EXT: uint = 0x8C2F; +export def GL_ARC_TO_NV: uint = 0xFE; +export def GL_ARRAY_BUFFER: uint = 0x8892; +export def GL_ARRAY_BUFFER_BINDING: uint = 0x8894; +export def GL_ARRAY_SIZE: uint = 0x92FB; +export def GL_ARRAY_STRIDE: uint = 0x92FE; +export def GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: uint = 0x8C93; +export def GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: uint = 0x87EE; +export def GL_ATC_RGB_AMD: uint = 0x8C92; +export def GL_ATOMIC_COUNTER_BARRIER_BIT: uint = 0x00001000; +export def GL_ATOMIC_COUNTER_BUFFER: uint = 0x92C0; +export def GL_ATOMIC_COUNTER_BUFFER_BINDING: uint = 0x92C1; +export def GL_ATOMIC_COUNTER_BUFFER_INDEX: uint = 0x9301; +export def GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV: uint = 0x959E; +export def GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV: uint = 0x959F; +export def GL_ATOMIC_COUNTER_BUFFER_SIZE: uint = 0x92C3; +export def GL_ATOMIC_COUNTER_BUFFER_START: uint = 0x92C2; +export def GL_ATTACHED_MEMORY_OBJECT_NV: uint = 0x95A4; +export def GL_ATTACHED_MEMORY_OFFSET_NV: uint = 0x95A5; +export def GL_ATTACHED_SHADERS: uint = 0x8B85; +export def GL_BACK: uint = 0x0405; +export def GL_BEVEL_NV: uint = 0x90A6; +export def GL_BGRA8_EXT: uint = 0x93A1; +export def GL_BGRA_EXT: uint = 0x80E1; +export def GL_BGRA_IMG: uint = 0x80E1; +export def GL_BGR_EXT: uint = 0x80E0; +export def GL_BINNING_CONTROL_HINT_QCOM: uint = 0x8FB0; +export def GL_BLACKHOLE_RENDER_INTEL: uint = 0x83FC; +export def GL_BLEND: uint = 0x0BE2; +export def GL_BLEND_ADVANCED_COHERENT_KHR: uint = 0x9285; +export def GL_BLEND_ADVANCED_COHERENT_NV: uint = 0x9285; +export def GL_BLEND_COLOR: uint = 0x8005; +export def GL_BLEND_DST_ALPHA: uint = 0x80CA; +export def GL_BLEND_DST_RGB: uint = 0x80C8; +export def GL_BLEND_EQUATION: uint = 0x8009; +export def GL_BLEND_EQUATION_ALPHA: uint = 0x883D; +export def GL_BLEND_EQUATION_RGB: uint = 0x8009; +export def GL_BLEND_OVERLAP_NV: uint = 0x9281; +export def GL_BLEND_PREMULTIPLIED_SRC_NV: uint = 0x9280; +export def GL_BLEND_SRC_ALPHA: uint = 0x80CB; +export def GL_BLEND_SRC_RGB: uint = 0x80C9; +export def GL_BLOCK_INDEX: uint = 0x92FD; +export def GL_BLUE: uint = 0x1905; +export def GL_BLUE_BITS: uint = 0x0D54; +export def GL_BLUE_NV: uint = 0x1905; +export def GL_BOLD_BIT_NV: uint = 0x01; +export def GL_BOOL: uint = 0x8B56; +export def GL_BOOL_VEC2: uint = 0x8B57; +export def GL_BOOL_VEC3: uint = 0x8B58; +export def GL_BOOL_VEC4: uint = 0x8B59; +export def GL_BOUNDING_BOX_NV: uint = 0x908D; +export def GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV: uint = 0x909C; +export def GL_BUFFER: uint = 0x82E0; +export def GL_BUFFER_ACCESS_FLAGS: uint = 0x911F; +export def GL_BUFFER_ACCESS_OES: uint = 0x88BB; +export def GL_BUFFER_BINDING: uint = 0x9302; +export def GL_BUFFER_DATA_SIZE: uint = 0x9303; +export def GL_BUFFER_IMMUTABLE_STORAGE_EXT: uint = 0x821F; +export def GL_BUFFER_KHR: uint = 0x82E0; +export def GL_BUFFER_MAPPED: uint = 0x88BC; +export def GL_BUFFER_MAPPED_OES: uint = 0x88BC; +export def GL_BUFFER_MAP_LENGTH: uint = 0x9120; +export def GL_BUFFER_MAP_OFFSET: uint = 0x9121; +export def GL_BUFFER_MAP_POINTER: uint = 0x88BD; +export def GL_BUFFER_MAP_POINTER_OES: uint = 0x88BD; +export def GL_BUFFER_OBJECT_EXT: uint = 0x9151; +export def GL_BUFFER_SIZE: uint = 0x8764; +export def GL_BUFFER_STORAGE_FLAGS_EXT: uint = 0x8220; +export def GL_BUFFER_UPDATE_BARRIER_BIT: uint = 0x00000200; +export def GL_BUFFER_USAGE: uint = 0x8765; +export def GL_BUFFER_VARIABLE: uint = 0x92E5; +export def GL_BYTE: uint = 0x1400; +export def GL_CCW: uint = 0x0901; +export def GL_CIRCULAR_CCW_ARC_TO_NV: uint = 0xF8; +export def GL_CIRCULAR_CW_ARC_TO_NV: uint = 0xFA; +export def GL_CIRCULAR_TANGENT_ARC_TO_NV: uint = 0xFC; +export def GL_CLAMP_TO_BORDER: uint = 0x812D; +export def GL_CLAMP_TO_BORDER_EXT: uint = 0x812D; +export def GL_CLAMP_TO_BORDER_NV: uint = 0x812D; +export def GL_CLAMP_TO_BORDER_OES: uint = 0x812D; +export def GL_CLAMP_TO_EDGE: uint = 0x812F; +export def GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT: uint = 0x00004000; +export def GL_CLIENT_STORAGE_BIT_EXT: uint = 0x0200; +export def GL_CLIP_DEPTH_MODE: uint = 0x935D; +export def GL_CLIP_DEPTH_MODE_EXT: uint = 0x935D; +export def GL_CLIP_DISTANCE0_APPLE: uint = 0x3000; +export def GL_CLIP_DISTANCE0_EXT: uint = 0x3000; +export def GL_CLIP_DISTANCE1_APPLE: uint = 0x3001; +export def GL_CLIP_DISTANCE1_EXT: uint = 0x3001; +export def GL_CLIP_DISTANCE2_APPLE: uint = 0x3002; +export def GL_CLIP_DISTANCE2_EXT: uint = 0x3002; +export def GL_CLIP_DISTANCE3_APPLE: uint = 0x3003; +export def GL_CLIP_DISTANCE3_EXT: uint = 0x3003; +export def GL_CLIP_DISTANCE4_APPLE: uint = 0x3004; +export def GL_CLIP_DISTANCE4_EXT: uint = 0x3004; +export def GL_CLIP_DISTANCE5_APPLE: uint = 0x3005; +export def GL_CLIP_DISTANCE5_EXT: uint = 0x3005; +export def GL_CLIP_DISTANCE6: uint = 0x3006; +export def GL_CLIP_DISTANCE6_APPLE: uint = 0x3006; +export def GL_CLIP_DISTANCE6_EXT: uint = 0x3006; +export def GL_CLIP_DISTANCE7: uint = 0x3007; +export def GL_CLIP_DISTANCE7_APPLE: uint = 0x3007; +export def GL_CLIP_DISTANCE7_EXT: uint = 0x3007; +export def GL_CLIP_ORIGIN: uint = 0x935C; +export def GL_CLIP_ORIGIN_EXT: uint = 0x935C; +export def GL_CLIP_PLANE0: uint = 0x3000; +export def GL_CLIP_PLANE1: uint = 0x3001; +export def GL_CLIP_PLANE2: uint = 0x3002; +export def GL_CLIP_PLANE3: uint = 0x3003; +export def GL_CLIP_PLANE4: uint = 0x3004; +export def GL_CLIP_PLANE5: uint = 0x3005; +export def GL_CLOSE_PATH_NV: uint = 0x00; +export def GL_COLOR: uint = 0x1800; +export def GL_COLORBURN: uint = 0x929A; +export def GL_COLORBURN_KHR: uint = 0x929A; +export def GL_COLORBURN_NV: uint = 0x929A; +export def GL_COLORDODGE: uint = 0x9299; +export def GL_COLORDODGE_KHR: uint = 0x9299; +export def GL_COLORDODGE_NV: uint = 0x9299; +export def GL_COLOR_ATTACHMENT0: uint = 0x8CE0; +export def GL_COLOR_ATTACHMENT0_EXT: uint = 0x8CE0; +export def GL_COLOR_ATTACHMENT0_NV: uint = 0x8CE0; +export def GL_COLOR_ATTACHMENT1: uint = 0x8CE1; +export def GL_COLOR_ATTACHMENT10: uint = 0x8CEA; +export def GL_COLOR_ATTACHMENT10_EXT: uint = 0x8CEA; +export def GL_COLOR_ATTACHMENT10_NV: uint = 0x8CEA; +export def GL_COLOR_ATTACHMENT11: uint = 0x8CEB; +export def GL_COLOR_ATTACHMENT11_EXT: uint = 0x8CEB; +export def GL_COLOR_ATTACHMENT11_NV: uint = 0x8CEB; +export def GL_COLOR_ATTACHMENT12: uint = 0x8CEC; +export def GL_COLOR_ATTACHMENT12_EXT: uint = 0x8CEC; +export def GL_COLOR_ATTACHMENT12_NV: uint = 0x8CEC; +export def GL_COLOR_ATTACHMENT13: uint = 0x8CED; +export def GL_COLOR_ATTACHMENT13_EXT: uint = 0x8CED; +export def GL_COLOR_ATTACHMENT13_NV: uint = 0x8CED; +export def GL_COLOR_ATTACHMENT14: uint = 0x8CEE; +export def GL_COLOR_ATTACHMENT14_EXT: uint = 0x8CEE; +export def GL_COLOR_ATTACHMENT14_NV: uint = 0x8CEE; +export def GL_COLOR_ATTACHMENT15: uint = 0x8CEF; +export def GL_COLOR_ATTACHMENT15_EXT: uint = 0x8CEF; +export def GL_COLOR_ATTACHMENT15_NV: uint = 0x8CEF; +export def GL_COLOR_ATTACHMENT16: uint = 0x8CF0; +export def GL_COLOR_ATTACHMENT17: uint = 0x8CF1; +export def GL_COLOR_ATTACHMENT18: uint = 0x8CF2; +export def GL_COLOR_ATTACHMENT19: uint = 0x8CF3; +export def GL_COLOR_ATTACHMENT1_EXT: uint = 0x8CE1; +export def GL_COLOR_ATTACHMENT1_NV: uint = 0x8CE1; +export def GL_COLOR_ATTACHMENT2: uint = 0x8CE2; +export def GL_COLOR_ATTACHMENT20: uint = 0x8CF4; +export def GL_COLOR_ATTACHMENT21: uint = 0x8CF5; +export def GL_COLOR_ATTACHMENT22: uint = 0x8CF6; +export def GL_COLOR_ATTACHMENT23: uint = 0x8CF7; +export def GL_COLOR_ATTACHMENT24: uint = 0x8CF8; +export def GL_COLOR_ATTACHMENT25: uint = 0x8CF9; +export def GL_COLOR_ATTACHMENT26: uint = 0x8CFA; +export def GL_COLOR_ATTACHMENT27: uint = 0x8CFB; +export def GL_COLOR_ATTACHMENT28: uint = 0x8CFC; +export def GL_COLOR_ATTACHMENT29: uint = 0x8CFD; +export def GL_COLOR_ATTACHMENT2_EXT: uint = 0x8CE2; +export def GL_COLOR_ATTACHMENT2_NV: uint = 0x8CE2; +export def GL_COLOR_ATTACHMENT3: uint = 0x8CE3; +export def GL_COLOR_ATTACHMENT30: uint = 0x8CFE; +export def GL_COLOR_ATTACHMENT31: uint = 0x8CFF; +export def GL_COLOR_ATTACHMENT3_EXT: uint = 0x8CE3; +export def GL_COLOR_ATTACHMENT3_NV: uint = 0x8CE3; +export def GL_COLOR_ATTACHMENT4: uint = 0x8CE4; +export def GL_COLOR_ATTACHMENT4_EXT: uint = 0x8CE4; +export def GL_COLOR_ATTACHMENT4_NV: uint = 0x8CE4; +export def GL_COLOR_ATTACHMENT5: uint = 0x8CE5; +export def GL_COLOR_ATTACHMENT5_EXT: uint = 0x8CE5; +export def GL_COLOR_ATTACHMENT5_NV: uint = 0x8CE5; +export def GL_COLOR_ATTACHMENT6: uint = 0x8CE6; +export def GL_COLOR_ATTACHMENT6_EXT: uint = 0x8CE6; +export def GL_COLOR_ATTACHMENT6_NV: uint = 0x8CE6; +export def GL_COLOR_ATTACHMENT7: uint = 0x8CE7; +export def GL_COLOR_ATTACHMENT7_EXT: uint = 0x8CE7; +export def GL_COLOR_ATTACHMENT7_NV: uint = 0x8CE7; +export def GL_COLOR_ATTACHMENT8: uint = 0x8CE8; +export def GL_COLOR_ATTACHMENT8_EXT: uint = 0x8CE8; +export def GL_COLOR_ATTACHMENT8_NV: uint = 0x8CE8; +export def GL_COLOR_ATTACHMENT9: uint = 0x8CE9; +export def GL_COLOR_ATTACHMENT9_EXT: uint = 0x8CE9; +export def GL_COLOR_ATTACHMENT9_NV: uint = 0x8CE9; +export def GL_COLOR_ATTACHMENT_EXT: uint = 0x90F0; +export def GL_COLOR_BUFFER_BIT: uint = 0x00004000; +export def GL_COLOR_BUFFER_BIT0_QCOM: uint = 0x00000001; +export def GL_COLOR_BUFFER_BIT1_QCOM: uint = 0x00000002; +export def GL_COLOR_BUFFER_BIT2_QCOM: uint = 0x00000004; +export def GL_COLOR_BUFFER_BIT3_QCOM: uint = 0x00000008; +export def GL_COLOR_BUFFER_BIT4_QCOM: uint = 0x00000010; +export def GL_COLOR_BUFFER_BIT5_QCOM: uint = 0x00000020; +export def GL_COLOR_BUFFER_BIT6_QCOM: uint = 0x00000040; +export def GL_COLOR_BUFFER_BIT7_QCOM: uint = 0x00000080; +export def GL_COLOR_CLEAR_VALUE: uint = 0x0C22; +export def GL_COLOR_EXT: uint = 0x1800; +export def GL_COLOR_SAMPLES_NV: uint = 0x8E20; +export def GL_COLOR_WRITEMASK: uint = 0x0C23; +export def GL_COMMAND_BARRIER_BIT: uint = 0x00000040; +export def GL_COMPARE_REF_TO_TEXTURE: uint = 0x884E; +export def GL_COMPARE_REF_TO_TEXTURE_EXT: uint = 0x884E; +export def GL_COMPARE_R_TO_TEXTURE: uint = 0x884E; +export def GL_COMPILE_STATUS: uint = 0x8B81; +export def GL_COMPLETION_STATUS_KHR: uint = 0x91B1; +export def GL_COMPRESSED_R11_EAC: uint = 0x9270; +export def GL_COMPRESSED_RED_GREEN_RGTC2_EXT: uint = 0x8DBD; +export def GL_COMPRESSED_RED_RGTC1_EXT: uint = 0x8DBB; +export def GL_COMPRESSED_RG11_EAC: uint = 0x9272; +export def GL_COMPRESSED_RGB8_ETC2: uint = 0x9274; +export def GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: uint = 0x9276; +export def GL_COMPRESSED_RGBA8_ETC2_EAC: uint = 0x9278; +export def GL_COMPRESSED_RGBA_ASTC_10x10: uint = 0x93BB; +export def GL_COMPRESSED_RGBA_ASTC_10x10_KHR: uint = 0x93BB; +export def GL_COMPRESSED_RGBA_ASTC_10x5: uint = 0x93B8; +export def GL_COMPRESSED_RGBA_ASTC_10x5_KHR: uint = 0x93B8; +export def GL_COMPRESSED_RGBA_ASTC_10x6: uint = 0x93B9; +export def GL_COMPRESSED_RGBA_ASTC_10x6_KHR: uint = 0x93B9; +export def GL_COMPRESSED_RGBA_ASTC_10x8: uint = 0x93BA; +export def GL_COMPRESSED_RGBA_ASTC_10x8_KHR: uint = 0x93BA; +export def GL_COMPRESSED_RGBA_ASTC_12x10: uint = 0x93BC; +export def GL_COMPRESSED_RGBA_ASTC_12x10_KHR: uint = 0x93BC; +export def GL_COMPRESSED_RGBA_ASTC_12x12: uint = 0x93BD; +export def GL_COMPRESSED_RGBA_ASTC_12x12_KHR: uint = 0x93BD; +export def GL_COMPRESSED_RGBA_ASTC_3x3x3_OES: uint = 0x93C0; +export def GL_COMPRESSED_RGBA_ASTC_4x3x3_OES: uint = 0x93C1; +export def GL_COMPRESSED_RGBA_ASTC_4x4: uint = 0x93B0; +export def GL_COMPRESSED_RGBA_ASTC_4x4_KHR: uint = 0x93B0; +export def GL_COMPRESSED_RGBA_ASTC_4x4x3_OES: uint = 0x93C2; +export def GL_COMPRESSED_RGBA_ASTC_4x4x4_OES: uint = 0x93C3; +export def GL_COMPRESSED_RGBA_ASTC_5x4: uint = 0x93B1; +export def GL_COMPRESSED_RGBA_ASTC_5x4_KHR: uint = 0x93B1; +export def GL_COMPRESSED_RGBA_ASTC_5x4x4_OES: uint = 0x93C4; +export def GL_COMPRESSED_RGBA_ASTC_5x5: uint = 0x93B2; +export def GL_COMPRESSED_RGBA_ASTC_5x5_KHR: uint = 0x93B2; +export def GL_COMPRESSED_RGBA_ASTC_5x5x4_OES: uint = 0x93C5; +export def GL_COMPRESSED_RGBA_ASTC_5x5x5_OES: uint = 0x93C6; +export def GL_COMPRESSED_RGBA_ASTC_6x5: uint = 0x93B3; +export def GL_COMPRESSED_RGBA_ASTC_6x5_KHR: uint = 0x93B3; +export def GL_COMPRESSED_RGBA_ASTC_6x5x5_OES: uint = 0x93C7; +export def GL_COMPRESSED_RGBA_ASTC_6x6: uint = 0x93B4; +export def GL_COMPRESSED_RGBA_ASTC_6x6_KHR: uint = 0x93B4; +export def GL_COMPRESSED_RGBA_ASTC_6x6x5_OES: uint = 0x93C8; +export def GL_COMPRESSED_RGBA_ASTC_6x6x6_OES: uint = 0x93C9; +export def GL_COMPRESSED_RGBA_ASTC_8x5: uint = 0x93B5; +export def GL_COMPRESSED_RGBA_ASTC_8x5_KHR: uint = 0x93B5; +export def GL_COMPRESSED_RGBA_ASTC_8x6: uint = 0x93B6; +export def GL_COMPRESSED_RGBA_ASTC_8x6_KHR: uint = 0x93B6; +export def GL_COMPRESSED_RGBA_ASTC_8x8: uint = 0x93B7; +export def GL_COMPRESSED_RGBA_ASTC_8x8_KHR: uint = 0x93B7; +export def GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: uint = 0x8E8C; +export def GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: uint = 0x8C03; +export def GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG: uint = 0x9137; +export def GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: uint = 0x8C02; +export def GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG: uint = 0x9138; +export def GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: uint = 0x83F1; +export def GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: uint = 0x83F2; +export def GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: uint = 0x83F2; +export def GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: uint = 0x83F3; +export def GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: uint = 0x83F3; +export def GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: uint = 0x8E8E; +export def GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: uint = 0x8E8F; +export def GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: uint = 0x8C01; +export def GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: uint = 0x8C00; +export def GL_COMPRESSED_RGB_S3TC_DXT1_EXT: uint = 0x83F0; +export def GL_COMPRESSED_SIGNED_R11_EAC: uint = 0x9271; +export def GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: uint = 0x8DBE; +export def GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: uint = 0x8DBC; +export def GL_COMPRESSED_SIGNED_RG11_EAC: uint = 0x9273; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10: uint = 0x93DB; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: uint = 0x93DB; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5: uint = 0x93D8; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: uint = 0x93D8; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6: uint = 0x93D9; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: uint = 0x93D9; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8: uint = 0x93DA; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: uint = 0x93DA; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10: uint = 0x93DC; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: uint = 0x93DC; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12: uint = 0x93DD; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: uint = 0x93DD; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES: uint = 0x93E0; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES: uint = 0x93E1; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4: uint = 0x93D0; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: uint = 0x93D0; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES: uint = 0x93E2; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES: uint = 0x93E3; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4: uint = 0x93D1; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: uint = 0x93D1; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES: uint = 0x93E4; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5: uint = 0x93D2; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: uint = 0x93D2; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES: uint = 0x93E5; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES: uint = 0x93E6; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5: uint = 0x93D3; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: uint = 0x93D3; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES: uint = 0x93E7; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6: uint = 0x93D4; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: uint = 0x93D4; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES: uint = 0x93E8; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: uint = 0x93E9; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5: uint = 0x93D5; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: uint = 0x93D5; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6: uint = 0x93D6; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: uint = 0x93D6; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8: uint = 0x93D7; +export def GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: uint = 0x93D7; +export def GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: uint = 0x9279; +export def GL_COMPRESSED_SRGB8_ETC2: uint = 0x9275; +export def GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: uint = 0x9277; +export def GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: uint = 0x8E8D; +export def GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: uint = 0x8A56; +export def GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG: uint = 0x93F0; +export def GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: uint = 0x8A57; +export def GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG: uint = 0x93F1; +export def GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: uint = 0x8C4D; +export def GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV: uint = 0x8C4D; +export def GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: uint = 0x8C4E; +export def GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV: uint = 0x8C4E; +export def GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: uint = 0x8C4F; +export def GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV: uint = 0x8C4F; +export def GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: uint = 0x8A54; +export def GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: uint = 0x8A55; +export def GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: uint = 0x8C4C; +export def GL_COMPRESSED_SRGB_S3TC_DXT1_NV: uint = 0x8C4C; +export def GL_COMPRESSED_TEXTURE_FORMATS: uint = 0x86A3; +export def GL_COMPUTE_SHADER: uint = 0x91B9; +export def GL_COMPUTE_SHADER_BIT: uint = 0x00000020; +export def GL_COMPUTE_WORK_GROUP_SIZE: uint = 0x8267; +export def GL_CONDITION_SATISFIED: uint = 0x911C; +export def GL_CONDITION_SATISFIED_APPLE: uint = 0x911C; +export def GL_CONFORMANT_NV: uint = 0x9374; +export def GL_CONIC_CURVE_TO_NV: uint = 0x1A; +export def GL_CONJOINT_NV: uint = 0x9284; +export def GL_CONSERVATIVE_RASTERIZATION_INTEL: uint = 0x83FE; +export def GL_CONSERVATIVE_RASTERIZATION_NV: uint = 0x9346; +export def GL_CONSERVATIVE_RASTER_MODE_NV: uint = 0x954D; +export def GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV: uint = 0x954E; +export def GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV: uint = 0x9550; +export def GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV: uint = 0x954F; +export def GL_CONSTANT_ALPHA: uint = 0x8003; +export def GL_CONSTANT_COLOR: uint = 0x8001; +export def GL_CONTEXT_FLAGS: uint = 0x821E; +export def GL_CONTEXT_FLAG_DEBUG_BIT: uint = 0x00000002; +export def GL_CONTEXT_FLAG_DEBUG_BIT_KHR: uint = 0x00000002; +export def GL_CONTEXT_FLAG_NO_ERROR_BIT: uint = 0x00000008; +export def GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR: uint = 0x00000008; +export def GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT: uint = 0x00000010; +export def GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT: uint = 0x00000004; +export def GL_CONTEXT_LOST: uint = 0x0507; +export def GL_CONTEXT_LOST_KHR: uint = 0x0507; +export def GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR: uint = 0x82FC; +export def GL_CONTEXT_RELEASE_BEHAVIOR_KHR: uint = 0x82FB; +export def GL_CONTEXT_ROBUST_ACCESS_EXT: uint = 0x90F3; +export def GL_CONTEXT_ROBUST_ACCESS_KHR: uint = 0x90F3; +export def GL_CONTRAST_NV: uint = 0x92A1; +export def GL_CONVEX_HULL_NV: uint = 0x908B; +export def GL_COPY_READ_BUFFER: uint = 0x8F36; +export def GL_COPY_READ_BUFFER_BINDING: uint = 0x8F36; +export def GL_COPY_READ_BUFFER_NV: uint = 0x8F36; +export def GL_COPY_WRITE_BUFFER: uint = 0x8F37; +export def GL_COPY_WRITE_BUFFER_BINDING: uint = 0x8F37; +export def GL_COPY_WRITE_BUFFER_NV: uint = 0x8F37; +export def GL_COUNTER_RANGE_AMD: uint = 0x8BC1; +export def GL_COUNTER_TYPE_AMD: uint = 0x8BC0; +export def GL_COUNT_DOWN_NV: uint = 0x9089; +export def GL_COUNT_UP_NV: uint = 0x9088; +export def GL_COVERAGE_ALL_FRAGMENTS_NV: uint = 0x8ED5; +export def GL_COVERAGE_ATTACHMENT_NV: uint = 0x8ED2; +export def GL_COVERAGE_AUTOMATIC_NV: uint = 0x8ED7; +export def GL_COVERAGE_BUFFERS_NV: uint = 0x8ED3; +export def GL_COVERAGE_BUFFER_BIT_NV: uint = 0x00008000; +export def GL_COVERAGE_COMPONENT4_NV: uint = 0x8ED1; +export def GL_COVERAGE_COMPONENT_NV: uint = 0x8ED0; +export def GL_COVERAGE_EDGE_FRAGMENTS_NV: uint = 0x8ED6; +export def GL_COVERAGE_MODULATION_NV: uint = 0x9332; +export def GL_COVERAGE_MODULATION_TABLE_NV: uint = 0x9331; +export def GL_COVERAGE_MODULATION_TABLE_SIZE_NV: uint = 0x9333; +export def GL_COVERAGE_SAMPLES_NV: uint = 0x8ED4; +export def GL_CPU_OPTIMIZED_QCOM: uint = 0x8FB1; +export def GL_CUBIC_CURVE_TO_NV: uint = 0x0C; +export def GL_CUBIC_IMG: uint = 0x9139; +export def GL_CUBIC_MIPMAP_LINEAR_IMG: uint = 0x913B; +export def GL_CUBIC_MIPMAP_NEAREST_IMG: uint = 0x913A; +export def GL_CULL_FACE: uint = 0x0B44; +export def GL_CULL_FACE_MODE: uint = 0x0B45; +export def GL_CURRENT_PROGRAM: uint = 0x8B8D; +export def GL_CURRENT_QUERY: uint = 0x8865; +export def GL_CURRENT_QUERY_EXT: uint = 0x8865; +export def GL_CURRENT_VERTEX_ATTRIB: uint = 0x8626; +export def GL_CW: uint = 0x0900; +export def GL_D3D12_FENCE_VALUE_EXT: uint = 0x9595; +export def GL_DARKEN: uint = 0x9297; +export def GL_DARKEN_KHR: uint = 0x9297; +export def GL_DARKEN_NV: uint = 0x9297; +export def GL_DEBUG_CALLBACK_FUNCTION: uint = 0x8244; +export def GL_DEBUG_CALLBACK_FUNCTION_KHR: uint = 0x8244; +export def GL_DEBUG_CALLBACK_USER_PARAM: uint = 0x8245; +export def GL_DEBUG_CALLBACK_USER_PARAM_KHR: uint = 0x8245; +export def GL_DEBUG_GROUP_STACK_DEPTH: uint = 0x826D; +export def GL_DEBUG_GROUP_STACK_DEPTH_KHR: uint = 0x826D; +export def GL_DEBUG_LOGGED_MESSAGES: uint = 0x9145; +export def GL_DEBUG_LOGGED_MESSAGES_KHR: uint = 0x9145; +export def GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH: uint = 0x8243; +export def GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR: uint = 0x8243; +export def GL_DEBUG_OUTPUT: uint = 0x92E0; +export def GL_DEBUG_OUTPUT_KHR: uint = 0x92E0; +export def GL_DEBUG_OUTPUT_SYNCHRONOUS: uint = 0x8242; +export def GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR: uint = 0x8242; +export def GL_DEBUG_SEVERITY_HIGH: uint = 0x9146; +export def GL_DEBUG_SEVERITY_HIGH_KHR: uint = 0x9146; +export def GL_DEBUG_SEVERITY_LOW: uint = 0x9148; +export def GL_DEBUG_SEVERITY_LOW_KHR: uint = 0x9148; +export def GL_DEBUG_SEVERITY_MEDIUM: uint = 0x9147; +export def GL_DEBUG_SEVERITY_MEDIUM_KHR: uint = 0x9147; +export def GL_DEBUG_SEVERITY_NOTIFICATION: uint = 0x826B; +export def GL_DEBUG_SEVERITY_NOTIFICATION_KHR: uint = 0x826B; +export def GL_DEBUG_SOURCE_API: uint = 0x8246; +export def GL_DEBUG_SOURCE_API_KHR: uint = 0x8246; +export def GL_DEBUG_SOURCE_APPLICATION: uint = 0x824A; +export def GL_DEBUG_SOURCE_APPLICATION_KHR: uint = 0x824A; +export def GL_DEBUG_SOURCE_OTHER: uint = 0x824B; +export def GL_DEBUG_SOURCE_OTHER_KHR: uint = 0x824B; +export def GL_DEBUG_SOURCE_SHADER_COMPILER: uint = 0x8248; +export def GL_DEBUG_SOURCE_SHADER_COMPILER_KHR: uint = 0x8248; +export def GL_DEBUG_SOURCE_THIRD_PARTY: uint = 0x8249; +export def GL_DEBUG_SOURCE_THIRD_PARTY_KHR: uint = 0x8249; +export def GL_DEBUG_SOURCE_WINDOW_SYSTEM: uint = 0x8247; +export def GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR: uint = 0x8247; +export def GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: uint = 0x824D; +export def GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR: uint = 0x824D; +export def GL_DEBUG_TYPE_ERROR: uint = 0x824C; +export def GL_DEBUG_TYPE_ERROR_KHR: uint = 0x824C; +export def GL_DEBUG_TYPE_MARKER: uint = 0x8268; +export def GL_DEBUG_TYPE_MARKER_KHR: uint = 0x8268; +export def GL_DEBUG_TYPE_OTHER: uint = 0x8251; +export def GL_DEBUG_TYPE_OTHER_KHR: uint = 0x8251; +export def GL_DEBUG_TYPE_PERFORMANCE: uint = 0x8250; +export def GL_DEBUG_TYPE_PERFORMANCE_KHR: uint = 0x8250; +export def GL_DEBUG_TYPE_POP_GROUP: uint = 0x826A; +export def GL_DEBUG_TYPE_POP_GROUP_KHR: uint = 0x826A; +export def GL_DEBUG_TYPE_PORTABILITY: uint = 0x824F; +export def GL_DEBUG_TYPE_PORTABILITY_KHR: uint = 0x824F; +export def GL_DEBUG_TYPE_PUSH_GROUP: uint = 0x8269; +export def GL_DEBUG_TYPE_PUSH_GROUP_KHR: uint = 0x8269; +export def GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: uint = 0x824E; +export def GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR: uint = 0x824E; +export def GL_DECODE_EXT: uint = 0x8A49; +export def GL_DECR: uint = 0x1E03; +export def GL_DECR_WRAP: uint = 0x8508; +export def GL_DEDICATED_MEMORY_OBJECT_EXT: uint = 0x9581; +export def GL_DELETE_STATUS: uint = 0x8B80; +export def GL_DEPTH: uint = 0x1801; +export def GL_DEPTH24_STENCIL8: uint = 0x88F0; +export def GL_DEPTH24_STENCIL8_OES: uint = 0x88F0; +export def GL_DEPTH32F_STENCIL8: uint = 0x8CAD; +export def GL_DEPTH_ATTACHMENT: uint = 0x8D00; +export def GL_DEPTH_BITS: uint = 0x0D56; +export def GL_DEPTH_BUFFER_BIT: uint = 0x00000100; +export def GL_DEPTH_BUFFER_BIT0_QCOM: uint = 0x00000100; +export def GL_DEPTH_BUFFER_BIT1_QCOM: uint = 0x00000200; +export def GL_DEPTH_BUFFER_BIT2_QCOM: uint = 0x00000400; +export def GL_DEPTH_BUFFER_BIT3_QCOM: uint = 0x00000800; +export def GL_DEPTH_BUFFER_BIT4_QCOM: uint = 0x00001000; +export def GL_DEPTH_BUFFER_BIT5_QCOM: uint = 0x00002000; +export def GL_DEPTH_BUFFER_BIT6_QCOM: uint = 0x00004000; +export def GL_DEPTH_BUFFER_BIT7_QCOM: uint = 0x00008000; +export def GL_DEPTH_CLAMP_EXT: uint = 0x864F; +export def GL_DEPTH_CLEAR_VALUE: uint = 0x0B73; +export def GL_DEPTH_COMPONENT: uint = 0x1902; +export def GL_DEPTH_COMPONENT16: uint = 0x81A5; +export def GL_DEPTH_COMPONENT16_NONLINEAR_NV: uint = 0x8E2C; +export def GL_DEPTH_COMPONENT16_OES: uint = 0x81A5; +export def GL_DEPTH_COMPONENT24: uint = 0x81A6; +export def GL_DEPTH_COMPONENT24_OES: uint = 0x81A6; +export def GL_DEPTH_COMPONENT32F: uint = 0x8CAC; +export def GL_DEPTH_COMPONENT32_OES: uint = 0x81A7; +export def GL_DEPTH_EXT: uint = 0x1801; +export def GL_DEPTH_FUNC: uint = 0x0B74; +export def GL_DEPTH_RANGE: uint = 0x0B70; +export def GL_DEPTH_SAMPLES_NV: uint = 0x932D; +export def GL_DEPTH_STENCIL: uint = 0x84F9; +export def GL_DEPTH_STENCIL_ATTACHMENT: uint = 0x821A; +export def GL_DEPTH_STENCIL_OES: uint = 0x84F9; +export def GL_DEPTH_STENCIL_TEXTURE_MODE: uint = 0x90EA; +export def GL_DEPTH_TEST: uint = 0x0B71; +export def GL_DEPTH_WRITEMASK: uint = 0x0B72; +export def GL_DETACHED_BUFFERS_NV: uint = 0x95AB; +export def GL_DETACHED_MEMORY_INCARNATION_NV: uint = 0x95A9; +export def GL_DETACHED_TEXTURES_NV: uint = 0x95AA; +export def GL_DEVICE_LUID_EXT: uint = 0x9599; +export def GL_DEVICE_NODE_MASK_EXT: uint = 0x959A; +export def GL_DEVICE_UUID_EXT: uint = 0x9597; +export def GL_DIFFERENCE: uint = 0x929E; +export def GL_DIFFERENCE_KHR: uint = 0x929E; +export def GL_DIFFERENCE_NV: uint = 0x929E; +export def GL_DISJOINT_NV: uint = 0x9283; +export def GL_DISPATCH_INDIRECT_BUFFER: uint = 0x90EE; +export def GL_DISPATCH_INDIRECT_BUFFER_BINDING: uint = 0x90EF; +export def GL_DITHER: uint = 0x0BD0; +export def GL_DMP_PROGRAM_BINARY_DMP: uint = 0x9253; +export def GL_DONT_CARE: uint = 0x1100; +export def GL_DOWNSAMPLE_SCALES_IMG: uint = 0x913E; +export def GL_DRAW_BUFFER0: uint = 0x8825; +export def GL_DRAW_BUFFER0_EXT: uint = 0x8825; +export def GL_DRAW_BUFFER0_NV: uint = 0x8825; +export def GL_DRAW_BUFFER1: uint = 0x8826; +export def GL_DRAW_BUFFER10: uint = 0x882F; +export def GL_DRAW_BUFFER10_EXT: uint = 0x882F; +export def GL_DRAW_BUFFER10_NV: uint = 0x882F; +export def GL_DRAW_BUFFER11: uint = 0x8830; +export def GL_DRAW_BUFFER11_EXT: uint = 0x8830; +export def GL_DRAW_BUFFER11_NV: uint = 0x8830; +export def GL_DRAW_BUFFER12: uint = 0x8831; +export def GL_DRAW_BUFFER12_EXT: uint = 0x8831; +export def GL_DRAW_BUFFER12_NV: uint = 0x8831; +export def GL_DRAW_BUFFER13: uint = 0x8832; +export def GL_DRAW_BUFFER13_EXT: uint = 0x8832; +export def GL_DRAW_BUFFER13_NV: uint = 0x8832; +export def GL_DRAW_BUFFER14: uint = 0x8833; +export def GL_DRAW_BUFFER14_EXT: uint = 0x8833; +export def GL_DRAW_BUFFER14_NV: uint = 0x8833; +export def GL_DRAW_BUFFER15: uint = 0x8834; +export def GL_DRAW_BUFFER15_EXT: uint = 0x8834; +export def GL_DRAW_BUFFER15_NV: uint = 0x8834; +export def GL_DRAW_BUFFER1_EXT: uint = 0x8826; +export def GL_DRAW_BUFFER1_NV: uint = 0x8826; +export def GL_DRAW_BUFFER2: uint = 0x8827; +export def GL_DRAW_BUFFER2_EXT: uint = 0x8827; +export def GL_DRAW_BUFFER2_NV: uint = 0x8827; +export def GL_DRAW_BUFFER3: uint = 0x8828; +export def GL_DRAW_BUFFER3_EXT: uint = 0x8828; +export def GL_DRAW_BUFFER3_NV: uint = 0x8828; +export def GL_DRAW_BUFFER4: uint = 0x8829; +export def GL_DRAW_BUFFER4_EXT: uint = 0x8829; +export def GL_DRAW_BUFFER4_NV: uint = 0x8829; +export def GL_DRAW_BUFFER5: uint = 0x882A; +export def GL_DRAW_BUFFER5_EXT: uint = 0x882A; +export def GL_DRAW_BUFFER5_NV: uint = 0x882A; +export def GL_DRAW_BUFFER6: uint = 0x882B; +export def GL_DRAW_BUFFER6_EXT: uint = 0x882B; +export def GL_DRAW_BUFFER6_NV: uint = 0x882B; +export def GL_DRAW_BUFFER7: uint = 0x882C; +export def GL_DRAW_BUFFER7_EXT: uint = 0x882C; +export def GL_DRAW_BUFFER7_NV: uint = 0x882C; +export def GL_DRAW_BUFFER8: uint = 0x882D; +export def GL_DRAW_BUFFER8_EXT: uint = 0x882D; +export def GL_DRAW_BUFFER8_NV: uint = 0x882D; +export def GL_DRAW_BUFFER9: uint = 0x882E; +export def GL_DRAW_BUFFER9_EXT: uint = 0x882E; +export def GL_DRAW_BUFFER9_NV: uint = 0x882E; +export def GL_DRAW_BUFFER_EXT: uint = 0x0C01; +export def GL_DRAW_FRAMEBUFFER: uint = 0x8CA9; +export def GL_DRAW_FRAMEBUFFER_ANGLE: uint = 0x8CA9; +export def GL_DRAW_FRAMEBUFFER_APPLE: uint = 0x8CA9; +export def GL_DRAW_FRAMEBUFFER_BINDING: uint = 0x8CA6; +export def GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: uint = 0x8CA6; +export def GL_DRAW_FRAMEBUFFER_BINDING_APPLE: uint = 0x8CA6; +export def GL_DRAW_FRAMEBUFFER_BINDING_NV: uint = 0x8CA6; +export def GL_DRAW_FRAMEBUFFER_NV: uint = 0x8CA9; +export def GL_DRAW_INDIRECT_BUFFER: uint = 0x8F3F; +export def GL_DRAW_INDIRECT_BUFFER_BINDING: uint = 0x8F43; +export def GL_DRIVER_UUID_EXT: uint = 0x9598; +export def GL_DST_ALPHA: uint = 0x0304; +export def GL_DST_ATOP_NV: uint = 0x928F; +export def GL_DST_COLOR: uint = 0x0306; +export def GL_DST_IN_NV: uint = 0x928B; +export def GL_DST_NV: uint = 0x9287; +export def GL_DST_OUT_NV: uint = 0x928D; +export def GL_DST_OVER_NV: uint = 0x9289; +export def GL_DUP_FIRST_CUBIC_CURVE_TO_NV: uint = 0xF2; +export def GL_DUP_LAST_CUBIC_CURVE_TO_NV: uint = 0xF4; +export def GL_DYNAMIC_COPY: uint = 0x88EA; +export def GL_DYNAMIC_DRAW: uint = 0x88E8; +export def GL_DYNAMIC_READ: uint = 0x88E9; +export def GL_DYNAMIC_STORAGE_BIT_EXT: uint = 0x0100; +export def GL_EFFECTIVE_RASTER_SAMPLES_EXT: uint = 0x932C; +export def GL_ELEMENT_ARRAY_BARRIER_BIT: uint = 0x00000002; +export def GL_ELEMENT_ARRAY_BUFFER: uint = 0x8893; +export def GL_ELEMENT_ARRAY_BUFFER_BINDING: uint = 0x8895; +export def GL_EQUAL: uint = 0x0202; +export def GL_ETC1_RGB8_OES: uint = 0x8D64; +export def GL_ETC1_SRGB8_NV: uint = 0x88EE; +export def GL_EXCLUSION: uint = 0x92A0; +export def GL_EXCLUSION_KHR: uint = 0x92A0; +export def GL_EXCLUSION_NV: uint = 0x92A0; +export def GL_EXCLUSIVE_EXT: uint = 0x8F11; +export def GL_EXTENSIONS: uint = 0x1F03; +export def GL_FACTOR_MAX_AMD: uint = 0x901D; +export def GL_FACTOR_MIN_AMD: uint = 0x901C; +export def GL_FALSE: u8 = 0; +export def GL_FASTEST: uint = 0x1101; +export def GL_FENCE_CONDITION_NV: uint = 0x84F4; +export def GL_FENCE_STATUS_NV: uint = 0x84F3; +export def GL_FETCH_PER_SAMPLE_ARM: uint = 0x8F65; +export def GL_FILE_NAME_NV: uint = 0x9074; +export def GL_FILL_NV: uint = 0x1B02; +export def GL_FILL_RECTANGLE_NV: uint = 0x933C; +export def GL_FIRST_TO_REST_NV: uint = 0x90AF; +export def GL_FIRST_VERTEX_CONVENTION: uint = 0x8E4D; +export def GL_FIRST_VERTEX_CONVENTION_EXT: uint = 0x8E4D; +export def GL_FIRST_VERTEX_CONVENTION_OES: uint = 0x8E4D; +export def GL_FIXED: uint = 0x140C; +export def GL_FLOAT: uint = 0x1406; +export def GL_FLOAT16_NV: uint = 0x8FF8; +export def GL_FLOAT16_VEC2_NV: uint = 0x8FF9; +export def GL_FLOAT16_VEC3_NV: uint = 0x8FFA; +export def GL_FLOAT16_VEC4_NV: uint = 0x8FFB; +export def GL_FLOAT_32_UNSIGNED_INT_24_8_REV: uint = 0x8DAD; +export def GL_FLOAT_MAT2: uint = 0x8B5A; +export def GL_FLOAT_MAT2x3: uint = 0x8B65; +export def GL_FLOAT_MAT2x3_NV: uint = 0x8B65; +export def GL_FLOAT_MAT2x4: uint = 0x8B66; +export def GL_FLOAT_MAT2x4_NV: uint = 0x8B66; +export def GL_FLOAT_MAT3: uint = 0x8B5B; +export def GL_FLOAT_MAT3x2: uint = 0x8B67; +export def GL_FLOAT_MAT3x2_NV: uint = 0x8B67; +export def GL_FLOAT_MAT3x4: uint = 0x8B68; +export def GL_FLOAT_MAT3x4_NV: uint = 0x8B68; +export def GL_FLOAT_MAT4: uint = 0x8B5C; +export def GL_FLOAT_MAT4x2: uint = 0x8B69; +export def GL_FLOAT_MAT4x2_NV: uint = 0x8B69; +export def GL_FLOAT_MAT4x3: uint = 0x8B6A; +export def GL_FLOAT_MAT4x3_NV: uint = 0x8B6A; +export def GL_FLOAT_VEC2: uint = 0x8B50; +export def GL_FLOAT_VEC3: uint = 0x8B51; +export def GL_FLOAT_VEC4: uint = 0x8B52; +export def GL_FONT_ASCENDER_BIT_NV: uint = 0x00200000; +export def GL_FONT_DESCENDER_BIT_NV: uint = 0x00400000; +export def GL_FONT_GLYPHS_AVAILABLE_NV: uint = 0x9368; +export def GL_FONT_HAS_KERNING_BIT_NV: uint = 0x10000000; +export def GL_FONT_HEIGHT_BIT_NV: uint = 0x00800000; +export def GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV: uint = 0x02000000; +export def GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV: uint = 0x01000000; +export def GL_FONT_NUM_GLYPH_INDICES_BIT_NV: uint = 0x20000000; +export def GL_FONT_TARGET_UNAVAILABLE_NV: uint = 0x9369; +export def GL_FONT_UNAVAILABLE_NV: uint = 0x936A; +export def GL_FONT_UNDERLINE_POSITION_BIT_NV: uint = 0x04000000; +export def GL_FONT_UNDERLINE_THICKNESS_BIT_NV: uint = 0x08000000; +export def GL_FONT_UNINTELLIGIBLE_NV: uint = 0x936B; +export def GL_FONT_UNITS_PER_EM_BIT_NV: uint = 0x00100000; +export def GL_FONT_X_MAX_BOUNDS_BIT_NV: uint = 0x00040000; +export def GL_FONT_X_MIN_BOUNDS_BIT_NV: uint = 0x00010000; +export def GL_FONT_Y_MAX_BOUNDS_BIT_NV: uint = 0x00080000; +export def GL_FONT_Y_MIN_BOUNDS_BIT_NV: uint = 0x00020000; +export def GL_FOVEATION_ENABLE_BIT_QCOM: uint = 0x00000001; +export def GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM: uint = 0x00000002; +export def GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM: uint = 0x00000004; +export def GL_FRACTIONAL_EVEN: uint = 0x8E7C; +export def GL_FRACTIONAL_EVEN_EXT: uint = 0x8E7C; +export def GL_FRACTIONAL_EVEN_OES: uint = 0x8E7C; +export def GL_FRACTIONAL_ODD: uint = 0x8E7B; +export def GL_FRACTIONAL_ODD_EXT: uint = 0x8E7B; +export def GL_FRACTIONAL_ODD_OES: uint = 0x8E7B; +export def GL_FRAGMENT_COVERAGE_COLOR_NV: uint = 0x92DE; +export def GL_FRAGMENT_COVERAGE_TO_COLOR_NV: uint = 0x92DD; +export def GL_FRAGMENT_INPUT_NV: uint = 0x936D; +export def GL_FRAGMENT_INTERPOLATION_OFFSET_BITS: uint = 0x8E5D; +export def GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES: uint = 0x8E5D; +export def GL_FRAGMENT_SHADER: uint = 0x8B30; +export def GL_FRAGMENT_SHADER_BIT: uint = 0x00000002; +export def GL_FRAGMENT_SHADER_BIT_EXT: uint = 0x00000002; +export def GL_FRAGMENT_SHADER_DERIVATIVE_HINT: uint = 0x8B8B; +export def GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: uint = 0x8B8B; +export def GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT: uint = 0x8A52; +export def GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM: uint = 0x8F66; +export def GL_FRAGMENT_SHADING_RATE_ATTACHMENT_WITH_DEFAULT_FRAMEBUFFER_SUPPORTED_EXT: uint = 0x96DF; +export def GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT: uint = 0x96D2; +export def GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT: uint = 0x96D5; +export def GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT: uint = 0x96D4; +export def GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT: uint = 0x96D6; +export def GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT: uint = 0x96D3; +export def GL_FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT: uint = 0x8F6F; +export def GL_FRAGMENT_SHADING_RATE_WITH_SAMPLE_MASK_SUPPORTED_EXT: uint = 0x96DE; +export def GL_FRAGMENT_SHADING_RATE_WITH_SHADER_DEPTH_STENCIL_WRITES_SUPPORTED_EXT: uint = 0x96DD; +export def GL_FRAMEBUFFER: uint = 0x8D40; +export def GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: uint = 0x8215; +export def GL_FRAMEBUFFER_ATTACHMENT_ANGLE: uint = 0x93A3; +export def GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: uint = 0x8214; +export def GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: uint = 0x8210; +export def GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: uint = 0x8210; +export def GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: uint = 0x8211; +export def GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: uint = 0x8211; +export def GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: uint = 0x8216; +export def GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: uint = 0x8213; +export def GL_FRAMEBUFFER_ATTACHMENT_LAYERED: uint = 0x8DA7; +export def GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT: uint = 0x8DA7; +export def GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES: uint = 0x8DA7; +export def GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: uint = 0x8CD1; +export def GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: uint = 0x8CD0; +export def GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: uint = 0x8212; +export def GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: uint = 0x8217; +export def GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES: uint = 0x8CD4; +export def GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR: uint = 0x9632; +export def GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: uint = 0x8CD3; +export def GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: uint = 0x8CD4; +export def GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: uint = 0x8CD2; +export def GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: uint = 0x9630; +export def GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT: uint = 0x8D6C; +export def GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG: uint = 0x913F; +export def GL_FRAMEBUFFER_BARRIER_BIT: uint = 0x00000400; +export def GL_FRAMEBUFFER_BINDING: uint = 0x8CA6; +export def GL_FRAMEBUFFER_COMPLETE: uint = 0x8CD5; +export def GL_FRAMEBUFFER_DEFAULT: uint = 0x8218; +export def GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: uint = 0x9314; +export def GL_FRAMEBUFFER_DEFAULT_HEIGHT: uint = 0x9311; +export def GL_FRAMEBUFFER_DEFAULT_LAYERS: uint = 0x9312; +export def GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT: uint = 0x9312; +export def GL_FRAMEBUFFER_DEFAULT_LAYERS_OES: uint = 0x9312; +export def GL_FRAMEBUFFER_DEFAULT_SAMPLES: uint = 0x9313; +export def GL_FRAMEBUFFER_DEFAULT_WIDTH: uint = 0x9310; +export def GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM: uint = 0x96A2; +export def GL_FRAMEBUFFER_FLIP_X_MESA: uint = 0x8BBC; +export def GL_FRAMEBUFFER_FLIP_Y_MESA: uint = 0x8BBB; +export def GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: uint = 0x8CD6; +export def GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: uint = 0x8CD9; +export def GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM: uint = 0x8BFF; +export def GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT: uint = 0x9652; +export def GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: uint = 0x8DA8; +export def GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT: uint = 0x8DA8; +export def GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES: uint = 0x8DA8; +export def GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: uint = 0x8CD7; +export def GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: uint = 0x8D56; +export def GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG: uint = 0x913C; +export def GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE: uint = 0x8D56; +export def GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE: uint = 0x8D56; +export def GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: uint = 0x8D56; +export def GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG: uint = 0x9134; +export def GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV: uint = 0x8D56; +export def GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR: uint = 0x9633; +export def GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV: uint = 0x9342; +export def GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV: uint = 0x9343; +export def GL_FRAMEBUFFER_SRGB_EXT: uint = 0x8DB9; +export def GL_FRAMEBUFFER_SWAP_XY_MESA: uint = 0x8BBD; +export def GL_FRAMEBUFFER_UNDEFINED: uint = 0x8219; +export def GL_FRAMEBUFFER_UNDEFINED_OES: uint = 0x8219; +export def GL_FRAMEBUFFER_UNSUPPORTED: uint = 0x8CDD; +export def GL_FRONT: uint = 0x0404; +export def GL_FRONT_AND_BACK: uint = 0x0408; +export def GL_FRONT_FACE: uint = 0x0B46; +export def GL_FUNC_ADD: uint = 0x8006; +export def GL_FUNC_REVERSE_SUBTRACT: uint = 0x800B; +export def GL_FUNC_SUBTRACT: uint = 0x800A; +export def GL_GCCSO_SHADER_BINARY_FJ: uint = 0x9260; +export def GL_GENERATE_MIPMAP_HINT: uint = 0x8192; +export def GL_GEOMETRY_INPUT_TYPE: uint = 0x8917; +export def GL_GEOMETRY_LINKED_INPUT_TYPE_EXT: uint = 0x8917; +export def GL_GEOMETRY_LINKED_INPUT_TYPE_OES: uint = 0x8917; +export def GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT: uint = 0x8918; +export def GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES: uint = 0x8918; +export def GL_GEOMETRY_LINKED_VERTICES_OUT_EXT: uint = 0x8916; +export def GL_GEOMETRY_LINKED_VERTICES_OUT_OES: uint = 0x8916; +export def GL_GEOMETRY_OUTPUT_TYPE: uint = 0x8918; +export def GL_GEOMETRY_SHADER: uint = 0x8DD9; +export def GL_GEOMETRY_SHADER_BIT: uint = 0x00000004; +export def GL_GEOMETRY_SHADER_BIT_EXT: uint = 0x00000004; +export def GL_GEOMETRY_SHADER_BIT_OES: uint = 0x00000004; +export def GL_GEOMETRY_SHADER_EXT: uint = 0x8DD9; +export def GL_GEOMETRY_SHADER_INVOCATIONS: uint = 0x887F; +export def GL_GEOMETRY_SHADER_INVOCATIONS_EXT: uint = 0x887F; +export def GL_GEOMETRY_SHADER_INVOCATIONS_OES: uint = 0x887F; +export def GL_GEOMETRY_SHADER_OES: uint = 0x8DD9; +export def GL_GEOMETRY_VERTICES_OUT: uint = 0x8916; +export def GL_GEQUAL: uint = 0x0206; +export def GL_GLYPH_HAS_KERNING_BIT_NV: uint = 0x100; +export def GL_GLYPH_HEIGHT_BIT_NV: uint = 0x02; +export def GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV: uint = 0x10; +export def GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV: uint = 0x04; +export def GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV: uint = 0x08; +export def GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV: uint = 0x80; +export def GL_GLYPH_VERTICAL_BEARING_X_BIT_NV: uint = 0x20; +export def GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV: uint = 0x40; +export def GL_GLYPH_WIDTH_BIT_NV: uint = 0x01; +export def GL_GPU_DISJOINT_EXT: uint = 0x8FBB; +export def GL_GPU_OPTIMIZED_QCOM: uint = 0x8FB2; +export def GL_GREATER: uint = 0x0204; +export def GL_GREEN: uint = 0x1904; +export def GL_GREEN_BITS: uint = 0x0D53; +export def GL_GREEN_NV: uint = 0x1904; +export def GL_GUILTY_CONTEXT_RESET: uint = 0x8253; +export def GL_GUILTY_CONTEXT_RESET_EXT: uint = 0x8253; +export def GL_GUILTY_CONTEXT_RESET_KHR: uint = 0x8253; +export def GL_HALF_FLOAT: uint = 0x140B; +export def GL_HALF_FLOAT_OES: uint = 0x8D61; +export def GL_HANDLE_TYPE_D3D11_IMAGE_EXT: uint = 0x958B; +export def GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT: uint = 0x958C; +export def GL_HANDLE_TYPE_D3D12_FENCE_EXT: uint = 0x9594; +export def GL_HANDLE_TYPE_D3D12_RESOURCE_EXT: uint = 0x958A; +export def GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT: uint = 0x9589; +export def GL_HANDLE_TYPE_OPAQUE_FD_EXT: uint = 0x9586; +export def GL_HANDLE_TYPE_OPAQUE_WIN32_EXT: uint = 0x9587; +export def GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT: uint = 0x9588; +export def GL_HARDLIGHT: uint = 0x929B; +export def GL_HARDLIGHT_KHR: uint = 0x929B; +export def GL_HARDLIGHT_NV: uint = 0x929B; +export def GL_HARDMIX_NV: uint = 0x92A9; +export def GL_HIGH_FLOAT: uint = 0x8DF2; +export def GL_HIGH_INT: uint = 0x8DF5; +export def GL_HORIZONTAL_LINE_TO_NV: uint = 0x06; +export def GL_HSL_COLOR: uint = 0x92AF; +export def GL_HSL_COLOR_KHR: uint = 0x92AF; +export def GL_HSL_COLOR_NV: uint = 0x92AF; +export def GL_HSL_HUE: uint = 0x92AD; +export def GL_HSL_HUE_KHR: uint = 0x92AD; +export def GL_HSL_HUE_NV: uint = 0x92AD; +export def GL_HSL_LUMINOSITY: uint = 0x92B0; +export def GL_HSL_LUMINOSITY_KHR: uint = 0x92B0; +export def GL_HSL_LUMINOSITY_NV: uint = 0x92B0; +export def GL_HSL_SATURATION: uint = 0x92AE; +export def GL_HSL_SATURATION_KHR: uint = 0x92AE; +export def GL_HSL_SATURATION_NV: uint = 0x92AE; +export def GL_IMAGE_2D: uint = 0x904D; +export def GL_IMAGE_2D_ARRAY: uint = 0x9053; +export def GL_IMAGE_3D: uint = 0x904E; +export def GL_IMAGE_BINDING_ACCESS: uint = 0x8F3E; +export def GL_IMAGE_BINDING_FORMAT: uint = 0x906E; +export def GL_IMAGE_BINDING_LAYER: uint = 0x8F3D; +export def GL_IMAGE_BINDING_LAYERED: uint = 0x8F3C; +export def GL_IMAGE_BINDING_LEVEL: uint = 0x8F3B; +export def GL_IMAGE_BINDING_NAME: uint = 0x8F3A; +export def GL_IMAGE_BUFFER: uint = 0x9051; +export def GL_IMAGE_BUFFER_EXT: uint = 0x9051; +export def GL_IMAGE_BUFFER_OES: uint = 0x9051; +export def GL_IMAGE_CUBE: uint = 0x9050; +export def GL_IMAGE_CUBE_MAP_ARRAY: uint = 0x9054; +export def GL_IMAGE_CUBE_MAP_ARRAY_EXT: uint = 0x9054; +export def GL_IMAGE_CUBE_MAP_ARRAY_OES: uint = 0x9054; +export def GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS: uint = 0x90C9; +export def GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE: uint = 0x90C8; +export def GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: uint = 0x90C7; +export def GL_IMPLEMENTATION_COLOR_READ_FORMAT: uint = 0x8B9B; +export def GL_IMPLEMENTATION_COLOR_READ_TYPE: uint = 0x8B9A; +export def GL_INCLUSIVE_EXT: uint = 0x8F10; +export def GL_INCR: uint = 0x1E02; +export def GL_INCR_WRAP: uint = 0x8507; +export def GL_INFO_LOG_LENGTH: uint = 0x8B84; +export def GL_INNOCENT_CONTEXT_RESET: uint = 0x8254; +export def GL_INNOCENT_CONTEXT_RESET_EXT: uint = 0x8254; +export def GL_INNOCENT_CONTEXT_RESET_KHR: uint = 0x8254; +export def GL_INT: uint = 0x1404; +export def GL_INT16_NV: uint = 0x8FE4; +export def GL_INT16_VEC2_NV: uint = 0x8FE5; +export def GL_INT16_VEC3_NV: uint = 0x8FE6; +export def GL_INT16_VEC4_NV: uint = 0x8FE7; +export def GL_INT64_NV: uint = 0x140E; +export def GL_INT64_VEC2_NV: uint = 0x8FE9; +export def GL_INT64_VEC3_NV: uint = 0x8FEA; +export def GL_INT64_VEC4_NV: uint = 0x8FEB; +export def GL_INT8_NV: uint = 0x8FE0; +export def GL_INT8_VEC2_NV: uint = 0x8FE1; +export def GL_INT8_VEC3_NV: uint = 0x8FE2; +export def GL_INT8_VEC4_NV: uint = 0x8FE3; +export def GL_INTERLEAVED_ATTRIBS: uint = 0x8C8C; +export def GL_INT_10_10_10_2_OES: uint = 0x8DF7; +export def GL_INT_2_10_10_10_REV: uint = 0x8D9F; +export def GL_INT_IMAGE_2D: uint = 0x9058; +export def GL_INT_IMAGE_2D_ARRAY: uint = 0x905E; +export def GL_INT_IMAGE_3D: uint = 0x9059; +export def GL_INT_IMAGE_BUFFER: uint = 0x905C; +export def GL_INT_IMAGE_BUFFER_EXT: uint = 0x905C; +export def GL_INT_IMAGE_BUFFER_OES: uint = 0x905C; +export def GL_INT_IMAGE_CUBE: uint = 0x905B; +export def GL_INT_IMAGE_CUBE_MAP_ARRAY: uint = 0x905F; +export def GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT: uint = 0x905F; +export def GL_INT_IMAGE_CUBE_MAP_ARRAY_OES: uint = 0x905F; +export def GL_INT_SAMPLER_2D: uint = 0x8DCA; +export def GL_INT_SAMPLER_2D_ARRAY: uint = 0x8DCF; +export def GL_INT_SAMPLER_2D_MULTISAMPLE: uint = 0x9109; +export def GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: uint = 0x910C; +export def GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES: uint = 0x910C; +export def GL_INT_SAMPLER_3D: uint = 0x8DCB; +export def GL_INT_SAMPLER_BUFFER: uint = 0x8DD0; +export def GL_INT_SAMPLER_BUFFER_EXT: uint = 0x8DD0; +export def GL_INT_SAMPLER_BUFFER_OES: uint = 0x8DD0; +export def GL_INT_SAMPLER_CUBE: uint = 0x8DCC; +export def GL_INT_SAMPLER_CUBE_MAP_ARRAY: uint = 0x900E; +export def GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT: uint = 0x900E; +export def GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES: uint = 0x900E; +export def GL_INT_VEC2: uint = 0x8B53; +export def GL_INT_VEC3: uint = 0x8B54; +export def GL_INT_VEC4: uint = 0x8B55; +export def GL_INVALID_ENUM: uint = 0x0500; +export def GL_INVALID_FRAMEBUFFER_OPERATION: uint = 0x0506; +export def GL_INVALID_INDEX: uint = 0xFFFFFFFF; +export def GL_INVALID_OPERATION: uint = 0x0502; +export def GL_INVALID_VALUE: uint = 0x0501; +export def GL_INVERT: uint = 0x150A; +export def GL_INVERT_OVG_NV: uint = 0x92B4; +export def GL_INVERT_RGB_NV: uint = 0x92A3; +export def GL_ISOLINES: uint = 0x8E7A; +export def GL_ISOLINES_EXT: uint = 0x8E7A; +export def GL_ISOLINES_OES: uint = 0x8E7A; +export def GL_IS_PER_PATCH: uint = 0x92E7; +export def GL_IS_PER_PATCH_EXT: uint = 0x92E7; +export def GL_IS_PER_PATCH_OES: uint = 0x92E7; +export def GL_IS_ROW_MAJOR: uint = 0x9300; +export def GL_ITALIC_BIT_NV: uint = 0x02; +export def GL_KEEP: uint = 0x1E00; +export def GL_LARGE_CCW_ARC_TO_NV: uint = 0x16; +export def GL_LARGE_CW_ARC_TO_NV: uint = 0x18; +export def GL_LAST_VERTEX_CONVENTION: uint = 0x8E4E; +export def GL_LAST_VERTEX_CONVENTION_EXT: uint = 0x8E4E; +export def GL_LAST_VERTEX_CONVENTION_OES: uint = 0x8E4E; +export def GL_LAYER_PROVOKING_VERTEX: uint = 0x825E; +export def GL_LAYER_PROVOKING_VERTEX_EXT: uint = 0x825E; +export def GL_LAYER_PROVOKING_VERTEX_OES: uint = 0x825E; +export def GL_LAYOUT_COLOR_ATTACHMENT_EXT: uint = 0x958E; +export def GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT: uint = 0x9531; +export def GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT: uint = 0x9530; +export def GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT: uint = 0x958F; +export def GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT: uint = 0x9590; +export def GL_LAYOUT_GENERAL_EXT: uint = 0x958D; +export def GL_LAYOUT_SHADER_READ_ONLY_EXT: uint = 0x9591; +export def GL_LAYOUT_TRANSFER_DST_EXT: uint = 0x9593; +export def GL_LAYOUT_TRANSFER_SRC_EXT: uint = 0x9592; +export def GL_LEQUAL: uint = 0x0203; +export def GL_LESS: uint = 0x0201; +export def GL_LIGHTEN: uint = 0x9298; +export def GL_LIGHTEN_KHR: uint = 0x9298; +export def GL_LIGHTEN_NV: uint = 0x9298; +export def GL_LINEAR: uint = 0x2601; +export def GL_LINEARBURN_NV: uint = 0x92A5; +export def GL_LINEARDODGE_NV: uint = 0x92A4; +export def GL_LINEARLIGHT_NV: uint = 0x92A7; +export def GL_LINEAR_MIPMAP_LINEAR: uint = 0x2703; +export def GL_LINEAR_MIPMAP_NEAREST: uint = 0x2701; +export def GL_LINEAR_TILING_EXT: uint = 0x9585; +export def GL_LINES: uint = 0x0001; +export def GL_LINES_ADJACENCY: uint = 0x000A; +export def GL_LINES_ADJACENCY_EXT: uint = 0x000A; +export def GL_LINES_ADJACENCY_OES: uint = 0x000A; +export def GL_LINE_LOOP: uint = 0x0002; +export def GL_LINE_NV: uint = 0x1B01; +export def GL_LINE_STRIP: uint = 0x0003; +export def GL_LINE_STRIP_ADJACENCY: uint = 0x000B; +export def GL_LINE_STRIP_ADJACENCY_EXT: uint = 0x000B; +export def GL_LINE_STRIP_ADJACENCY_OES: uint = 0x000B; +export def GL_LINE_TO_NV: uint = 0x04; +export def GL_LINE_WIDTH: uint = 0x0B21; +export def GL_LINK_STATUS: uint = 0x8B82; +export def GL_LOCATION: uint = 0x930E; +export def GL_LOCATION_INDEX_EXT: uint = 0x930F; +export def GL_LOSE_CONTEXT_ON_RESET: uint = 0x8252; +export def GL_LOSE_CONTEXT_ON_RESET_EXT: uint = 0x8252; +export def GL_LOSE_CONTEXT_ON_RESET_KHR: uint = 0x8252; +export def GL_LOWER_LEFT: uint = 0x8CA1; +export def GL_LOWER_LEFT_EXT: uint = 0x8CA1; +export def GL_LOW_FLOAT: uint = 0x8DF0; +export def GL_LOW_INT: uint = 0x8DF3; +export def GL_LUID_SIZE_EXT: uint = 8; +export def GL_LUMINANCE: uint = 0x1909; +export def GL_LUMINANCE16F_EXT: uint = 0x881E; +export def GL_LUMINANCE32F_EXT: uint = 0x8818; +export def GL_LUMINANCE4_ALPHA4_OES: uint = 0x8043; +export def GL_LUMINANCE8_ALPHA8_EXT: uint = 0x8045; +export def GL_LUMINANCE8_ALPHA8_OES: uint = 0x8045; +export def GL_LUMINANCE8_EXT: uint = 0x8040; +export def GL_LUMINANCE8_OES: uint = 0x8040; +export def GL_LUMINANCE_ALPHA: uint = 0x190A; +export def GL_LUMINANCE_ALPHA16F_EXT: uint = 0x881F; +export def GL_LUMINANCE_ALPHA32F_EXT: uint = 0x8819; +export def GL_MAJOR_VERSION: uint = 0x821B; +export def GL_MALI_PROGRAM_BINARY_ARM: uint = 0x8F61; +export def GL_MALI_SHADER_BINARY_ARM: uint = 0x8F60; +export def GL_MAP_COHERENT_BIT_EXT: uint = 0x0080; +export def GL_MAP_FLUSH_EXPLICIT_BIT: uint = 0x0010; +export def GL_MAP_FLUSH_EXPLICIT_BIT_EXT: uint = 0x0010; +export def GL_MAP_INVALIDATE_BUFFER_BIT: uint = 0x0008; +export def GL_MAP_INVALIDATE_BUFFER_BIT_EXT: uint = 0x0008; +export def GL_MAP_INVALIDATE_RANGE_BIT: uint = 0x0004; +export def GL_MAP_INVALIDATE_RANGE_BIT_EXT: uint = 0x0004; +export def GL_MAP_PERSISTENT_BIT_EXT: uint = 0x0040; +export def GL_MAP_READ_BIT: uint = 0x0001; +export def GL_MAP_READ_BIT_EXT: uint = 0x0001; +export def GL_MAP_UNSYNCHRONIZED_BIT: uint = 0x0020; +export def GL_MAP_UNSYNCHRONIZED_BIT_EXT: uint = 0x0020; +export def GL_MAP_WRITE_BIT: uint = 0x0002; +export def GL_MAP_WRITE_BIT_EXT: uint = 0x0002; +export def GL_MATRIX_STRIDE: uint = 0x92FF; +export def GL_MAX: uint = 0x8008; +export def GL_MAX_3D_TEXTURE_SIZE: uint = 0x8073; +export def GL_MAX_3D_TEXTURE_SIZE_OES: uint = 0x8073; +export def GL_MAX_ARRAY_TEXTURE_LAYERS: uint = 0x88FF; +export def GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: uint = 0x92DC; +export def GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE: uint = 0x92D8; +export def GL_MAX_CLIP_DISTANCES_APPLE: uint = 0x0D32; +export def GL_MAX_CLIP_DISTANCES_EXT: uint = 0x0D32; +export def GL_MAX_CLIP_PLANES: uint = 0x0D32; +export def GL_MAX_COARSE_FRAGMENT_SAMPLES_NV: uint = 0x955F; +export def GL_MAX_COLOR_ATTACHMENTS: uint = 0x8CDF; +export def GL_MAX_COLOR_ATTACHMENTS_EXT: uint = 0x8CDF; +export def GL_MAX_COLOR_ATTACHMENTS_NV: uint = 0x8CDF; +export def GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD: uint = 0x91B3; +export def GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD: uint = 0x91B4; +export def GL_MAX_COLOR_TEXTURE_SAMPLES: uint = 0x910E; +export def GL_MAX_COMBINED_ATOMIC_COUNTERS: uint = 0x92D7; +export def GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: uint = 0x92D1; +export def GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES: uint = 0x82FA; +export def GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT: uint = 0x82FA; +export def GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: uint = 0x8266; +export def GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: uint = 0x8A33; +export def GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS: uint = 0x8A32; +export def GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT: uint = 0x8A32; +export def GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES: uint = 0x8A32; +export def GL_MAX_COMBINED_IMAGE_UNIFORMS: uint = 0x90CF; +export def GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS: uint = 0x8F39; +export def GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV: uint = 0x8E67; +export def GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: uint = 0x8F39; +export def GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: uint = 0x90DC; +export def GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV: uint = 0x8E6F; +export def GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS: uint = 0x8E1E; +export def GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT: uint = 0x8E1E; +export def GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES: uint = 0x8E1E; +export def GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS: uint = 0x8E1F; +export def GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT: uint = 0x8E1F; +export def GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES: uint = 0x8E1F; +export def GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: uint = 0x8B4D; +export def GL_MAX_COMBINED_UNIFORM_BLOCKS: uint = 0x8A2E; +export def GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: uint = 0x8A31; +export def GL_MAX_COMPUTE_ATOMIC_COUNTERS: uint = 0x8265; +export def GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: uint = 0x8264; +export def GL_MAX_COMPUTE_IMAGE_UNIFORMS: uint = 0x91BD; +export def GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: uint = 0x90DB; +export def GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: uint = 0x8262; +export def GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: uint = 0x91BC; +export def GL_MAX_COMPUTE_UNIFORM_BLOCKS: uint = 0x91BB; +export def GL_MAX_COMPUTE_UNIFORM_COMPONENTS: uint = 0x8263; +export def GL_MAX_COMPUTE_WORK_GROUP_COUNT: uint = 0x91BE; +export def GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: uint = 0x90EB; +export def GL_MAX_COMPUTE_WORK_GROUP_SIZE: uint = 0x91BF; +export def GL_MAX_CUBE_MAP_TEXTURE_SIZE: uint = 0x851C; +export def GL_MAX_CULL_DISTANCES: uint = 0x82F9; +export def GL_MAX_CULL_DISTANCES_EXT: uint = 0x82F9; +export def GL_MAX_DEBUG_GROUP_STACK_DEPTH: uint = 0x826C; +export def GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR: uint = 0x826C; +export def GL_MAX_DEBUG_LOGGED_MESSAGES: uint = 0x9144; +export def GL_MAX_DEBUG_LOGGED_MESSAGES_KHR: uint = 0x9144; +export def GL_MAX_DEBUG_MESSAGE_LENGTH: uint = 0x9143; +export def GL_MAX_DEBUG_MESSAGE_LENGTH_KHR: uint = 0x9143; +export def GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD: uint = 0x91B5; +export def GL_MAX_DEPTH_TEXTURE_SAMPLES: uint = 0x910F; +export def GL_MAX_DETACHED_BUFFERS_NV: uint = 0x95AD; +export def GL_MAX_DETACHED_TEXTURES_NV: uint = 0x95AC; +export def GL_MAX_DRAW_BUFFERS: uint = 0x8824; +export def GL_MAX_DRAW_BUFFERS_EXT: uint = 0x8824; +export def GL_MAX_DRAW_BUFFERS_NV: uint = 0x8824; +export def GL_MAX_DRAW_MESH_TASKS_COUNT_NV: uint = 0x953D; +export def GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT: uint = 0x88FC; +export def GL_MAX_ELEMENTS_INDICES: uint = 0x80E9; +export def GL_MAX_ELEMENTS_VERTICES: uint = 0x80E8; +export def GL_MAX_ELEMENT_INDEX: uint = 0x8D6B; +export def GL_MAX_EXT: uint = 0x8008; +export def GL_MAX_FRAGMENT_ATOMIC_COUNTERS: uint = 0x92D6; +export def GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: uint = 0x92D0; +export def GL_MAX_FRAGMENT_IMAGE_UNIFORMS: uint = 0x90CE; +export def GL_MAX_FRAGMENT_INPUT_COMPONENTS: uint = 0x9125; +export def GL_MAX_FRAGMENT_INTERPOLATION_OFFSET: uint = 0x8E5C; +export def GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES: uint = 0x8E5C; +export def GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: uint = 0x90DA; +export def GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT: uint = 0x96DC; +export def GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT: uint = 0x96DB; +export def GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT: uint = 0x96DA; +export def GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT: uint = 0x96D8; +export def GL_MAX_FRAGMENT_UNIFORM_BLOCKS: uint = 0x8A2D; +export def GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: uint = 0x8B49; +export def GL_MAX_FRAGMENT_UNIFORM_VECTORS: uint = 0x8DFD; +export def GL_MAX_FRAMEBUFFER_HEIGHT: uint = 0x9316; +export def GL_MAX_FRAMEBUFFER_LAYERS: uint = 0x9317; +export def GL_MAX_FRAMEBUFFER_LAYERS_EXT: uint = 0x9317; +export def GL_MAX_FRAMEBUFFER_LAYERS_OES: uint = 0x9317; +export def GL_MAX_FRAMEBUFFER_SAMPLES: uint = 0x9318; +export def GL_MAX_FRAMEBUFFER_WIDTH: uint = 0x9315; +export def GL_MAX_GEOMETRY_ATOMIC_COUNTERS: uint = 0x92D5; +export def GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT: uint = 0x92D5; +export def GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES: uint = 0x92D5; +export def GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS: uint = 0x92CF; +export def GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT: uint = 0x92CF; +export def GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES: uint = 0x92CF; +export def GL_MAX_GEOMETRY_IMAGE_UNIFORMS: uint = 0x90CD; +export def GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT: uint = 0x90CD; +export def GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES: uint = 0x90CD; +export def GL_MAX_GEOMETRY_INPUT_COMPONENTS: uint = 0x9123; +export def GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT: uint = 0x9123; +export def GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES: uint = 0x9123; +export def GL_MAX_GEOMETRY_OUTPUT_COMPONENTS: uint = 0x9124; +export def GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT: uint = 0x9124; +export def GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES: uint = 0x9124; +export def GL_MAX_GEOMETRY_OUTPUT_VERTICES: uint = 0x8DE0; +export def GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT: uint = 0x8DE0; +export def GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES: uint = 0x8DE0; +export def GL_MAX_GEOMETRY_SHADER_INVOCATIONS: uint = 0x8E5A; +export def GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT: uint = 0x8E5A; +export def GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES: uint = 0x8E5A; +export def GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS: uint = 0x90D7; +export def GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT: uint = 0x90D7; +export def GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES: uint = 0x90D7; +export def GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: uint = 0x8C29; +export def GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT: uint = 0x8C29; +export def GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES: uint = 0x8C29; +export def GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: uint = 0x8DE1; +export def GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT: uint = 0x8DE1; +export def GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES: uint = 0x8DE1; +export def GL_MAX_GEOMETRY_UNIFORM_BLOCKS: uint = 0x8A2C; +export def GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT: uint = 0x8A2C; +export def GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES: uint = 0x8A2C; +export def GL_MAX_GEOMETRY_UNIFORM_COMPONENTS: uint = 0x8DDF; +export def GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT: uint = 0x8DDF; +export def GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES: uint = 0x8DDF; +export def GL_MAX_IMAGE_UNITS: uint = 0x8F38; +export def GL_MAX_INTEGER_SAMPLES: uint = 0x9110; +export def GL_MAX_LABEL_LENGTH: uint = 0x82E8; +export def GL_MAX_LABEL_LENGTH_KHR: uint = 0x82E8; +export def GL_MAX_MESH_ATOMIC_COUNTERS_NV: uint = 0x8E65; +export def GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV: uint = 0x8E64; +export def GL_MAX_MESH_IMAGE_UNIFORMS_NV: uint = 0x8E62; +export def GL_MAX_MESH_OUTPUT_PRIMITIVES_NV: uint = 0x9539; +export def GL_MAX_MESH_OUTPUT_VERTICES_NV: uint = 0x9538; +export def GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV: uint = 0x8E66; +export def GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV: uint = 0x8E61; +export def GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV: uint = 0x9536; +export def GL_MAX_MESH_UNIFORM_BLOCKS_NV: uint = 0x8E60; +export def GL_MAX_MESH_UNIFORM_COMPONENTS_NV: uint = 0x8E63; +export def GL_MAX_MESH_VIEWS_NV: uint = 0x9557; +export def GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV: uint = 0x95A2; +export def GL_MAX_MESH_WORK_GROUP_SIZE_NV: uint = 0x953B; +export def GL_MAX_MULTIVIEW_BUFFERS_EXT: uint = 0x90F2; +export def GL_MAX_NAME_LENGTH: uint = 0x92F6; +export def GL_MAX_NUM_ACTIVE_VARIABLES: uint = 0x92F7; +export def GL_MAX_PATCH_VERTICES: uint = 0x8E7D; +export def GL_MAX_PATCH_VERTICES_EXT: uint = 0x8E7D; +export def GL_MAX_PATCH_VERTICES_OES: uint = 0x8E7D; +export def GL_MAX_PROGRAM_TEXEL_OFFSET: uint = 0x8905; +export def GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET: uint = 0x8E5F; +export def GL_MAX_RASTER_SAMPLES_EXT: uint = 0x9329; +export def GL_MAX_RENDERBUFFER_SIZE: uint = 0x84E8; +export def GL_MAX_SAMPLES: uint = 0x8D57; +export def GL_MAX_SAMPLES_ANGLE: uint = 0x8D57; +export def GL_MAX_SAMPLES_APPLE: uint = 0x8D57; +export def GL_MAX_SAMPLES_EXT: uint = 0x8D57; +export def GL_MAX_SAMPLES_IMG: uint = 0x9135; +export def GL_MAX_SAMPLES_NV: uint = 0x8D57; +export def GL_MAX_SAMPLE_MASK_WORDS: uint = 0x8E59; +export def GL_MAX_SERVER_WAIT_TIMEOUT: uint = 0x9111; +export def GL_MAX_SERVER_WAIT_TIMEOUT_APPLE: uint = 0x9111; +export def GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT: uint = 0x9650; +export def GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT: uint = 0x9651; +export def GL_MAX_SHADER_COMPILER_THREADS_KHR: uint = 0x91B0; +export def GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT: uint = 0x8F63; +export def GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT: uint = 0x8F67; +export def GL_MAX_SHADER_STORAGE_BLOCK_SIZE: uint = 0x90DE; +export def GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: uint = 0x90DD; +export def GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM: uint = 0x8FA1; +export def GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT: uint = 0x9199; +export def GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT: uint = 0x919A; +export def GL_MAX_SPARSE_TEXTURE_SIZE_EXT: uint = 0x9198; +export def GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV: uint = 0x9349; +export def GL_MAX_TASK_ATOMIC_COUNTERS_NV: uint = 0x8E6D; +export def GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV: uint = 0x8E6C; +export def GL_MAX_TASK_IMAGE_UNIFORMS_NV: uint = 0x8E6A; +export def GL_MAX_TASK_OUTPUT_COUNT_NV: uint = 0x953A; +export def GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV: uint = 0x8E6E; +export def GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV: uint = 0x8E69; +export def GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV: uint = 0x9537; +export def GL_MAX_TASK_UNIFORM_BLOCKS_NV: uint = 0x8E68; +export def GL_MAX_TASK_UNIFORM_COMPONENTS_NV: uint = 0x8E6B; +export def GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV: uint = 0x95A3; +export def GL_MAX_TASK_WORK_GROUP_SIZE_NV: uint = 0x953C; +export def GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS: uint = 0x92D3; +export def GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT: uint = 0x92D3; +export def GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES: uint = 0x92D3; +export def GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS: uint = 0x92CD; +export def GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT: uint = 0x92CD; +export def GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES: uint = 0x92CD; +export def GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS: uint = 0x90CB; +export def GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT: uint = 0x90CB; +export def GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES: uint = 0x90CB; +export def GL_MAX_TESS_CONTROL_INPUT_COMPONENTS: uint = 0x886C; +export def GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT: uint = 0x886C; +export def GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES: uint = 0x886C; +export def GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS: uint = 0x8E83; +export def GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT: uint = 0x8E83; +export def GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES: uint = 0x8E83; +export def GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: uint = 0x90D8; +export def GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT: uint = 0x90D8; +export def GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES: uint = 0x90D8; +export def GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS: uint = 0x8E81; +export def GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT: uint = 0x8E81; +export def GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES: uint = 0x8E81; +export def GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS: uint = 0x8E85; +export def GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT: uint = 0x8E85; +export def GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES: uint = 0x8E85; +export def GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS: uint = 0x8E89; +export def GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT: uint = 0x8E89; +export def GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES: uint = 0x8E89; +export def GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS: uint = 0x8E7F; +export def GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT: uint = 0x8E7F; +export def GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES: uint = 0x8E7F; +export def GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS: uint = 0x92D4; +export def GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT: uint = 0x92D4; +export def GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES: uint = 0x92D4; +export def GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS: uint = 0x92CE; +export def GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT: uint = 0x92CE; +export def GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES: uint = 0x92CE; +export def GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS: uint = 0x90CC; +export def GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT: uint = 0x90CC; +export def GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES: uint = 0x90CC; +export def GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS: uint = 0x886D; +export def GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT: uint = 0x886D; +export def GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES: uint = 0x886D; +export def GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS: uint = 0x8E86; +export def GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT: uint = 0x8E86; +export def GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES: uint = 0x8E86; +export def GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS: uint = 0x90D9; +export def GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT: uint = 0x90D9; +export def GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES: uint = 0x90D9; +export def GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS: uint = 0x8E82; +export def GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT: uint = 0x8E82; +export def GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES: uint = 0x8E82; +export def GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS: uint = 0x8E8A; +export def GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT: uint = 0x8E8A; +export def GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES: uint = 0x8E8A; +export def GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS: uint = 0x8E80; +export def GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT: uint = 0x8E80; +export def GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES: uint = 0x8E80; +export def GL_MAX_TESS_GEN_LEVEL: uint = 0x8E7E; +export def GL_MAX_TESS_GEN_LEVEL_EXT: uint = 0x8E7E; +export def GL_MAX_TESS_GEN_LEVEL_OES: uint = 0x8E7E; +export def GL_MAX_TESS_PATCH_COMPONENTS: uint = 0x8E84; +export def GL_MAX_TESS_PATCH_COMPONENTS_EXT: uint = 0x8E84; +export def GL_MAX_TESS_PATCH_COMPONENTS_OES: uint = 0x8E84; +export def GL_MAX_TEXTURE_BUFFER_SIZE: uint = 0x8C2B; +export def GL_MAX_TEXTURE_BUFFER_SIZE_EXT: uint = 0x8C2B; +export def GL_MAX_TEXTURE_BUFFER_SIZE_OES: uint = 0x8C2B; +export def GL_MAX_TEXTURE_IMAGE_UNITS: uint = 0x8872; +export def GL_MAX_TEXTURE_LOD_BIAS: uint = 0x84FD; +export def GL_MAX_TEXTURE_MAX_ANISOTROPY: uint = 0x84FF; +export def GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: uint = 0x84FF; +export def GL_MAX_TEXTURE_SIZE: uint = 0x0D33; +export def GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV: uint = 0x95B6; +export def GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: uint = 0x8C8A; +export def GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: uint = 0x8C8B; +export def GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: uint = 0x8C80; +export def GL_MAX_UNIFORM_BLOCK_SIZE: uint = 0x8A30; +export def GL_MAX_UNIFORM_BUFFER_BINDINGS: uint = 0x8A2F; +export def GL_MAX_UNIFORM_LOCATIONS: uint = 0x826E; +export def GL_MAX_VARYING_COMPONENTS: uint = 0x8B4B; +export def GL_MAX_VARYING_FLOATS: uint = 0x8B4B; +export def GL_MAX_VARYING_VECTORS: uint = 0x8DFC; +export def GL_MAX_VERTEX_ATOMIC_COUNTERS: uint = 0x92D2; +export def GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: uint = 0x92CC; +export def GL_MAX_VERTEX_ATTRIBS: uint = 0x8869; +export def GL_MAX_VERTEX_ATTRIB_BINDINGS: uint = 0x82DA; +export def GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: uint = 0x82D9; +export def GL_MAX_VERTEX_ATTRIB_STRIDE: uint = 0x82E5; +export def GL_MAX_VERTEX_IMAGE_UNIFORMS: uint = 0x90CA; +export def GL_MAX_VERTEX_OUTPUT_COMPONENTS: uint = 0x9122; +export def GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: uint = 0x90D6; +export def GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: uint = 0x8B4C; +export def GL_MAX_VERTEX_UNIFORM_BLOCKS: uint = 0x8A2B; +export def GL_MAX_VERTEX_UNIFORM_COMPONENTS: uint = 0x8B4A; +export def GL_MAX_VERTEX_UNIFORM_VECTORS: uint = 0x8DFB; +export def GL_MAX_VIEWPORTS_NV: uint = 0x825B; +export def GL_MAX_VIEWPORTS_OES: uint = 0x825B; +export def GL_MAX_VIEWPORT_DIMS: uint = 0x0D3A; +export def GL_MAX_VIEWS_OVR: uint = 0x9631; +export def GL_MAX_WINDOW_RECTANGLES_EXT: uint = 0x8F14; +export def GL_MEDIUM_FLOAT: uint = 0x8DF1; +export def GL_MEDIUM_INT: uint = 0x8DF4; +export def GL_MEMORY_ATTACHABLE_ALIGNMENT_NV: uint = 0x95A6; +export def GL_MEMORY_ATTACHABLE_NV: uint = 0x95A8; +export def GL_MEMORY_ATTACHABLE_SIZE_NV: uint = 0x95A7; +export def GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV: uint = 0x9543; +export def GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV: uint = 0x92DF; +export def GL_MESH_OUTPUT_TYPE_NV: uint = 0x957B; +export def GL_MESH_PRIMITIVES_OUT_NV: uint = 0x957A; +export def GL_MESH_SHADER_BIT_NV: uint = 0x00000040; +export def GL_MESH_SHADER_NV: uint = 0x9559; +export def GL_MESH_SUBROUTINE_NV: uint = 0x957C; +export def GL_MESH_SUBROUTINE_UNIFORM_NV: uint = 0x957E; +export def GL_MESH_VERTICES_OUT_NV: uint = 0x9579; +export def GL_MESH_WORK_GROUP_SIZE_NV: uint = 0x953E; +export def GL_MIN: uint = 0x8007; +export def GL_MINOR_VERSION: uint = 0x821C; +export def GL_MINUS_CLAMPED_NV: uint = 0x92B3; +export def GL_MINUS_NV: uint = 0x929F; +export def GL_MIN_EXT: uint = 0x8007; +export def GL_MIN_FRAGMENT_INTERPOLATION_OFFSET: uint = 0x8E5B; +export def GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES: uint = 0x8E5B; +export def GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT: uint = 0x96D9; +export def GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT: uint = 0x96D7; +export def GL_MIN_PROGRAM_TEXEL_OFFSET: uint = 0x8904; +export def GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET: uint = 0x8E5E; +export def GL_MIN_SAMPLE_SHADING_VALUE: uint = 0x8C37; +export def GL_MIN_SAMPLE_SHADING_VALUE_OES: uint = 0x8C37; +export def GL_MIRRORED_REPEAT: uint = 0x8370; +export def GL_MIRROR_CLAMP_TO_EDGE_EXT: uint = 0x8743; +export def GL_MITER_REVERT_NV: uint = 0x90A7; +export def GL_MITER_TRUNCATE_NV: uint = 0x90A8; +export def GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV: uint = 0x932F; +export def GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV: uint = 0x9330; +export def GL_MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM: uint = 0x8C90; +export def GL_MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM: uint = 0x8C91; +export def GL_MOVE_TO_CONTINUES_NV: uint = 0x90B6; +export def GL_MOVE_TO_NV: uint = 0x02; +export def GL_MOVE_TO_RESETS_NV: uint = 0x90B5; +export def GL_MULTIPLY: uint = 0x9294; +export def GL_MULTIPLY_KHR: uint = 0x9294; +export def GL_MULTIPLY_NV: uint = 0x9294; +export def GL_MULTISAMPLES_NV: uint = 0x9371; +export def GL_MULTISAMPLE_BUFFER_BIT0_QCOM: uint = 0x01000000; +export def GL_MULTISAMPLE_BUFFER_BIT1_QCOM: uint = 0x02000000; +export def GL_MULTISAMPLE_BUFFER_BIT2_QCOM: uint = 0x04000000; +export def GL_MULTISAMPLE_BUFFER_BIT3_QCOM: uint = 0x08000000; +export def GL_MULTISAMPLE_BUFFER_BIT4_QCOM: uint = 0x10000000; +export def GL_MULTISAMPLE_BUFFER_BIT5_QCOM: uint = 0x20000000; +export def GL_MULTISAMPLE_BUFFER_BIT6_QCOM: uint = 0x40000000; +export def GL_MULTISAMPLE_BUFFER_BIT7_QCOM: uint = 0x80000000; +export def GL_MULTISAMPLE_EXT: uint = 0x809D; +export def GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY: uint = 0x9382; +export def GL_MULTISAMPLE_LINE_WIDTH_RANGE: uint = 0x9381; +export def GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT: uint = 0x932B; +export def GL_MULTIVIEW_EXT: uint = 0x90F1; +export def GL_NAME_LENGTH: uint = 0x92F9; +export def GL_NEAREST: uint = 0x2600; +export def GL_NEAREST_MIPMAP_LINEAR: uint = 0x2702; +export def GL_NEAREST_MIPMAP_NEAREST: uint = 0x2700; +export def GL_NEGATIVE_ONE_TO_ONE: uint = 0x935E; +export def GL_NEGATIVE_ONE_TO_ONE_EXT: uint = 0x935E; +export def GL_NEVER: uint = 0x0200; +export def GL_NICEST: uint = 0x1102; +export def GL_NONE: uint = 0; +export def GL_NOTEQUAL: uint = 0x0205; +export def GL_NO_ERROR: uint = 0; +export def GL_NO_RESET_NOTIFICATION: uint = 0x8261; +export def GL_NO_RESET_NOTIFICATION_EXT: uint = 0x8261; +export def GL_NO_RESET_NOTIFICATION_KHR: uint = 0x8261; +export def GL_NUM_ACTIVE_VARIABLES: uint = 0x9304; +export def GL_NUM_COMPRESSED_TEXTURE_FORMATS: uint = 0x86A2; +export def GL_NUM_DEVICE_UUIDS_EXT: uint = 0x9596; +export def GL_NUM_DOWNSAMPLE_SCALES_IMG: uint = 0x913D; +export def GL_NUM_EXTENSIONS: uint = 0x821D; +export def GL_NUM_PROGRAM_BINARY_FORMATS: uint = 0x87FE; +export def GL_NUM_PROGRAM_BINARY_FORMATS_OES: uint = 0x87FE; +export def GL_NUM_SAMPLE_COUNTS: uint = 0x9380; +export def GL_NUM_SHADER_BINARY_FORMATS: uint = 0x8DF9; +export def GL_NUM_SPARSE_LEVELS_EXT: uint = 0x91AA; +export def GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD: uint = 0x91B6; +export def GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT: uint = 0x8F6E; +export def GL_NUM_TILING_TYPES_EXT: uint = 0x9582; +export def GL_NUM_VIRTUAL_PAGE_SIZES_EXT: uint = 0x91A8; +export def GL_NUM_WINDOW_RECTANGLES_EXT: uint = 0x8F15; +export def GL_OBJECT_TYPE: uint = 0x9112; +export def GL_OBJECT_TYPE_APPLE: uint = 0x9112; +export def GL_OFFSET: uint = 0x92FC; +export def GL_ONE: uint = 1; +export def GL_ONE_MINUS_CONSTANT_ALPHA: uint = 0x8004; +export def GL_ONE_MINUS_CONSTANT_COLOR: uint = 0x8002; +export def GL_ONE_MINUS_DST_ALPHA: uint = 0x0305; +export def GL_ONE_MINUS_DST_COLOR: uint = 0x0307; +export def GL_ONE_MINUS_SRC1_ALPHA_EXT: uint = 0x88FB; +export def GL_ONE_MINUS_SRC1_COLOR_EXT: uint = 0x88FA; +export def GL_ONE_MINUS_SRC_ALPHA: uint = 0x0303; +export def GL_ONE_MINUS_SRC_COLOR: uint = 0x0301; +export def GL_OPTIMAL_TILING_EXT: uint = 0x9584; +export def GL_OUT_OF_MEMORY: uint = 0x0505; +export def GL_OVERLAY: uint = 0x9296; +export def GL_OVERLAY_KHR: uint = 0x9296; +export def GL_OVERLAY_NV: uint = 0x9296; +export def GL_PACK_ALIGNMENT: uint = 0x0D05; +export def GL_PACK_REVERSE_ROW_ORDER_ANGLE: uint = 0x93A4; +export def GL_PACK_ROW_LENGTH: uint = 0x0D02; +export def GL_PACK_SKIP_PIXELS: uint = 0x0D04; +export def GL_PACK_SKIP_ROWS: uint = 0x0D03; +export def GL_PALETTE4_R5_G6_B5_OES: uint = 0x8B92; +export def GL_PALETTE4_RGB5_A1_OES: uint = 0x8B94; +export def GL_PALETTE4_RGB8_OES: uint = 0x8B90; +export def GL_PALETTE4_RGBA4_OES: uint = 0x8B93; +export def GL_PALETTE4_RGBA8_OES: uint = 0x8B91; +export def GL_PALETTE8_R5_G6_B5_OES: uint = 0x8B97; +export def GL_PALETTE8_RGB5_A1_OES: uint = 0x8B99; +export def GL_PALETTE8_RGB8_OES: uint = 0x8B95; +export def GL_PALETTE8_RGBA4_OES: uint = 0x8B98; +export def GL_PALETTE8_RGBA8_OES: uint = 0x8B96; +export def GL_PATCHES: uint = 0x000E; +export def GL_PATCHES_EXT: uint = 0x000E; +export def GL_PATCHES_OES: uint = 0x000E; +export def GL_PATCH_VERTICES: uint = 0x8E72; +export def GL_PATCH_VERTICES_EXT: uint = 0x8E72; +export def GL_PATCH_VERTICES_OES: uint = 0x8E72; +export def GL_PATH_CLIENT_LENGTH_NV: uint = 0x907F; +export def GL_PATH_COMMAND_COUNT_NV: uint = 0x909D; +export def GL_PATH_COMPUTED_LENGTH_NV: uint = 0x90A0; +export def GL_PATH_COORD_COUNT_NV: uint = 0x909E; +export def GL_PATH_COVER_DEPTH_FUNC_NV: uint = 0x90BF; +export def GL_PATH_DASH_ARRAY_COUNT_NV: uint = 0x909F; +export def GL_PATH_DASH_CAPS_NV: uint = 0x907B; +export def GL_PATH_DASH_OFFSET_NV: uint = 0x907E; +export def GL_PATH_DASH_OFFSET_RESET_NV: uint = 0x90B4; +export def GL_PATH_END_CAPS_NV: uint = 0x9076; +export def GL_PATH_ERROR_POSITION_NV: uint = 0x90AB; +export def GL_PATH_FILL_BOUNDING_BOX_NV: uint = 0x90A1; +export def GL_PATH_FILL_COVER_MODE_NV: uint = 0x9082; +export def GL_PATH_FILL_MASK_NV: uint = 0x9081; +export def GL_PATH_FILL_MODE_NV: uint = 0x9080; +export def GL_PATH_FORMAT_PS_NV: uint = 0x9071; +export def GL_PATH_FORMAT_SVG_NV: uint = 0x9070; +export def GL_PATH_GEN_COEFF_NV: uint = 0x90B1; +export def GL_PATH_GEN_COMPONENTS_NV: uint = 0x90B3; +export def GL_PATH_GEN_MODE_NV: uint = 0x90B0; +export def GL_PATH_INITIAL_DASH_CAP_NV: uint = 0x907C; +export def GL_PATH_INITIAL_END_CAP_NV: uint = 0x9077; +export def GL_PATH_JOIN_STYLE_NV: uint = 0x9079; +export def GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV: uint = 0x0D36; +export def GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV: uint = 0x0D38; +export def GL_PATH_MITER_LIMIT_NV: uint = 0x907A; +export def GL_PATH_MODELVIEW_MATRIX_NV: uint = 0x0BA6; +export def GL_PATH_MODELVIEW_NV: uint = 0x1700; +export def GL_PATH_MODELVIEW_STACK_DEPTH_NV: uint = 0x0BA3; +export def GL_PATH_OBJECT_BOUNDING_BOX_NV: uint = 0x908A; +export def GL_PATH_PROJECTION_MATRIX_NV: uint = 0x0BA7; +export def GL_PATH_PROJECTION_NV: uint = 0x1701; +export def GL_PATH_PROJECTION_STACK_DEPTH_NV: uint = 0x0BA4; +export def GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV: uint = 0x90BD; +export def GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV: uint = 0x90BE; +export def GL_PATH_STENCIL_FUNC_NV: uint = 0x90B7; +export def GL_PATH_STENCIL_REF_NV: uint = 0x90B8; +export def GL_PATH_STENCIL_VALUE_MASK_NV: uint = 0x90B9; +export def GL_PATH_STROKE_BOUNDING_BOX_NV: uint = 0x90A2; +export def GL_PATH_STROKE_COVER_MODE_NV: uint = 0x9083; +export def GL_PATH_STROKE_MASK_NV: uint = 0x9084; +export def GL_PATH_STROKE_WIDTH_NV: uint = 0x9075; +export def GL_PATH_TERMINAL_DASH_CAP_NV: uint = 0x907D; +export def GL_PATH_TERMINAL_END_CAP_NV: uint = 0x9078; +export def GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV: uint = 0x84E3; +export def GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV: uint = 0x84E4; +export def GL_PERCENTAGE_AMD: uint = 0x8BC3; +export def GL_PERFMON_GLOBAL_MODE_QCOM: uint = 0x8FA0; +export def GL_PERFMON_RESULT_AMD: uint = 0x8BC6; +export def GL_PERFMON_RESULT_AVAILABLE_AMD: uint = 0x8BC4; +export def GL_PERFMON_RESULT_SIZE_AMD: uint = 0x8BC5; +export def GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL: uint = 0x94FC; +export def GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL: uint = 0x94FB; +export def GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL: uint = 0x94FA; +export def GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL: uint = 0x94F8; +export def GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL: uint = 0x94F9; +export def GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL: uint = 0x94FF; +export def GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL: uint = 0x94F1; +export def GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL: uint = 0x94F2; +export def GL_PERFQUERY_COUNTER_EVENT_INTEL: uint = 0x94F0; +export def GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL: uint = 0x94FE; +export def GL_PERFQUERY_COUNTER_RAW_INTEL: uint = 0x94F4; +export def GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL: uint = 0x94F3; +export def GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL: uint = 0x94F5; +export def GL_PERFQUERY_DONOT_FLUSH_INTEL: uint = 0x83F9; +export def GL_PERFQUERY_FLUSH_INTEL: uint = 0x83FA; +export def GL_PERFQUERY_GLOBAL_CONTEXT_INTEL: uint = 0x00000001; +export def GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL: uint = 0x9500; +export def GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL: uint = 0x94FD; +export def GL_PERFQUERY_SINGLE_CONTEXT_INTEL: uint = 0x00000000; +export def GL_PERFQUERY_WAIT_INTEL: uint = 0x83FB; +export def GL_PINLIGHT_NV: uint = 0x92A8; +export def GL_PIXEL_BUFFER_BARRIER_BIT: uint = 0x00000080; +export def GL_PIXEL_PACK_BUFFER: uint = 0x88EB; +export def GL_PIXEL_PACK_BUFFER_BINDING: uint = 0x88ED; +export def GL_PIXEL_PACK_BUFFER_BINDING_NV: uint = 0x88ED; +export def GL_PIXEL_PACK_BUFFER_NV: uint = 0x88EB; +export def GL_PIXEL_UNPACK_BUFFER: uint = 0x88EC; +export def GL_PIXEL_UNPACK_BUFFER_BINDING: uint = 0x88EF; +export def GL_PIXEL_UNPACK_BUFFER_BINDING_NV: uint = 0x88EF; +export def GL_PIXEL_UNPACK_BUFFER_NV: uint = 0x88EC; +export def GL_PLUS_CLAMPED_ALPHA_NV: uint = 0x92B2; +export def GL_PLUS_CLAMPED_NV: uint = 0x92B1; +export def GL_PLUS_DARKER_NV: uint = 0x9292; +export def GL_PLUS_NV: uint = 0x9291; +export def GL_POINTS: uint = 0x0000; +export def GL_POINT_NV: uint = 0x1B00; +export def GL_POLYGON_MODE_NV: uint = 0x0B40; +export def GL_POLYGON_OFFSET_CLAMP: uint = 0x8E1B; +export def GL_POLYGON_OFFSET_CLAMP_EXT: uint = 0x8E1B; +export def GL_POLYGON_OFFSET_FACTOR: uint = 0x8038; +export def GL_POLYGON_OFFSET_FILL: uint = 0x8037; +export def GL_POLYGON_OFFSET_LINE_NV: uint = 0x2A02; +export def GL_POLYGON_OFFSET_POINT_NV: uint = 0x2A01; +export def GL_POLYGON_OFFSET_UNITS: uint = 0x2A00; +export def GL_PRIMITIVES_GENERATED: uint = 0x8C87; +export def GL_PRIMITIVES_GENERATED_EXT: uint = 0x8C87; +export def GL_PRIMITIVES_GENERATED_OES: uint = 0x8C87; +export def GL_PRIMITIVE_BOUNDING_BOX: uint = 0x92BE; +export def GL_PRIMITIVE_BOUNDING_BOX_EXT: uint = 0x92BE; +export def GL_PRIMITIVE_BOUNDING_BOX_OES: uint = 0x92BE; +export def GL_PRIMITIVE_RESTART_FIXED_INDEX: uint = 0x8D69; +export def GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED: uint = 0x8221; +export def GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES: uint = 0x8221; +export def GL_PROGRAM: uint = 0x82E2; +export def GL_PROGRAMMABLE_SAMPLE_LOCATION_NV: uint = 0x9341; +export def GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV: uint = 0x9340; +export def GL_PROGRAM_BINARY_ANGLE: uint = 0x93A6; +export def GL_PROGRAM_BINARY_FORMATS: uint = 0x87FF; +export def GL_PROGRAM_BINARY_FORMATS_OES: uint = 0x87FF; +export def GL_PROGRAM_BINARY_FORMAT_MESA: uint = 0x875F; +export def GL_PROGRAM_BINARY_LENGTH: uint = 0x8741; +export def GL_PROGRAM_BINARY_LENGTH_OES: uint = 0x8741; +export def GL_PROGRAM_BINARY_RETRIEVABLE_HINT: uint = 0x8257; +export def GL_PROGRAM_INPUT: uint = 0x92E3; +export def GL_PROGRAM_KHR: uint = 0x82E2; +export def GL_PROGRAM_OBJECT_EXT: uint = 0x8B40; +export def GL_PROGRAM_OUTPUT: uint = 0x92E4; +export def GL_PROGRAM_PIPELINE: uint = 0x82E4; +export def GL_PROGRAM_PIPELINE_BINDING: uint = 0x825A; +export def GL_PROGRAM_PIPELINE_BINDING_EXT: uint = 0x825A; +export def GL_PROGRAM_PIPELINE_KHR: uint = 0x82E4; +export def GL_PROGRAM_PIPELINE_OBJECT_EXT: uint = 0x8A4F; +export def GL_PROGRAM_SEPARABLE: uint = 0x8258; +export def GL_PROGRAM_SEPARABLE_EXT: uint = 0x8258; +export def GL_PROTECTED_MEMORY_OBJECT_EXT: uint = 0x959B; +export def GL_QUADRATIC_CURVE_TO_NV: uint = 0x0A; +export def GL_QUADS: uint = 0x0007; +export def GL_QUADS_EXT: uint = 0x0007; +export def GL_QUADS_OES: uint = 0x0007; +export def GL_QUERY: uint = 0x82E3; +export def GL_QUERY_BY_REGION_NO_WAIT_NV: uint = 0x8E16; +export def GL_QUERY_BY_REGION_WAIT_NV: uint = 0x8E15; +export def GL_QUERY_COUNTER_BITS_EXT: uint = 0x8864; +export def GL_QUERY_KHR: uint = 0x82E3; +export def GL_QUERY_NO_WAIT_NV: uint = 0x8E14; +export def GL_QUERY_OBJECT_EXT: uint = 0x9153; +export def GL_QUERY_RESULT: uint = 0x8866; +export def GL_QUERY_RESULT_AVAILABLE: uint = 0x8867; +export def GL_QUERY_RESULT_AVAILABLE_EXT: uint = 0x8867; +export def GL_QUERY_RESULT_EXT: uint = 0x8866; +export def GL_QUERY_WAIT_NV: uint = 0x8E13; +export def GL_R11F_G11F_B10F: uint = 0x8C3A; +export def GL_R11F_G11F_B10F_APPLE: uint = 0x8C3A; +export def GL_R16F: uint = 0x822D; +export def GL_R16F_EXT: uint = 0x822D; +export def GL_R16I: uint = 0x8233; +export def GL_R16UI: uint = 0x8234; +export def GL_R16_EXT: uint = 0x822A; +export def GL_R16_SNORM_EXT: uint = 0x8F98; +export def GL_R32F: uint = 0x822E; +export def GL_R32F_EXT: uint = 0x822E; +export def GL_R32I: uint = 0x8235; +export def GL_R32UI: uint = 0x8236; +export def GL_R8: uint = 0x8229; +export def GL_R8I: uint = 0x8231; +export def GL_R8UI: uint = 0x8232; +export def GL_R8_EXT: uint = 0x8229; +export def GL_R8_SNORM: uint = 0x8F94; +export def GL_RASTERIZER_DISCARD: uint = 0x8C89; +export def GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT: uint = 0x932A; +export def GL_RASTER_MULTISAMPLE_EXT: uint = 0x9327; +export def GL_RASTER_SAMPLES_EXT: uint = 0x9328; +export def GL_READ_BUFFER: uint = 0x0C02; +export def GL_READ_BUFFER_EXT: uint = 0x0C02; +export def GL_READ_BUFFER_NV: uint = 0x0C02; +export def GL_READ_FRAMEBUFFER: uint = 0x8CA8; +export def GL_READ_FRAMEBUFFER_ANGLE: uint = 0x8CA8; +export def GL_READ_FRAMEBUFFER_APPLE: uint = 0x8CA8; +export def GL_READ_FRAMEBUFFER_BINDING: uint = 0x8CAA; +export def GL_READ_FRAMEBUFFER_BINDING_ANGLE: uint = 0x8CAA; +export def GL_READ_FRAMEBUFFER_BINDING_APPLE: uint = 0x8CAA; +export def GL_READ_FRAMEBUFFER_BINDING_NV: uint = 0x8CAA; +export def GL_READ_FRAMEBUFFER_NV: uint = 0x8CA8; +export def GL_READ_ONLY: uint = 0x88B8; +export def GL_READ_WRITE: uint = 0x88BA; +export def GL_RECT_NV: uint = 0xF6; +export def GL_RED: uint = 0x1903; +export def GL_RED_BITS: uint = 0x0D52; +export def GL_RED_EXT: uint = 0x1903; +export def GL_RED_INTEGER: uint = 0x8D94; +export def GL_RED_NV: uint = 0x1903; +export def GL_REFERENCED_BY_COMPUTE_SHADER: uint = 0x930B; +export def GL_REFERENCED_BY_FRAGMENT_SHADER: uint = 0x930A; +export def GL_REFERENCED_BY_GEOMETRY_SHADER: uint = 0x9309; +export def GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: uint = 0x9309; +export def GL_REFERENCED_BY_GEOMETRY_SHADER_OES: uint = 0x9309; +export def GL_REFERENCED_BY_MESH_SHADER_NV: uint = 0x95A0; +export def GL_REFERENCED_BY_TASK_SHADER_NV: uint = 0x95A1; +export def GL_REFERENCED_BY_TESS_CONTROL_SHADER: uint = 0x9307; +export def GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: uint = 0x9307; +export def GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES: uint = 0x9307; +export def GL_REFERENCED_BY_TESS_EVALUATION_SHADER: uint = 0x9308; +export def GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: uint = 0x9308; +export def GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES: uint = 0x9308; +export def GL_REFERENCED_BY_VERTEX_SHADER: uint = 0x9306; +export def GL_RELATIVE_ARC_TO_NV: uint = 0xFF; +export def GL_RELATIVE_CONIC_CURVE_TO_NV: uint = 0x1B; +export def GL_RELATIVE_CUBIC_CURVE_TO_NV: uint = 0x0D; +export def GL_RELATIVE_HORIZONTAL_LINE_TO_NV: uint = 0x07; +export def GL_RELATIVE_LARGE_CCW_ARC_TO_NV: uint = 0x17; +export def GL_RELATIVE_LARGE_CW_ARC_TO_NV: uint = 0x19; +export def GL_RELATIVE_LINE_TO_NV: uint = 0x05; +export def GL_RELATIVE_MOVE_TO_NV: uint = 0x03; +export def GL_RELATIVE_QUADRATIC_CURVE_TO_NV: uint = 0x0B; +export def GL_RELATIVE_RECT_NV: uint = 0xF7; +export def GL_RELATIVE_ROUNDED_RECT2_NV: uint = 0xEB; +export def GL_RELATIVE_ROUNDED_RECT4_NV: uint = 0xED; +export def GL_RELATIVE_ROUNDED_RECT8_NV: uint = 0xEF; +export def GL_RELATIVE_ROUNDED_RECT_NV: uint = 0xE9; +export def GL_RELATIVE_SMALL_CCW_ARC_TO_NV: uint = 0x13; +export def GL_RELATIVE_SMALL_CW_ARC_TO_NV: uint = 0x15; +export def GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV: uint = 0x11; +export def GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV: uint = 0x0F; +export def GL_RELATIVE_VERTICAL_LINE_TO_NV: uint = 0x09; +export def GL_RENDERBUFFER: uint = 0x8D41; +export def GL_RENDERBUFFER_ALPHA_SIZE: uint = 0x8D53; +export def GL_RENDERBUFFER_BINDING: uint = 0x8CA7; +export def GL_RENDERBUFFER_BLUE_SIZE: uint = 0x8D52; +export def GL_RENDERBUFFER_DEPTH_SIZE: uint = 0x8D54; +export def GL_RENDERBUFFER_GREEN_SIZE: uint = 0x8D51; +export def GL_RENDERBUFFER_HEIGHT: uint = 0x8D43; +export def GL_RENDERBUFFER_INTERNAL_FORMAT: uint = 0x8D44; +export def GL_RENDERBUFFER_RED_SIZE: uint = 0x8D50; +export def GL_RENDERBUFFER_SAMPLES: uint = 0x8CAB; +export def GL_RENDERBUFFER_SAMPLES_ANGLE: uint = 0x8CAB; +export def GL_RENDERBUFFER_SAMPLES_APPLE: uint = 0x8CAB; +export def GL_RENDERBUFFER_SAMPLES_EXT: uint = 0x8CAB; +export def GL_RENDERBUFFER_SAMPLES_IMG: uint = 0x9133; +export def GL_RENDERBUFFER_SAMPLES_NV: uint = 0x8CAB; +export def GL_RENDERBUFFER_STENCIL_SIZE: uint = 0x8D55; +export def GL_RENDERBUFFER_STORAGE_SAMPLES_AMD: uint = 0x91B2; +export def GL_RENDERBUFFER_WIDTH: uint = 0x8D42; +export def GL_RENDERER: uint = 0x1F01; +export def GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM: uint = 0x8FB3; +export def GL_REPEAT: uint = 0x2901; +export def GL_REPLACE: uint = 0x1E01; +export def GL_REPRESENTATIVE_FRAGMENT_TEST_NV: uint = 0x937F; +export def GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: uint = 0x8D68; +export def GL_RESET_NOTIFICATION_STRATEGY: uint = 0x8256; +export def GL_RESET_NOTIFICATION_STRATEGY_EXT: uint = 0x8256; +export def GL_RESET_NOTIFICATION_STRATEGY_KHR: uint = 0x8256; +export def GL_RESTART_PATH_NV: uint = 0xF0; +export def GL_RG: uint = 0x8227; +export def GL_RG16F: uint = 0x822F; +export def GL_RG16F_EXT: uint = 0x822F; +export def GL_RG16I: uint = 0x8239; +export def GL_RG16UI: uint = 0x823A; +export def GL_RG16_EXT: uint = 0x822C; +export def GL_RG16_SNORM_EXT: uint = 0x8F99; +export def GL_RG32F: uint = 0x8230; +export def GL_RG32F_EXT: uint = 0x8230; +export def GL_RG32I: uint = 0x823B; +export def GL_RG32UI: uint = 0x823C; +export def GL_RG8: uint = 0x822B; +export def GL_RG8I: uint = 0x8237; +export def GL_RG8UI: uint = 0x8238; +export def GL_RG8_EXT: uint = 0x822B; +export def GL_RG8_SNORM: uint = 0x8F95; +export def GL_RGB: uint = 0x1907; +export def GL_RGB10_A2: uint = 0x8059; +export def GL_RGB10_A2UI: uint = 0x906F; +export def GL_RGB10_A2_EXT: uint = 0x8059; +export def GL_RGB10_EXT: uint = 0x8052; +export def GL_RGB16F: uint = 0x881B; +export def GL_RGB16F_EXT: uint = 0x881B; +export def GL_RGB16I: uint = 0x8D89; +export def GL_RGB16UI: uint = 0x8D77; +export def GL_RGB16_EXT: uint = 0x8054; +export def GL_RGB16_SNORM_EXT: uint = 0x8F9A; +export def GL_RGB32F: uint = 0x8815; +export def GL_RGB32F_EXT: uint = 0x8815; +export def GL_RGB32I: uint = 0x8D83; +export def GL_RGB32UI: uint = 0x8D71; +export def GL_RGB565: uint = 0x8D62; +export def GL_RGB565_OES: uint = 0x8D62; +export def GL_RGB5_A1: uint = 0x8057; +export def GL_RGB5_A1_OES: uint = 0x8057; +export def GL_RGB8: uint = 0x8051; +export def GL_RGB8I: uint = 0x8D8F; +export def GL_RGB8UI: uint = 0x8D7D; +export def GL_RGB8_OES: uint = 0x8051; +export def GL_RGB8_SNORM: uint = 0x8F96; +export def GL_RGB9_E5: uint = 0x8C3D; +export def GL_RGB9_E5_APPLE: uint = 0x8C3D; +export def GL_RGBA: uint = 0x1908; +export def GL_RGBA16F: uint = 0x881A; +export def GL_RGBA16F_EXT: uint = 0x881A; +export def GL_RGBA16I: uint = 0x8D88; +export def GL_RGBA16UI: uint = 0x8D76; +export def GL_RGBA16_EXT: uint = 0x805B; +export def GL_RGBA16_SNORM_EXT: uint = 0x8F9B; +export def GL_RGBA32F: uint = 0x8814; +export def GL_RGBA32F_EXT: uint = 0x8814; +export def GL_RGBA32I: uint = 0x8D82; +export def GL_RGBA32UI: uint = 0x8D70; +export def GL_RGBA4: uint = 0x8056; +export def GL_RGBA4_OES: uint = 0x8056; +export def GL_RGBA8: uint = 0x8058; +export def GL_RGBA8I: uint = 0x8D8E; +export def GL_RGBA8UI: uint = 0x8D7C; +export def GL_RGBA8_OES: uint = 0x8058; +export def GL_RGBA8_SNORM: uint = 0x8F97; +export def GL_RGBA_INTEGER: uint = 0x8D99; +export def GL_RGB_422_APPLE: uint = 0x8A1F; +export def GL_RGB_INTEGER: uint = 0x8D98; +export def GL_RGB_RAW_422_APPLE: uint = 0x8A51; +export def GL_RG_EXT: uint = 0x8227; +export def GL_RG_INTEGER: uint = 0x8228; +export def GL_ROUNDED_RECT2_NV: uint = 0xEA; +export def GL_ROUNDED_RECT4_NV: uint = 0xEC; +export def GL_ROUNDED_RECT8_NV: uint = 0xEE; +export def GL_ROUNDED_RECT_NV: uint = 0xE8; +export def GL_ROUND_NV: uint = 0x90A4; +export def GL_SAMPLER: uint = 0x82E6; +export def GL_SAMPLER_2D: uint = 0x8B5E; +export def GL_SAMPLER_2D_ARRAY: uint = 0x8DC1; +export def GL_SAMPLER_2D_ARRAY_SHADOW: uint = 0x8DC4; +export def GL_SAMPLER_2D_ARRAY_SHADOW_NV: uint = 0x8DC4; +export def GL_SAMPLER_2D_MULTISAMPLE: uint = 0x9108; +export def GL_SAMPLER_2D_MULTISAMPLE_ARRAY: uint = 0x910B; +export def GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES: uint = 0x910B; +export def GL_SAMPLER_2D_SHADOW: uint = 0x8B62; +export def GL_SAMPLER_2D_SHADOW_EXT: uint = 0x8B62; +export def GL_SAMPLER_3D: uint = 0x8B5F; +export def GL_SAMPLER_3D_OES: uint = 0x8B5F; +export def GL_SAMPLER_BINDING: uint = 0x8919; +export def GL_SAMPLER_BUFFER: uint = 0x8DC2; +export def GL_SAMPLER_BUFFER_EXT: uint = 0x8DC2; +export def GL_SAMPLER_BUFFER_OES: uint = 0x8DC2; +export def GL_SAMPLER_CUBE: uint = 0x8B60; +export def GL_SAMPLER_CUBE_MAP_ARRAY: uint = 0x900C; +export def GL_SAMPLER_CUBE_MAP_ARRAY_EXT: uint = 0x900C; +export def GL_SAMPLER_CUBE_MAP_ARRAY_OES: uint = 0x900C; +export def GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: uint = 0x900D; +export def GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT: uint = 0x900D; +export def GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES: uint = 0x900D; +export def GL_SAMPLER_CUBE_SHADOW: uint = 0x8DC5; +export def GL_SAMPLER_CUBE_SHADOW_NV: uint = 0x8DC5; +export def GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT: uint = 0x8BE7; +export def GL_SAMPLER_EXTERNAL_OES: uint = 0x8D66; +export def GL_SAMPLER_KHR: uint = 0x82E6; +export def GL_SAMPLES: uint = 0x80A9; +export def GL_SAMPLE_ALPHA_TO_COVERAGE: uint = 0x809E; +export def GL_SAMPLE_ALPHA_TO_ONE_EXT: uint = 0x809F; +export def GL_SAMPLE_BUFFERS: uint = 0x80A8; +export def GL_SAMPLE_COVERAGE: uint = 0x80A0; +export def GL_SAMPLE_COVERAGE_INVERT: uint = 0x80AB; +export def GL_SAMPLE_COVERAGE_VALUE: uint = 0x80AA; +export def GL_SAMPLE_LOCATION_NV: uint = 0x8E50; +export def GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV: uint = 0x933F; +export def GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV: uint = 0x933E; +export def GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV: uint = 0x933D; +export def GL_SAMPLE_MASK: uint = 0x8E51; +export def GL_SAMPLE_MASK_VALUE: uint = 0x8E52; +export def GL_SAMPLE_POSITION: uint = 0x8E50; +export def GL_SAMPLE_POSITION_NV: uint = 0x8E50; +export def GL_SAMPLE_SHADING: uint = 0x8C36; +export def GL_SAMPLE_SHADING_OES: uint = 0x8C36; +export def GL_SCISSOR_BOX: uint = 0x0C10; +export def GL_SCISSOR_BOX_EXCLUSIVE_NV: uint = 0x9556; +export def GL_SCISSOR_TEST: uint = 0x0C11; +export def GL_SCISSOR_TEST_EXCLUSIVE_NV: uint = 0x9555; +export def GL_SCREEN: uint = 0x9295; +export def GL_SCREEN_KHR: uint = 0x9295; +export def GL_SCREEN_NV: uint = 0x9295; +export def GL_SEMAPHORE_TYPE_BINARY_NV: uint = 0x95B4; +export def GL_SEMAPHORE_TYPE_NV: uint = 0x95B3; +export def GL_SEMAPHORE_TYPE_TIMELINE_NV: uint = 0x95B5; +export def GL_SEPARATE_ATTRIBS: uint = 0x8C8D; +export def GL_SGX_BINARY_IMG: uint = 0x8C0A; +export def GL_SGX_PROGRAM_BINARY_IMG: uint = 0x9130; +export def GL_SHADER: uint = 0x82E1; +export def GL_SHADER_BINARY_DMP: uint = 0x9250; +export def GL_SHADER_BINARY_FORMATS: uint = 0x8DF8; +export def GL_SHADER_BINARY_VIV: uint = 0x8FC4; +export def GL_SHADER_COMPILER: uint = 0x8DFA; +export def GL_SHADER_IMAGE_ACCESS_BARRIER_BIT: uint = 0x00000020; +export def GL_SHADER_KHR: uint = 0x82E1; +export def GL_SHADER_OBJECT_EXT: uint = 0x8B48; +export def GL_SHADER_PIXEL_LOCAL_STORAGE_EXT: uint = 0x8F64; +export def GL_SHADER_SOURCE_LENGTH: uint = 0x8B88; +export def GL_SHADER_STORAGE_BARRIER_BIT: uint = 0x00002000; +export def GL_SHADER_STORAGE_BLOCK: uint = 0x92E6; +export def GL_SHADER_STORAGE_BUFFER: uint = 0x90D2; +export def GL_SHADER_STORAGE_BUFFER_BINDING: uint = 0x90D3; +export def GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: uint = 0x90DF; +export def GL_SHADER_STORAGE_BUFFER_SIZE: uint = 0x90D5; +export def GL_SHADER_STORAGE_BUFFER_START: uint = 0x90D4; +export def GL_SHADER_TYPE: uint = 0x8B4F; +export def GL_SHADING_LANGUAGE_VERSION: uint = 0x8B8C; +export def GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV: uint = 0x956F; +export def GL_SHADING_RATE_1X1_PIXELS_EXT: uint = 0x96A6; +export def GL_SHADING_RATE_1X1_PIXELS_QCOM: uint = 0x96A6; +export def GL_SHADING_RATE_1X2_PIXELS_EXT: uint = 0x96A7; +export def GL_SHADING_RATE_1X2_PIXELS_QCOM: uint = 0x96A7; +export def GL_SHADING_RATE_1X4_PIXELS_EXT: uint = 0x96AA; +export def GL_SHADING_RATE_1X4_PIXELS_QCOM: uint = 0x96AA; +export def GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV: uint = 0x9566; +export def GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV: uint = 0x9567; +export def GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV: uint = 0x9568; +export def GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV: uint = 0x9569; +export def GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV: uint = 0x956A; +export def GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV: uint = 0x956B; +export def GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV: uint = 0x9565; +export def GL_SHADING_RATE_2X1_PIXELS_EXT: uint = 0x96A8; +export def GL_SHADING_RATE_2X1_PIXELS_QCOM: uint = 0x96A8; +export def GL_SHADING_RATE_2X2_PIXELS_EXT: uint = 0x96A9; +export def GL_SHADING_RATE_2X2_PIXELS_QCOM: uint = 0x96A9; +export def GL_SHADING_RATE_2X4_PIXELS_EXT: uint = 0x96AD; +export def GL_SHADING_RATE_2X4_PIXELS_QCOM: uint = 0x96AD; +export def GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV: uint = 0x956C; +export def GL_SHADING_RATE_4X1_PIXELS_EXT: uint = 0x96AB; +export def GL_SHADING_RATE_4X1_PIXELS_QCOM: uint = 0x96AB; +export def GL_SHADING_RATE_4X2_PIXELS_EXT: uint = 0x96AC; +export def GL_SHADING_RATE_4X2_PIXELS_QCOM: uint = 0x96AC; +export def GL_SHADING_RATE_4X4_PIXELS_EXT: uint = 0x96AE; +export def GL_SHADING_RATE_4X4_PIXELS_QCOM: uint = 0x96AE; +export def GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV: uint = 0x956D; +export def GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV: uint = 0x956E; +export def GL_SHADING_RATE_ATTACHMENT_EXT: uint = 0x96D1; +export def GL_SHADING_RATE_EXT: uint = 0x96D0; +export def GL_SHADING_RATE_IMAGE_BINDING_NV: uint = 0x955B; +export def GL_SHADING_RATE_IMAGE_NV: uint = 0x9563; +export def GL_SHADING_RATE_IMAGE_PALETTE_COUNT_NV: uint = 0x95B2; +export def GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV: uint = 0x955E; +export def GL_SHADING_RATE_IMAGE_PER_PRIMITIVE_NV: uint = 0x95B1; +export def GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV: uint = 0x955D; +export def GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV: uint = 0x955C; +export def GL_SHADING_RATE_NO_INVOCATIONS_NV: uint = 0x9564; +export def GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM: uint = 0x96A5; +export def GL_SHADING_RATE_QCOM: uint = 0x96A4; +export def GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV: uint = 0x95AE; +export def GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV: uint = 0x95AF; +export def GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV: uint = 0x95B0; +export def GL_SHARED_EDGE_NV: uint = 0xC0; +export def GL_SHORT: uint = 0x1402; +export def GL_SIGNALED: uint = 0x9119; +export def GL_SIGNALED_APPLE: uint = 0x9119; +export def GL_SIGNED_NORMALIZED: uint = 0x8F9C; +export def GL_SKIP_DECODE_EXT: uint = 0x8A4A; +export def GL_SKIP_MISSING_GLYPH_NV: uint = 0x90A9; +export def GL_SLUMINANCE8_ALPHA8_NV: uint = 0x8C45; +export def GL_SLUMINANCE8_NV: uint = 0x8C47; +export def GL_SLUMINANCE_ALPHA_NV: uint = 0x8C44; +export def GL_SLUMINANCE_NV: uint = 0x8C46; +export def GL_SMALL_CCW_ARC_TO_NV: uint = 0x12; +export def GL_SMALL_CW_ARC_TO_NV: uint = 0x14; +export def GL_SMAPHS30_PROGRAM_BINARY_DMP: uint = 0x9251; +export def GL_SMAPHS_PROGRAM_BINARY_DMP: uint = 0x9252; +export def GL_SMOOTH_CUBIC_CURVE_TO_NV: uint = 0x10; +export def GL_SMOOTH_QUADRATIC_CURVE_TO_NV: uint = 0x0E; +export def GL_SOFTLIGHT: uint = 0x929C; +export def GL_SOFTLIGHT_KHR: uint = 0x929C; +export def GL_SOFTLIGHT_NV: uint = 0x929C; +export def GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT: uint = 0x91A9; +export def GL_SQUARE_NV: uint = 0x90A3; +export def GL_SR8_EXT: uint = 0x8FBD; +export def GL_SRC1_ALPHA_EXT: uint = 0x8589; +export def GL_SRC1_COLOR_EXT: uint = 0x88F9; +export def GL_SRC_ALPHA: uint = 0x0302; +export def GL_SRC_ALPHA_SATURATE: uint = 0x0308; +export def GL_SRC_ALPHA_SATURATE_EXT: uint = 0x0308; +export def GL_SRC_ATOP_NV: uint = 0x928E; +export def GL_SRC_COLOR: uint = 0x0300; +export def GL_SRC_IN_NV: uint = 0x928A; +export def GL_SRC_NV: uint = 0x9286; +export def GL_SRC_OUT_NV: uint = 0x928C; +export def GL_SRC_OVER_NV: uint = 0x9288; +export def GL_SRG8_EXT: uint = 0x8FBE; +export def GL_SRGB: uint = 0x8C40; +export def GL_SRGB8: uint = 0x8C41; +export def GL_SRGB8_ALPHA8: uint = 0x8C43; +export def GL_SRGB8_ALPHA8_EXT: uint = 0x8C43; +export def GL_SRGB8_NV: uint = 0x8C41; +export def GL_SRGB_ALPHA_EXT: uint = 0x8C42; +export def GL_SRGB_EXT: uint = 0x8C40; +export def GL_STACK_OVERFLOW: uint = 0x0503; +export def GL_STACK_OVERFLOW_KHR: uint = 0x0503; +export def GL_STACK_UNDERFLOW: uint = 0x0504; +export def GL_STACK_UNDERFLOW_KHR: uint = 0x0504; +export def GL_STANDARD_FONT_FORMAT_NV: uint = 0x936C; +export def GL_STANDARD_FONT_NAME_NV: uint = 0x9072; +export def GL_STATE_RESTORE: uint = 0x8BDC; +export def GL_STATIC_COPY: uint = 0x88E6; +export def GL_STATIC_DRAW: uint = 0x88E4; +export def GL_STATIC_READ: uint = 0x88E5; +export def GL_STENCIL: uint = 0x1802; +export def GL_STENCIL_ATTACHMENT: uint = 0x8D20; +export def GL_STENCIL_BACK_FAIL: uint = 0x8801; +export def GL_STENCIL_BACK_FUNC: uint = 0x8800; +export def GL_STENCIL_BACK_PASS_DEPTH_FAIL: uint = 0x8802; +export def GL_STENCIL_BACK_PASS_DEPTH_PASS: uint = 0x8803; +export def GL_STENCIL_BACK_REF: uint = 0x8CA3; +export def GL_STENCIL_BACK_VALUE_MASK: uint = 0x8CA4; +export def GL_STENCIL_BACK_WRITEMASK: uint = 0x8CA5; +export def GL_STENCIL_BITS: uint = 0x0D57; +export def GL_STENCIL_BUFFER_BIT: uint = 0x00000400; +export def GL_STENCIL_BUFFER_BIT0_QCOM: uint = 0x00010000; +export def GL_STENCIL_BUFFER_BIT1_QCOM: uint = 0x00020000; +export def GL_STENCIL_BUFFER_BIT2_QCOM: uint = 0x00040000; +export def GL_STENCIL_BUFFER_BIT3_QCOM: uint = 0x00080000; +export def GL_STENCIL_BUFFER_BIT4_QCOM: uint = 0x00100000; +export def GL_STENCIL_BUFFER_BIT5_QCOM: uint = 0x00200000; +export def GL_STENCIL_BUFFER_BIT6_QCOM: uint = 0x00400000; +export def GL_STENCIL_BUFFER_BIT7_QCOM: uint = 0x00800000; +export def GL_STENCIL_CLEAR_VALUE: uint = 0x0B91; +export def GL_STENCIL_EXT: uint = 0x1802; +export def GL_STENCIL_FAIL: uint = 0x0B94; +export def GL_STENCIL_FUNC: uint = 0x0B92; +export def GL_STENCIL_INDEX: uint = 0x1901; +export def GL_STENCIL_INDEX1_OES: uint = 0x8D46; +export def GL_STENCIL_INDEX4_OES: uint = 0x8D47; +export def GL_STENCIL_INDEX8: uint = 0x8D48; +export def GL_STENCIL_INDEX8_OES: uint = 0x8D48; +export def GL_STENCIL_INDEX_OES: uint = 0x1901; +export def GL_STENCIL_PASS_DEPTH_FAIL: uint = 0x0B95; +export def GL_STENCIL_PASS_DEPTH_PASS: uint = 0x0B96; +export def GL_STENCIL_REF: uint = 0x0B97; +export def GL_STENCIL_SAMPLES_NV: uint = 0x932E; +export def GL_STENCIL_TEST: uint = 0x0B90; +export def GL_STENCIL_VALUE_MASK: uint = 0x0B93; +export def GL_STENCIL_WRITEMASK: uint = 0x0B98; +export def GL_STREAM_COPY: uint = 0x88E2; +export def GL_STREAM_DRAW: uint = 0x88E0; +export def GL_STREAM_READ: uint = 0x88E1; +export def GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR: uint = 0x00000004; +export def GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR: uint = 0x00000008; +export def GL_SUBGROUP_FEATURE_BASIC_BIT_KHR: uint = 0x00000001; +export def GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR: uint = 0x00000040; +export def GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV: uint = 0x00000100; +export def GL_SUBGROUP_FEATURE_QUAD_BIT_KHR: uint = 0x00000080; +export def GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR: uint = 0x00000010; +export def GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR: uint = 0x00000020; +export def GL_SUBGROUP_FEATURE_VOTE_BIT_KHR: uint = 0x00000002; +export def GL_SUBGROUP_QUAD_ALL_STAGES_KHR: uint = 0x9535; +export def GL_SUBGROUP_SIZE_KHR: uint = 0x9532; +export def GL_SUBGROUP_SUPPORTED_FEATURES_KHR: uint = 0x9534; +export def GL_SUBGROUP_SUPPORTED_STAGES_KHR: uint = 0x9533; +export def GL_SUBPIXEL_BITS: uint = 0x0D50; +export def GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV: uint = 0x9347; +export def GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV: uint = 0x9348; +export def GL_SUPERSAMPLE_SCALE_X_NV: uint = 0x9372; +export def GL_SUPERSAMPLE_SCALE_Y_NV: uint = 0x9373; +export def GL_SUPPORTED_MULTISAMPLE_MODES_AMD: uint = 0x91B7; +export def GL_SURFACE_COMPRESSION_EXT: uint = 0x96C0; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT: uint = 0x96CD; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT: uint = 0x96CE; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT: uint = 0x96CF; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT: uint = 0x96C4; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT: uint = 0x96C5; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT: uint = 0x96C6; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT: uint = 0x96C7; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT: uint = 0x96C8; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT: uint = 0x96C9; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT: uint = 0x96CA; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT: uint = 0x96CB; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT: uint = 0x96CC; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT: uint = 0x96C2; +export def GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT: uint = 0x96C1; +export def GL_SYNC_CONDITION: uint = 0x9113; +export def GL_SYNC_CONDITION_APPLE: uint = 0x9113; +export def GL_SYNC_FENCE: uint = 0x9116; +export def GL_SYNC_FENCE_APPLE: uint = 0x9116; +export def GL_SYNC_FLAGS: uint = 0x9115; +export def GL_SYNC_FLAGS_APPLE: uint = 0x9115; +export def GL_SYNC_FLUSH_COMMANDS_BIT: uint = 0x00000001; +export def GL_SYNC_FLUSH_COMMANDS_BIT_APPLE: uint = 0x00000001; +export def GL_SYNC_GPU_COMMANDS_COMPLETE: uint = 0x9117; +export def GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE: uint = 0x9117; +export def GL_SYNC_OBJECT_APPLE: uint = 0x8A53; +export def GL_SYNC_STATUS: uint = 0x9114; +export def GL_SYNC_STATUS_APPLE: uint = 0x9114; +export def GL_SYSTEM_FONT_NAME_NV: uint = 0x9073; +export def GL_TASK_SHADER_BIT_NV: uint = 0x00000080; +export def GL_TASK_SHADER_NV: uint = 0x955A; +export def GL_TASK_SUBROUTINE_NV: uint = 0x957D; +export def GL_TASK_SUBROUTINE_UNIFORM_NV: uint = 0x957F; +export def GL_TASK_WORK_GROUP_SIZE_NV: uint = 0x953F; +export def GL_TESS_CONTROL_OUTPUT_VERTICES: uint = 0x8E75; +export def GL_TESS_CONTROL_OUTPUT_VERTICES_EXT: uint = 0x8E75; +export def GL_TESS_CONTROL_OUTPUT_VERTICES_OES: uint = 0x8E75; +export def GL_TESS_CONTROL_SHADER: uint = 0x8E88; +export def GL_TESS_CONTROL_SHADER_BIT: uint = 0x00000008; +export def GL_TESS_CONTROL_SHADER_BIT_EXT: uint = 0x00000008; +export def GL_TESS_CONTROL_SHADER_BIT_OES: uint = 0x00000008; +export def GL_TESS_CONTROL_SHADER_EXT: uint = 0x8E88; +export def GL_TESS_CONTROL_SHADER_OES: uint = 0x8E88; +export def GL_TESS_EVALUATION_SHADER: uint = 0x8E87; +export def GL_TESS_EVALUATION_SHADER_BIT: uint = 0x00000010; +export def GL_TESS_EVALUATION_SHADER_BIT_EXT: uint = 0x00000010; +export def GL_TESS_EVALUATION_SHADER_BIT_OES: uint = 0x00000010; +export def GL_TESS_EVALUATION_SHADER_EXT: uint = 0x8E87; +export def GL_TESS_EVALUATION_SHADER_OES: uint = 0x8E87; +export def GL_TESS_GEN_MODE: uint = 0x8E76; +export def GL_TESS_GEN_MODE_EXT: uint = 0x8E76; +export def GL_TESS_GEN_MODE_OES: uint = 0x8E76; +export def GL_TESS_GEN_POINT_MODE: uint = 0x8E79; +export def GL_TESS_GEN_POINT_MODE_EXT: uint = 0x8E79; +export def GL_TESS_GEN_POINT_MODE_OES: uint = 0x8E79; +export def GL_TESS_GEN_SPACING: uint = 0x8E77; +export def GL_TESS_GEN_SPACING_EXT: uint = 0x8E77; +export def GL_TESS_GEN_SPACING_OES: uint = 0x8E77; +export def GL_TESS_GEN_VERTEX_ORDER: uint = 0x8E78; +export def GL_TESS_GEN_VERTEX_ORDER_EXT: uint = 0x8E78; +export def GL_TESS_GEN_VERTEX_ORDER_OES: uint = 0x8E78; +export def GL_TEXTURE: uint = 0x1702; +export def GL_TEXTURE0: uint = 0x84C0; +export def GL_TEXTURE1: uint = 0x84C1; +export def GL_TEXTURE10: uint = 0x84CA; +export def GL_TEXTURE11: uint = 0x84CB; +export def GL_TEXTURE12: uint = 0x84CC; +export def GL_TEXTURE13: uint = 0x84CD; +export def GL_TEXTURE14: uint = 0x84CE; +export def GL_TEXTURE15: uint = 0x84CF; +export def GL_TEXTURE16: uint = 0x84D0; +export def GL_TEXTURE17: uint = 0x84D1; +export def GL_TEXTURE18: uint = 0x84D2; +export def GL_TEXTURE19: uint = 0x84D3; +export def GL_TEXTURE2: uint = 0x84C2; +export def GL_TEXTURE20: uint = 0x84D4; +export def GL_TEXTURE21: uint = 0x84D5; +export def GL_TEXTURE22: uint = 0x84D6; +export def GL_TEXTURE23: uint = 0x84D7; +export def GL_TEXTURE24: uint = 0x84D8; +export def GL_TEXTURE25: uint = 0x84D9; +export def GL_TEXTURE26: uint = 0x84DA; +export def GL_TEXTURE27: uint = 0x84DB; +export def GL_TEXTURE28: uint = 0x84DC; +export def GL_TEXTURE29: uint = 0x84DD; +export def GL_TEXTURE3: uint = 0x84C3; +export def GL_TEXTURE30: uint = 0x84DE; +export def GL_TEXTURE31: uint = 0x84DF; +export def GL_TEXTURE4: uint = 0x84C4; +export def GL_TEXTURE5: uint = 0x84C5; +export def GL_TEXTURE6: uint = 0x84C6; +export def GL_TEXTURE7: uint = 0x84C7; +export def GL_TEXTURE8: uint = 0x84C8; +export def GL_TEXTURE9: uint = 0x84C9; +export def GL_TEXTURE_2D: uint = 0x0DE1; +export def GL_TEXTURE_2D_ARRAY: uint = 0x8C1A; +export def GL_TEXTURE_2D_MULTISAMPLE: uint = 0x9100; +export def GL_TEXTURE_2D_MULTISAMPLE_ARRAY: uint = 0x9102; +export def GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES: uint = 0x9102; +export def GL_TEXTURE_3D: uint = 0x806F; +export def GL_TEXTURE_3D_OES: uint = 0x806F; +export def GL_TEXTURE_ALPHA_SIZE: uint = 0x805F; +export def GL_TEXTURE_ALPHA_TYPE: uint = 0x8C13; +export def GL_TEXTURE_ASTC_DECODE_PRECISION_EXT: uint = 0x8F69; +export def GL_TEXTURE_BASE_LEVEL: uint = 0x813C; +export def GL_TEXTURE_BINDING_2D: uint = 0x8069; +export def GL_TEXTURE_BINDING_2D_ARRAY: uint = 0x8C1D; +export def GL_TEXTURE_BINDING_2D_MULTISAMPLE: uint = 0x9104; +export def GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: uint = 0x9105; +export def GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES: uint = 0x9105; +export def GL_TEXTURE_BINDING_3D: uint = 0x806A; +export def GL_TEXTURE_BINDING_3D_OES: uint = 0x806A; +export def GL_TEXTURE_BINDING_BUFFER: uint = 0x8C2C; +export def GL_TEXTURE_BINDING_BUFFER_EXT: uint = 0x8C2C; +export def GL_TEXTURE_BINDING_BUFFER_OES: uint = 0x8C2C; +export def GL_TEXTURE_BINDING_CUBE_MAP: uint = 0x8514; +export def GL_TEXTURE_BINDING_CUBE_MAP_ARRAY: uint = 0x900A; +export def GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT: uint = 0x900A; +export def GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES: uint = 0x900A; +export def GL_TEXTURE_BINDING_EXTERNAL_OES: uint = 0x8D67; +export def GL_TEXTURE_BLUE_SIZE: uint = 0x805E; +export def GL_TEXTURE_BLUE_TYPE: uint = 0x8C12; +export def GL_TEXTURE_BORDER_COLOR: uint = 0x1004; +export def GL_TEXTURE_BORDER_COLOR_EXT: uint = 0x1004; +export def GL_TEXTURE_BORDER_COLOR_NV: uint = 0x1004; +export def GL_TEXTURE_BORDER_COLOR_OES: uint = 0x1004; +export def GL_TEXTURE_BUFFER: uint = 0x8C2A; +export def GL_TEXTURE_BUFFER_BINDING: uint = 0x8C2A; +export def GL_TEXTURE_BUFFER_BINDING_EXT: uint = 0x8C2A; +export def GL_TEXTURE_BUFFER_BINDING_OES: uint = 0x8C2A; +export def GL_TEXTURE_BUFFER_DATA_STORE_BINDING: uint = 0x8C2D; +export def GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT: uint = 0x8C2D; +export def GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES: uint = 0x8C2D; +export def GL_TEXTURE_BUFFER_EXT: uint = 0x8C2A; +export def GL_TEXTURE_BUFFER_OES: uint = 0x8C2A; +export def GL_TEXTURE_BUFFER_OFFSET: uint = 0x919D; +export def GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT: uint = 0x919F; +export def GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT: uint = 0x919F; +export def GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES: uint = 0x919F; +export def GL_TEXTURE_BUFFER_OFFSET_EXT: uint = 0x919D; +export def GL_TEXTURE_BUFFER_OFFSET_OES: uint = 0x919D; +export def GL_TEXTURE_BUFFER_SIZE: uint = 0x919E; +export def GL_TEXTURE_BUFFER_SIZE_EXT: uint = 0x919E; +export def GL_TEXTURE_BUFFER_SIZE_OES: uint = 0x919E; +export def GL_TEXTURE_COMPARE_FUNC: uint = 0x884D; +export def GL_TEXTURE_COMPARE_FUNC_EXT: uint = 0x884D; +export def GL_TEXTURE_COMPARE_MODE: uint = 0x884C; +export def GL_TEXTURE_COMPARE_MODE_EXT: uint = 0x884C; +export def GL_TEXTURE_COMPRESSED: uint = 0x86A1; +export def GL_TEXTURE_CUBE_MAP: uint = 0x8513; +export def GL_TEXTURE_CUBE_MAP_ARRAY: uint = 0x9009; +export def GL_TEXTURE_CUBE_MAP_ARRAY_EXT: uint = 0x9009; +export def GL_TEXTURE_CUBE_MAP_ARRAY_OES: uint = 0x9009; +export def GL_TEXTURE_CUBE_MAP_NEGATIVE_X: uint = 0x8516; +export def GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: uint = 0x8518; +export def GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: uint = 0x851A; +export def GL_TEXTURE_CUBE_MAP_POSITIVE_X: uint = 0x8515; +export def GL_TEXTURE_CUBE_MAP_POSITIVE_Y: uint = 0x8517; +export def GL_TEXTURE_CUBE_MAP_POSITIVE_Z: uint = 0x8519; +export def GL_TEXTURE_DEPTH: uint = 0x8071; +export def GL_TEXTURE_DEPTH_QCOM: uint = 0x8BD4; +export def GL_TEXTURE_DEPTH_SIZE: uint = 0x884A; +export def GL_TEXTURE_DEPTH_TYPE: uint = 0x8C16; +export def GL_TEXTURE_EXTERNAL_OES: uint = 0x8D65; +export def GL_TEXTURE_FETCH_BARRIER_BIT: uint = 0x00000008; +export def GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: uint = 0x9107; +export def GL_TEXTURE_FORMAT_QCOM: uint = 0x8BD6; +export def GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT: uint = 0x8FBF; +export def GL_TEXTURE_FOVEATED_CUTOFF_DENSITY_QCOM: uint = 0x96A0; +export def GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM: uint = 0x8BFB; +export def GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM: uint = 0x8BFD; +export def GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM: uint = 0x8BFC; +export def GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM: uint = 0x8BFE; +export def GL_TEXTURE_GREEN_SIZE: uint = 0x805D; +export def GL_TEXTURE_GREEN_TYPE: uint = 0x8C11; +export def GL_TEXTURE_HEIGHT: uint = 0x1001; +export def GL_TEXTURE_HEIGHT_QCOM: uint = 0x8BD3; +export def GL_TEXTURE_IMAGE_VALID_QCOM: uint = 0x8BD8; +export def GL_TEXTURE_IMMUTABLE_FORMAT: uint = 0x912F; +export def GL_TEXTURE_IMMUTABLE_FORMAT_EXT: uint = 0x912F; +export def GL_TEXTURE_IMMUTABLE_LEVELS: uint = 0x82DF; +export def GL_TEXTURE_INTERNAL_FORMAT: uint = 0x1003; +export def GL_TEXTURE_INTERNAL_FORMAT_QCOM: uint = 0x8BD5; +export def GL_TEXTURE_MAG_FILTER: uint = 0x2800; +export def GL_TEXTURE_MAX_ANISOTROPY: uint = 0x84FE; +export def GL_TEXTURE_MAX_ANISOTROPY_EXT: uint = 0x84FE; +export def GL_TEXTURE_MAX_LEVEL: uint = 0x813D; +export def GL_TEXTURE_MAX_LEVEL_APPLE: uint = 0x813D; +export def GL_TEXTURE_MAX_LOD: uint = 0x813B; +export def GL_TEXTURE_MIN_FILTER: uint = 0x2801; +export def GL_TEXTURE_MIN_LOD: uint = 0x813A; +export def GL_TEXTURE_NUM_LEVELS_QCOM: uint = 0x8BD9; +export def GL_TEXTURE_OBJECT_VALID_QCOM: uint = 0x8BDB; +export def GL_TEXTURE_PROTECTED_EXT: uint = 0x8BFA; +export def GL_TEXTURE_REDUCTION_MODE_ARB: uint = 0x9366; +export def GL_TEXTURE_REDUCTION_MODE_EXT: uint = 0x9366; +export def GL_TEXTURE_RED_SIZE: uint = 0x805C; +export def GL_TEXTURE_RED_TYPE: uint = 0x8C10; +export def GL_TEXTURE_SAMPLES: uint = 0x9106; +export def GL_TEXTURE_SAMPLES_IMG: uint = 0x9136; +export def GL_TEXTURE_SHARED_SIZE: uint = 0x8C3F; +export def GL_TEXTURE_SPARSE_EXT: uint = 0x91A6; +export def GL_TEXTURE_SRGB_DECODE_EXT: uint = 0x8A48; +export def GL_TEXTURE_STENCIL_SIZE: uint = 0x88F1; +export def GL_TEXTURE_SWIZZLE_A: uint = 0x8E45; +export def GL_TEXTURE_SWIZZLE_B: uint = 0x8E44; +export def GL_TEXTURE_SWIZZLE_G: uint = 0x8E43; +export def GL_TEXTURE_SWIZZLE_R: uint = 0x8E42; +export def GL_TEXTURE_TARGET_QCOM: uint = 0x8BDA; +export def GL_TEXTURE_TILING_EXT: uint = 0x9580; +export def GL_TEXTURE_TYPE_QCOM: uint = 0x8BD7; +export def GL_TEXTURE_UNNORMALIZED_COORDINATES_ARM: uint = 0x8F6A; +export def GL_TEXTURE_UPDATE_BARRIER_BIT: uint = 0x00000100; +export def GL_TEXTURE_USAGE_ANGLE: uint = 0x93A2; +export def GL_TEXTURE_VIEW_MIN_LAYER_EXT: uint = 0x82DD; +export def GL_TEXTURE_VIEW_MIN_LAYER_OES: uint = 0x82DD; +export def GL_TEXTURE_VIEW_MIN_LEVEL_EXT: uint = 0x82DB; +export def GL_TEXTURE_VIEW_MIN_LEVEL_OES: uint = 0x82DB; +export def GL_TEXTURE_VIEW_NUM_LAYERS_EXT: uint = 0x82DE; +export def GL_TEXTURE_VIEW_NUM_LAYERS_OES: uint = 0x82DE; +export def GL_TEXTURE_VIEW_NUM_LEVELS_EXT: uint = 0x82DC; +export def GL_TEXTURE_VIEW_NUM_LEVELS_OES: uint = 0x82DC; +export def GL_TEXTURE_WIDTH: uint = 0x1000; +export def GL_TEXTURE_WIDTH_QCOM: uint = 0x8BD2; +export def GL_TEXTURE_WRAP_R: uint = 0x8072; +export def GL_TEXTURE_WRAP_R_OES: uint = 0x8072; +export def GL_TEXTURE_WRAP_S: uint = 0x2802; +export def GL_TEXTURE_WRAP_T: uint = 0x2803; +export def GL_TILING_TYPES_EXT: uint = 0x9583; +export def GL_TIMELINE_SEMAPHORE_VALUE_NV: uint = 0x9595; +export def GL_TIMEOUT_EXPIRED: uint = 0x911B; +export def GL_TIMEOUT_EXPIRED_APPLE: uint = 0x911B; +export def GL_TIMEOUT_IGNORED: u64 = 0xFFFFFFFFFFFFFFFF; +export def GL_TIMEOUT_IGNORED_APPLE: u64 = 0xFFFFFFFFFFFFFFFF; +export def GL_TIMESTAMP_EXT: uint = 0x8E28; +export def GL_TIME_ELAPSED_EXT: uint = 0x88BF; +export def GL_TOP_LEVEL_ARRAY_SIZE: uint = 0x930C; +export def GL_TOP_LEVEL_ARRAY_STRIDE: uint = 0x930D; +export def GL_TRANSFORM_FEEDBACK: uint = 0x8E22; +export def GL_TRANSFORM_FEEDBACK_ACTIVE: uint = 0x8E24; +export def GL_TRANSFORM_FEEDBACK_BARRIER_BIT: uint = 0x00000800; +export def GL_TRANSFORM_FEEDBACK_BINDING: uint = 0x8E25; +export def GL_TRANSFORM_FEEDBACK_BUFFER: uint = 0x8C8E; +export def GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE: uint = 0x8E24; +export def GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: uint = 0x8C8F; +export def GL_TRANSFORM_FEEDBACK_BUFFER_MODE: uint = 0x8C7F; +export def GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED: uint = 0x8E23; +export def GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: uint = 0x8C85; +export def GL_TRANSFORM_FEEDBACK_BUFFER_START: uint = 0x8C84; +export def GL_TRANSFORM_FEEDBACK_PAUSED: uint = 0x8E23; +export def GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: uint = 0x8C88; +export def GL_TRANSFORM_FEEDBACK_VARYING: uint = 0x92F4; +export def GL_TRANSFORM_FEEDBACK_VARYINGS: uint = 0x8C83; +export def GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: uint = 0x8C76; +export def GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: uint = 0x93A0; +export def GL_TRANSLATE_2D_NV: uint = 0x9090; +export def GL_TRANSLATE_3D_NV: uint = 0x9091; +export def GL_TRANSLATE_X_NV: uint = 0x908E; +export def GL_TRANSLATE_Y_NV: uint = 0x908F; +export def GL_TRANSPOSE_AFFINE_2D_NV: uint = 0x9096; +export def GL_TRANSPOSE_AFFINE_3D_NV: uint = 0x9098; +export def GL_TRIANGLES: uint = 0x0004; +export def GL_TRIANGLES_ADJACENCY: uint = 0x000C; +export def GL_TRIANGLES_ADJACENCY_EXT: uint = 0x000C; +export def GL_TRIANGLES_ADJACENCY_OES: uint = 0x000C; +export def GL_TRIANGLE_FAN: uint = 0x0006; +export def GL_TRIANGLE_STRIP: uint = 0x0005; +export def GL_TRIANGLE_STRIP_ADJACENCY: uint = 0x000D; +export def GL_TRIANGLE_STRIP_ADJACENCY_EXT: uint = 0x000D; +export def GL_TRIANGLE_STRIP_ADJACENCY_OES: uint = 0x000D; +export def GL_TRIANGULAR_NV: uint = 0x90A5; +export def GL_TRUE: u8 = 1; +export def GL_TYPE: uint = 0x92FA; +export def GL_UNCORRELATED_NV: uint = 0x9282; +export def GL_UNDEFINED_VERTEX: uint = 0x8260; +export def GL_UNDEFINED_VERTEX_EXT: uint = 0x8260; +export def GL_UNDEFINED_VERTEX_OES: uint = 0x8260; +export def GL_UNIFORM: uint = 0x92E1; +export def GL_UNIFORM_ARRAY_STRIDE: uint = 0x8A3C; +export def GL_UNIFORM_BARRIER_BIT: uint = 0x00000004; +export def GL_UNIFORM_BLOCK: uint = 0x92E2; +export def GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: uint = 0x8A42; +export def GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: uint = 0x8A43; +export def GL_UNIFORM_BLOCK_BINDING: uint = 0x8A3F; +export def GL_UNIFORM_BLOCK_DATA_SIZE: uint = 0x8A40; +export def GL_UNIFORM_BLOCK_INDEX: uint = 0x8A3A; +export def GL_UNIFORM_BLOCK_NAME_LENGTH: uint = 0x8A41; +export def GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: uint = 0x8A46; +export def GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV: uint = 0x959C; +export def GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV: uint = 0x959D; +export def GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: uint = 0x8A44; +export def GL_UNIFORM_BUFFER: uint = 0x8A11; +export def GL_UNIFORM_BUFFER_BINDING: uint = 0x8A28; +export def GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: uint = 0x8A34; +export def GL_UNIFORM_BUFFER_SIZE: uint = 0x8A2A; +export def GL_UNIFORM_BUFFER_START: uint = 0x8A29; +export def GL_UNIFORM_IS_ROW_MAJOR: uint = 0x8A3E; +export def GL_UNIFORM_MATRIX_STRIDE: uint = 0x8A3D; +export def GL_UNIFORM_NAME_LENGTH: uint = 0x8A39; +export def GL_UNIFORM_OFFSET: uint = 0x8A3B; +export def GL_UNIFORM_SIZE: uint = 0x8A38; +export def GL_UNIFORM_TYPE: uint = 0x8A37; +export def GL_UNKNOWN_CONTEXT_RESET: uint = 0x8255; +export def GL_UNKNOWN_CONTEXT_RESET_EXT: uint = 0x8255; +export def GL_UNKNOWN_CONTEXT_RESET_KHR: uint = 0x8255; +export def GL_UNPACK_ALIGNMENT: uint = 0x0CF5; +export def GL_UNPACK_IMAGE_HEIGHT: uint = 0x806E; +export def GL_UNPACK_ROW_LENGTH: uint = 0x0CF2; +export def GL_UNPACK_ROW_LENGTH_EXT: uint = 0x0CF2; +export def GL_UNPACK_SKIP_IMAGES: uint = 0x806D; +export def GL_UNPACK_SKIP_PIXELS: uint = 0x0CF4; +export def GL_UNPACK_SKIP_PIXELS_EXT: uint = 0x0CF4; +export def GL_UNPACK_SKIP_ROWS: uint = 0x0CF3; +export def GL_UNPACK_SKIP_ROWS_EXT: uint = 0x0CF3; +export def GL_UNSIGNALED: uint = 0x9118; +export def GL_UNSIGNALED_APPLE: uint = 0x9118; +export def GL_UNSIGNED_BYTE: uint = 0x1401; +export def GL_UNSIGNED_INT: uint = 0x1405; +export def GL_UNSIGNED_INT16_NV: uint = 0x8FF0; +export def GL_UNSIGNED_INT16_VEC2_NV: uint = 0x8FF1; +export def GL_UNSIGNED_INT16_VEC3_NV: uint = 0x8FF2; +export def GL_UNSIGNED_INT16_VEC4_NV: uint = 0x8FF3; +export def GL_UNSIGNED_INT64_AMD: uint = 0x8BC2; +export def GL_UNSIGNED_INT64_NV: uint = 0x140F; +export def GL_UNSIGNED_INT64_VEC2_NV: uint = 0x8FF5; +export def GL_UNSIGNED_INT64_VEC3_NV: uint = 0x8FF6; +export def GL_UNSIGNED_INT64_VEC4_NV: uint = 0x8FF7; +export def GL_UNSIGNED_INT8_NV: uint = 0x8FEC; +export def GL_UNSIGNED_INT8_VEC2_NV: uint = 0x8FED; +export def GL_UNSIGNED_INT8_VEC3_NV: uint = 0x8FEE; +export def GL_UNSIGNED_INT8_VEC4_NV: uint = 0x8FEF; +export def GL_UNSIGNED_INT_10F_11F_11F_REV: uint = 0x8C3B; +export def GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE: uint = 0x8C3B; +export def GL_UNSIGNED_INT_10_10_10_2_OES: uint = 0x8DF6; +export def GL_UNSIGNED_INT_24_8: uint = 0x84FA; +export def GL_UNSIGNED_INT_24_8_OES: uint = 0x84FA; +export def GL_UNSIGNED_INT_2_10_10_10_REV: uint = 0x8368; +export def GL_UNSIGNED_INT_2_10_10_10_REV_EXT: uint = 0x8368; +export def GL_UNSIGNED_INT_5_9_9_9_REV: uint = 0x8C3E; +export def GL_UNSIGNED_INT_5_9_9_9_REV_APPLE: uint = 0x8C3E; +export def GL_UNSIGNED_INT_ATOMIC_COUNTER: uint = 0x92DB; +export def GL_UNSIGNED_INT_IMAGE_2D: uint = 0x9063; +export def GL_UNSIGNED_INT_IMAGE_2D_ARRAY: uint = 0x9069; +export def GL_UNSIGNED_INT_IMAGE_3D: uint = 0x9064; +export def GL_UNSIGNED_INT_IMAGE_BUFFER: uint = 0x9067; +export def GL_UNSIGNED_INT_IMAGE_BUFFER_EXT: uint = 0x9067; +export def GL_UNSIGNED_INT_IMAGE_BUFFER_OES: uint = 0x9067; +export def GL_UNSIGNED_INT_IMAGE_CUBE: uint = 0x9066; +export def GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: uint = 0x906A; +export def GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT: uint = 0x906A; +export def GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES: uint = 0x906A; +export def GL_UNSIGNED_INT_SAMPLER_2D: uint = 0x8DD2; +export def GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: uint = 0x8DD7; +export def GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: uint = 0x910A; +export def GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: uint = 0x910D; +export def GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES: uint = 0x910D; +export def GL_UNSIGNED_INT_SAMPLER_3D: uint = 0x8DD3; +export def GL_UNSIGNED_INT_SAMPLER_BUFFER: uint = 0x8DD8; +export def GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT: uint = 0x8DD8; +export def GL_UNSIGNED_INT_SAMPLER_BUFFER_OES: uint = 0x8DD8; +export def GL_UNSIGNED_INT_SAMPLER_CUBE: uint = 0x8DD4; +export def GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: uint = 0x900F; +export def GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT: uint = 0x900F; +export def GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES: uint = 0x900F; +export def GL_UNSIGNED_INT_VEC2: uint = 0x8DC6; +export def GL_UNSIGNED_INT_VEC3: uint = 0x8DC7; +export def GL_UNSIGNED_INT_VEC4: uint = 0x8DC8; +export def GL_UNSIGNED_NORMALIZED: uint = 0x8C17; +export def GL_UNSIGNED_NORMALIZED_EXT: uint = 0x8C17; +export def GL_UNSIGNED_SHORT: uint = 0x1403; +export def GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: uint = 0x8366; +export def GL_UNSIGNED_SHORT_4_4_4_4: uint = 0x8033; +export def GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: uint = 0x8365; +export def GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG: uint = 0x8365; +export def GL_UNSIGNED_SHORT_5_5_5_1: uint = 0x8034; +export def GL_UNSIGNED_SHORT_5_6_5: uint = 0x8363; +export def GL_UNSIGNED_SHORT_8_8_APPLE: uint = 0x85BA; +export def GL_UNSIGNED_SHORT_8_8_REV_APPLE: uint = 0x85BB; +export def GL_UPPER_LEFT: uint = 0x8CA2; +export def GL_UPPER_LEFT_EXT: uint = 0x8CA2; +export def GL_USE_MISSING_GLYPH_NV: uint = 0x90AA; +export def GL_UTF16_NV: uint = 0x909B; +export def GL_UTF8_NV: uint = 0x909A; +export def GL_UUID_SIZE_EXT: uint = 16; +export def GL_VALIDATE_STATUS: uint = 0x8B83; +export def GL_VENDOR: uint = 0x1F00; +export def GL_VERSION: uint = 0x1F02; +export def GL_VERTEX_ARRAY: uint = 0x8074; +export def GL_VERTEX_ARRAY_BINDING: uint = 0x85B5; +export def GL_VERTEX_ARRAY_BINDING_OES: uint = 0x85B5; +export def GL_VERTEX_ARRAY_KHR: uint = 0x8074; +export def GL_VERTEX_ARRAY_OBJECT_EXT: uint = 0x9154; +export def GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT: uint = 0x00000001; +export def GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: uint = 0x889F; +export def GL_VERTEX_ATTRIB_ARRAY_DIVISOR: uint = 0x88FE; +export def GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: uint = 0x88FE; +export def GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT: uint = 0x88FE; +export def GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV: uint = 0x88FE; +export def GL_VERTEX_ATTRIB_ARRAY_ENABLED: uint = 0x8622; +export def GL_VERTEX_ATTRIB_ARRAY_INTEGER: uint = 0x88FD; +export def GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: uint = 0x886A; +export def GL_VERTEX_ATTRIB_ARRAY_POINTER: uint = 0x8645; +export def GL_VERTEX_ATTRIB_ARRAY_SIZE: uint = 0x8623; +export def GL_VERTEX_ATTRIB_ARRAY_STRIDE: uint = 0x8624; +export def GL_VERTEX_ATTRIB_ARRAY_TYPE: uint = 0x8625; +export def GL_VERTEX_ATTRIB_BINDING: uint = 0x82D4; +export def GL_VERTEX_ATTRIB_RELATIVE_OFFSET: uint = 0x82D5; +export def GL_VERTEX_BINDING_BUFFER: uint = 0x8F4F; +export def GL_VERTEX_BINDING_DIVISOR: uint = 0x82D6; +export def GL_VERTEX_BINDING_OFFSET: uint = 0x82D7; +export def GL_VERTEX_BINDING_STRIDE: uint = 0x82D8; +export def GL_VERTEX_SHADER: uint = 0x8B31; +export def GL_VERTEX_SHADER_BIT: uint = 0x00000001; +export def GL_VERTEX_SHADER_BIT_EXT: uint = 0x00000001; +export def GL_VERTICAL_LINE_TO_NV: uint = 0x08; +export def GL_VIEWPORT: uint = 0x0BA2; +export def GL_VIEWPORT_BOUNDS_RANGE_NV: uint = 0x825D; +export def GL_VIEWPORT_BOUNDS_RANGE_OES: uint = 0x825D; +export def GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV: uint = 0x825F; +export def GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES: uint = 0x825F; +export def GL_VIEWPORT_POSITION_W_SCALE_NV: uint = 0x937C; +export def GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV: uint = 0x937D; +export def GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV: uint = 0x937E; +export def GL_VIEWPORT_SUBPIXEL_BITS_NV: uint = 0x825C; +export def GL_VIEWPORT_SUBPIXEL_BITS_OES: uint = 0x825C; +export def GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV: uint = 0x9357; +export def GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV: uint = 0x9351; +export def GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV: uint = 0x9353; +export def GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV: uint = 0x9355; +export def GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV: uint = 0x9356; +export def GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV: uint = 0x9350; +export def GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV: uint = 0x9352; +export def GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV: uint = 0x9354; +export def GL_VIEWPORT_SWIZZLE_W_NV: uint = 0x935B; +export def GL_VIEWPORT_SWIZZLE_X_NV: uint = 0x9358; +export def GL_VIEWPORT_SWIZZLE_Y_NV: uint = 0x9359; +export def GL_VIEWPORT_SWIZZLE_Z_NV: uint = 0x935A; +export def GL_VIRTUAL_PAGE_SIZE_INDEX_EXT: uint = 0x91A7; +export def GL_VIRTUAL_PAGE_SIZE_X_EXT: uint = 0x9195; +export def GL_VIRTUAL_PAGE_SIZE_Y_EXT: uint = 0x9196; +export def GL_VIRTUAL_PAGE_SIZE_Z_EXT: uint = 0x9197; +export def GL_VIVIDLIGHT_NV: uint = 0x92A6; +export def GL_WAIT_FAILED: uint = 0x911D; +export def GL_WAIT_FAILED_APPLE: uint = 0x911D; +export def GL_WEIGHTED_AVERAGE_ARB: uint = 0x9367; +export def GL_WEIGHTED_AVERAGE_EXT: uint = 0x9367; +export def GL_WINDOW_RECTANGLE_EXT: uint = 0x8F12; +export def GL_WINDOW_RECTANGLE_MODE_EXT: uint = 0x8F13; +export def GL_WRITEONLY_RENDERING_QCOM: uint = 0x8823; +export def GL_WRITE_ONLY: uint = 0x88B9; +export def GL_WRITE_ONLY_OES: uint = 0x88B9; +export def GL_XOR_NV: uint = 0x1506; +export def GL_Z400_BINARY_AMD: uint = 0x8740; +export def GL_ZERO: uint = 0; +export def GL_ZERO_TO_ONE: uint = 0x935F; +export def GL_ZERO_TO_ONE_EXT: uint = 0x935F; + +// Function pointers +export type fp_glAcquireKeyedMutexWin32EXT = fn(memory: uint, key: u64, timeout: uint) u8; +export type fp_glActiveShaderProgram = fn(pipeline: uint, program: uint) void; +export type fp_glActiveShaderProgramEXT = fn(pipeline: uint, program: uint) void; +export type fp_glActiveTexture = fn(texture: gl_enum) void; +export type fp_glAlphaFuncQCOM = fn(func: gl_enum, ref: f64) void; +export type fp_glApplyFramebufferAttachmentCMAAINTEL = fn() void; +export type fp_glAttachShader = fn(program: uint, shader: uint) void; +export type fp_glBeginConditionalRenderNV = fn(id: uint, mode: gl_enum) void; +export type fp_glBeginPerfMonitorAMD = fn(monitor: uint) void; +export type fp_glBeginPerfQueryINTEL = fn(queryHandle: uint) void; +export type fp_glBeginQuery = fn(target: gl_enum, id: uint) void; +export type fp_glBeginQueryEXT = fn(target: gl_enum, id: uint) void; +export type fp_glBeginTransformFeedback = fn(primitiveMode: gl_enum) void; +export type fp_glBindAttribLocation = fn(program: uint, index: uint, name: nullable *const i8) void; +export type fp_glBindBuffer = fn(target: gl_enum, buffer: uint) void; +export type fp_glBindBufferBase = fn(target: gl_enum, index: uint, buffer: uint) void; +export type fp_glBindBufferRange = fn(target: gl_enum, index: uint, buffer: uint, offset_: size, size_: uintptr) void; +export type fp_glBindFragDataLocationEXT = fn(program: uint, color: uint, name: nullable *const i8) void; +export type fp_glBindFragDataLocationIndexedEXT = fn(program: uint, colorNumber: uint, index: uint, name: nullable *const i8) void; +export type fp_glBindFramebuffer = fn(target: gl_enum, framebuffer: uint) void; +export type fp_glBindImageTexture = fn(unit: uint, texture: uint, level: i32, layered: u8, layer: i32, access: gl_enum, format: gl_enum) void; +export type fp_glBindProgramPipeline = fn(pipeline: uint) void; +export type fp_glBindProgramPipelineEXT = fn(pipeline: uint) void; +export type fp_glBindRenderbuffer = fn(target: gl_enum, renderbuffer: uint) void; +export type fp_glBindSampler = fn(unit: uint, sampler: uint) void; +export type fp_glBindShadingRateImageNV = fn(texture: uint) void; +export type fp_glBindTexture = fn(target: gl_enum, texture: uint) void; +export type fp_glBindTransformFeedback = fn(target: gl_enum, id: uint) void; +export type fp_glBindVertexArray = fn(array: uint) void; +export type fp_glBindVertexArrayOES = fn(array: uint) void; +export type fp_glBindVertexBuffer = fn(bindingindex: uint, buffer: uint, offset_: size, stride: i32) void; +export type fp_glBlendBarrier = fn() void; +export type fp_glBlendBarrierKHR = fn() void; +export type fp_glBlendBarrierNV = fn() void; +export type fp_glBlendColor = fn(red: f32, green: f32, blue: f32, alpha: f32) void; +export type fp_glBlendEquation = fn(mode: gl_enum) void; +export type fp_glBlendEquationSeparate = fn(modeRGB: gl_enum, modeAlpha: gl_enum) void; +export type fp_glBlendEquationSeparatei = fn(buf: uint, modeRGB: gl_enum, modeAlpha: gl_enum) void; +export type fp_glBlendEquationSeparateiEXT = fn(buf: uint, modeRGB: gl_enum, modeAlpha: gl_enum) void; +export type fp_glBlendEquationSeparateiOES = fn(buf: uint, modeRGB: gl_enum, modeAlpha: gl_enum) void; +export type fp_glBlendEquationi = fn(buf: uint, mode: gl_enum) void; +export type fp_glBlendEquationiEXT = fn(buf: uint, mode: gl_enum) void; +export type fp_glBlendEquationiOES = fn(buf: uint, mode: gl_enum) void; +export type fp_glBlendFunc = fn(sfactor: gl_enum, dfactor: gl_enum) void; +export type fp_glBlendFuncSeparate = fn(sfactorRGB: gl_enum, dfactorRGB: gl_enum, sfactorAlpha: gl_enum, dfactorAlpha: gl_enum) void; +export type fp_glBlendFuncSeparatei = fn(buf: uint, srcRGB: gl_enum, dstRGB: gl_enum, srcAlpha: gl_enum, dstAlpha: gl_enum) void; +export type fp_glBlendFuncSeparateiEXT = fn(buf: uint, srcRGB: gl_enum, dstRGB: gl_enum, srcAlpha: gl_enum, dstAlpha: gl_enum) void; +export type fp_glBlendFuncSeparateiOES = fn(buf: uint, srcRGB: gl_enum, dstRGB: gl_enum, srcAlpha: gl_enum, dstAlpha: gl_enum) void; +export type fp_glBlendFunci = fn(buf: uint, src: gl_enum, dst: gl_enum) void; +export type fp_glBlendFunciEXT = fn(buf: uint, src: gl_enum, dst: gl_enum) void; +export type fp_glBlendFunciOES = fn(buf: uint, src: gl_enum, dst: gl_enum) void; +export type fp_glBlendParameteriNV = fn(pname: gl_enum, value: i32) void; +export type fp_glBlitFramebuffer = fn(srcX0: i32, srcY0: i32, srcX1: i32, srcY1: i32, dstX0: i32, dstY0: i32, dstX1: i32, dstY1: i32, mask: gl_bitfield, filter: gl_enum) void; +export type fp_glBlitFramebufferANGLE = fn(srcX0: i32, srcY0: i32, srcX1: i32, srcY1: i32, dstX0: i32, dstY0: i32, dstX1: i32, dstY1: i32, mask: gl_bitfield, filter: gl_enum) void; +export type fp_glBlitFramebufferNV = fn(srcX0: i32, srcY0: i32, srcX1: i32, srcY1: i32, dstX0: i32, dstY0: i32, dstX1: i32, dstY1: i32, mask: gl_bitfield, filter: gl_enum) void; +export type fp_glBufferAttachMemoryNV = fn(target: gl_enum, memory: uint, offset_: u64) void; +export type fp_glBufferData = fn(target: gl_enum, size_: uintptr, data: nullable *const opaque, usage: gl_enum) void; +export type fp_glBufferPageCommitmentMemNV = fn(target: gl_enum, offset_: size, size_: uintptr, memory: uint, memOffset: u64, commit: u8) void; +export type fp_glBufferStorageEXT = fn(target: gl_enum, size_: uintptr, data: nullable *const opaque, flags: gl_bitfield) void; +export type fp_glBufferStorageExternalEXT = fn(target: gl_enum, offset_: size, size_: uintptr, clientBuffer: *opaque, flags: gl_bitfield) void; +export type fp_glBufferStorageMemEXT = fn(target: gl_enum, size_: uintptr, memory: uint, offset_: u64) void; +export type fp_glBufferSubData = fn(target: gl_enum, offset_: size, size_: uintptr, data: nullable *const opaque) void; +export type fp_glCheckFramebufferStatus = fn(target: gl_enum) gl_enum; +export type fp_glClear = fn(mask: gl_bitfield) void; +export type fp_glClearBufferfi = fn(buffer: gl_enum, drawbuffer: i32, depth: f32, stencil: i32) void; +export type fp_glClearBufferfv = fn(buffer: gl_enum, drawbuffer: i32, value: nullable *const f32) void; +export type fp_glClearBufferiv = fn(buffer: gl_enum, drawbuffer: i32, value: nullable *const i32) void; +export type fp_glClearBufferuiv = fn(buffer: gl_enum, drawbuffer: i32, value: nullable *const uint) void; +export type fp_glClearColor = fn(red: f32, green: f32, blue: f32, alpha: f32) void; +export type fp_glClearDepthf = fn(d: f32) void; +export type fp_glClearPixelLocalStorageuiEXT = fn(offset_: i32, n: i32, values: nullable *const uint) void; +export type fp_glClearStencil = fn(s: i32) void; +export type fp_glClearTexImageEXT = fn(texture: uint, level: i32, format: gl_enum, type_: gl_enum, data: nullable *const opaque) void; +export type fp_glClearTexSubImageEXT = fn(texture: uint, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: gl_enum, type_: gl_enum, data: nullable *const opaque) void; +export type fp_glClientWaitSync = fn(sync: size, flags: gl_bitfield, timeout: u64) gl_enum; +export type fp_glClientWaitSyncAPPLE = fn(sync: size, flags: gl_bitfield, timeout: u64) gl_enum; +export type fp_glClipControlEXT = fn(origin: gl_enum, depth: gl_enum) void; +export type fp_glColorMask = fn(red: u8, green: u8, blue: u8, alpha: u8) void; +export type fp_glColorMaski = fn(index: uint, r: u8, g: u8, b: u8, a: u8) void; +export type fp_glColorMaskiEXT = fn(index: uint, r: u8, g: u8, b: u8, a: u8) void; +export type fp_glColorMaskiOES = fn(index: uint, r: u8, g: u8, b: u8, a: u8) void; +export type fp_glCompileShader = fn(shader: uint) void; +export type fp_glCompressedTexImage2D = fn(target: gl_enum, level: i32, internalformat: gl_enum, width: i32, height: i32, border: i32, imageSize: i32, data: nullable *const opaque) void; +export type fp_glCompressedTexImage3D = fn(target: gl_enum, level: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32, border: i32, imageSize: i32, data: nullable *const opaque) void; +export type fp_glCompressedTexImage3DOES = fn(target: gl_enum, level: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32, border: i32, imageSize: i32, data: nullable *const opaque) void; +export type fp_glCompressedTexSubImage2D = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, width: i32, height: i32, format: gl_enum, imageSize: i32, data: nullable *const opaque) void; +export type fp_glCompressedTexSubImage3D = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: gl_enum, imageSize: i32, data: nullable *const opaque) void; +export type fp_glCompressedTexSubImage3DOES = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: gl_enum, imageSize: i32, data: nullable *const opaque) void; +export type fp_glConservativeRasterParameteriNV = fn(pname: gl_enum, param: i32) void; +export type fp_glCopyBufferSubData = fn(readTarget: gl_enum, writeTarget: gl_enum, readOffset: size, writeOffset: size, size_: uintptr) void; +export type fp_glCopyBufferSubDataNV = fn(readTarget: gl_enum, writeTarget: gl_enum, readOffset: size, writeOffset: size, size_: uintptr) void; +export type fp_glCopyImageSubData = fn(srcName: uint, srcTarget: gl_enum, srcLevel: i32, srcX: i32, srcY: i32, srcZ: i32, dstName: uint, dstTarget: gl_enum, dstLevel: i32, dstX: i32, dstY: i32, dstZ: i32, srcWidth: i32, srcHeight: i32, srcDepth: i32) void; +export type fp_glCopyImageSubDataEXT = fn(srcName: uint, srcTarget: gl_enum, srcLevel: i32, srcX: i32, srcY: i32, srcZ: i32, dstName: uint, dstTarget: gl_enum, dstLevel: i32, dstX: i32, dstY: i32, dstZ: i32, srcWidth: i32, srcHeight: i32, srcDepth: i32) void; +export type fp_glCopyImageSubDataOES = fn(srcName: uint, srcTarget: gl_enum, srcLevel: i32, srcX: i32, srcY: i32, srcZ: i32, dstName: uint, dstTarget: gl_enum, dstLevel: i32, dstX: i32, dstY: i32, dstZ: i32, srcWidth: i32, srcHeight: i32, srcDepth: i32) void; +export type fp_glCopyPathNV = fn(resultPath: uint, srcPath: uint) void; +export type fp_glCopyTexImage2D = fn(target: gl_enum, level: i32, internalformat: gl_enum, x: i32, y: i32, width: i32, height: i32, border: i32) void; +export type fp_glCopyTexSubImage2D = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, x: i32, y: i32, width: i32, height: i32) void; +export type fp_glCopyTexSubImage3D = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, x: i32, y: i32, width: i32, height: i32) void; +export type fp_glCopyTexSubImage3DOES = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, x: i32, y: i32, width: i32, height: i32) void; +export type fp_glCopyTextureLevelsAPPLE = fn(destinationTexture: uint, sourceTexture: uint, sourceBaseLevel: i32, sourceLevelCount: i32) void; +export type fp_glCoverFillPathInstancedNV = fn(numPaths: i32, pathNameType: gl_enum, paths: nullable *const opaque, pathBase: uint, coverMode: gl_enum, transformType: gl_enum, transformValues: nullable *const f32) void; +export type fp_glCoverFillPathNV = fn(path: uint, coverMode: gl_enum) void; +export type fp_glCoverStrokePathInstancedNV = fn(numPaths: i32, pathNameType: gl_enum, paths: nullable *const opaque, pathBase: uint, coverMode: gl_enum, transformType: gl_enum, transformValues: nullable *const f32) void; +export type fp_glCoverStrokePathNV = fn(path: uint, coverMode: gl_enum) void; +export type fp_glCoverageMaskNV = fn(mask: u8) void; +export type fp_glCoverageModulationNV = fn(components: gl_enum) void; +export type fp_glCoverageModulationTableNV = fn(n: i32, v: nullable *const f32) void; +export type fp_glCoverageOperationNV = fn(operation: gl_enum) void; +export type fp_glCreateMemoryObjectsEXT = fn(n: i32, memoryObjects: nullable *uint) void; +export type fp_glCreatePerfQueryINTEL = fn(queryId: uint, queryHandle: nullable *uint) void; +export type fp_glCreateProgram = fn() uint; +export type fp_glCreateSemaphoresNV = fn(n: i32, semaphores: nullable *uint) void; +export type fp_glCreateShader = fn(type_: gl_enum) uint; +export type fp_glCreateShaderProgramv = fn(type_: gl_enum, count: i32, strings: nullable *const nullable *const i8) uint; +export type fp_glCreateShaderProgramvEXT = fn(type_: gl_enum, count: i32, strings: nullable *const nullable *const i8) uint; +export type fp_glCullFace = fn(mode: gl_enum) void; +export type fp_glDebugMessageCallback = fn(callback: GLDEBUGPROC, userParam: nullable *const opaque) void; +export type fp_glDebugMessageCallbackKHR = fn(callback: GLDEBUGPROCKHR, userParam: nullable *const opaque) void; +export type fp_glDebugMessageControl = fn(source: gl_enum, type_: gl_enum, severity: gl_enum, count: i32, ids: nullable *const uint, enabled: u8) void; +export type fp_glDebugMessageControlKHR = fn(source: gl_enum, type_: gl_enum, severity: gl_enum, count: i32, ids: nullable *const uint, enabled: u8) void; +export type fp_glDebugMessageInsert = fn(source: gl_enum, type_: gl_enum, id: uint, severity: gl_enum, length: i32, buf: nullable *const i8) void; +export type fp_glDebugMessageInsertKHR = fn(source: gl_enum, type_: gl_enum, id: uint, severity: gl_enum, length: i32, buf: nullable *const i8) void; +export type fp_glDeleteBuffers = fn(n: i32, buffers: nullable *const uint) void; +export type fp_glDeleteFencesNV = fn(n: i32, fences: nullable *const uint) void; +export type fp_glDeleteFramebuffers = fn(n: i32, framebuffers: nullable *const uint) void; +export type fp_glDeleteMemoryObjectsEXT = fn(n: i32, memoryObjects: nullable *const uint) void; +export type fp_glDeletePathsNV = fn(path: uint, range: i32) void; +export type fp_glDeletePerfMonitorsAMD = fn(n: i32, monitors: nullable *uint) void; +export type fp_glDeletePerfQueryINTEL = fn(queryHandle: uint) void; +export type fp_glDeleteProgram = fn(program: uint) void; +export type fp_glDeleteProgramPipelines = fn(n: i32, pipelines: nullable *const uint) void; +export type fp_glDeleteProgramPipelinesEXT = fn(n: i32, pipelines: nullable *const uint) void; +export type fp_glDeleteQueries = fn(n: i32, ids: nullable *const uint) void; +export type fp_glDeleteQueriesEXT = fn(n: i32, ids: nullable *const uint) void; +export type fp_glDeleteRenderbuffers = fn(n: i32, renderbuffers: nullable *const uint) void; +export type fp_glDeleteSamplers = fn(count: i32, samplers: nullable *const uint) void; +export type fp_glDeleteSemaphoresEXT = fn(n: i32, semaphores: nullable *const uint) void; +export type fp_glDeleteShader = fn(shader: uint) void; +export type fp_glDeleteSync = fn(sync: size) void; +export type fp_glDeleteSyncAPPLE = fn(sync: size) void; +export type fp_glDeleteTextures = fn(n: i32, textures: nullable *const uint) void; +export type fp_glDeleteTransformFeedbacks = fn(n: i32, ids: nullable *const uint) void; +export type fp_glDeleteVertexArrays = fn(n: i32, arrays: nullable *const uint) void; +export type fp_glDeleteVertexArraysOES = fn(n: i32, arrays: nullable *const uint) void; +export type fp_glDepthFunc = fn(func: gl_enum) void; +export type fp_glDepthMask = fn(flag: u8) void; +export type fp_glDepthRangeArrayfvNV = fn(first: uint, count: i32, v: nullable *const f32) void; +export type fp_glDepthRangeArrayfvOES = fn(first: uint, count: i32, v: nullable *const f32) void; +export type fp_glDepthRangeIndexedfNV = fn(index: uint, n: f32, f: f32) void; +export type fp_glDepthRangeIndexedfOES = fn(index: uint, n: f32, f: f32) void; +export type fp_glDepthRangef = fn(n: f32, f: f32) void; +export type fp_glDetachShader = fn(program: uint, shader: uint) void; +export type fp_glDisable = fn(cap: gl_enum) void; +export type fp_glDisableDriverControlQCOM = fn(driverControl: uint) void; +export type fp_glDisableVertexAttribArray = fn(index: uint) void; +export type fp_glDisablei = fn(target: gl_enum, index: uint) void; +export type fp_glDisableiEXT = fn(target: gl_enum, index: uint) void; +export type fp_glDisableiNV = fn(target: gl_enum, index: uint) void; +export type fp_glDisableiOES = fn(target: gl_enum, index: uint) void; +export type fp_glDiscardFramebufferEXT = fn(target: gl_enum, numAttachments: i32, attachments: nullable *const gl_enum) void; +export type fp_glDispatchCompute = fn(num_groups_x: uint, num_groups_y: uint, num_groups_z: uint) void; +export type fp_glDispatchComputeIndirect = fn(indirect: size) void; +export type fp_glDrawArrays = fn(mode: gl_enum, first: i32, count: i32) void; +export type fp_glDrawArraysIndirect = fn(mode: gl_enum, indirect: nullable *const opaque) void; +export type fp_glDrawArraysInstanced = fn(mode: gl_enum, first: i32, count: i32, instancecount: i32) void; +export type fp_glDrawArraysInstancedANGLE = fn(mode: gl_enum, first: i32, count: i32, primcount: i32) void; +export type fp_glDrawArraysInstancedBaseInstanceEXT = fn(mode: gl_enum, first: i32, count: i32, instancecount: i32, baseinstance: uint) void; +export type fp_glDrawArraysInstancedEXT = fn(mode: gl_enum, start: i32, count: i32, primcount: i32) void; +export type fp_glDrawArraysInstancedNV = fn(mode: gl_enum, first: i32, count: i32, primcount: i32) void; +export type fp_glDrawBuffers = fn(n: i32, bufs: nullable *const gl_enum) void; +export type fp_glDrawBuffersEXT = fn(n: i32, bufs: nullable *const gl_enum) void; +export type fp_glDrawBuffersIndexedEXT = fn(n: i32, location: nullable *const gl_enum, indices: nullable *const i32) void; +export type fp_glDrawBuffersNV = fn(n: i32, bufs: nullable *const gl_enum) void; +export type fp_glDrawElements = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque) void; +export type fp_glDrawElementsBaseVertex = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, basevertex: i32) void; +export type fp_glDrawElementsBaseVertexEXT = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, basevertex: i32) void; +export type fp_glDrawElementsBaseVertexOES = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, basevertex: i32) void; +export type fp_glDrawElementsIndirect = fn(mode: gl_enum, type_: gl_enum, indirect: nullable *const opaque) void; +export type fp_glDrawElementsInstanced = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, instancecount: i32) void; +export type fp_glDrawElementsInstancedANGLE = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, primcount: i32) void; +export type fp_glDrawElementsInstancedBaseInstanceEXT = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, instancecount: i32, baseinstance: uint) void; +export type fp_glDrawElementsInstancedBaseVertex = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, instancecount: i32, basevertex: i32) void; +export type fp_glDrawElementsInstancedBaseVertexBaseInstanceEXT = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, instancecount: i32, basevertex: i32, baseinstance: uint) void; +export type fp_glDrawElementsInstancedBaseVertexEXT = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, instancecount: i32, basevertex: i32) void; +export type fp_glDrawElementsInstancedBaseVertexOES = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, instancecount: i32, basevertex: i32) void; +export type fp_glDrawElementsInstancedEXT = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, primcount: i32) void; +export type fp_glDrawElementsInstancedNV = fn(mode: gl_enum, count: i32, type_: gl_enum, indices: nullable *const opaque, primcount: i32) void; +export type fp_glDrawMeshTasksIndirectNV = fn(indirect: size) void; +export type fp_glDrawMeshTasksNV = fn(first: uint, count: uint) void; +export type fp_glDrawRangeElements = fn(mode: gl_enum, start: uint, end: uint, count: i32, type_: gl_enum, indices: nullable *const opaque) void; +export type fp_glDrawRangeElementsBaseVertex = fn(mode: gl_enum, start: uint, end: uint, count: i32, type_: gl_enum, indices: nullable *const opaque, basevertex: i32) void; +export type fp_glDrawRangeElementsBaseVertexEXT = fn(mode: gl_enum, start: uint, end: uint, count: i32, type_: gl_enum, indices: nullable *const opaque, basevertex: i32) void; +export type fp_glDrawRangeElementsBaseVertexOES = fn(mode: gl_enum, start: uint, end: uint, count: i32, type_: gl_enum, indices: nullable *const opaque, basevertex: i32) void; +export type fp_glDrawTransformFeedbackEXT = fn(mode: gl_enum, id: uint) void; +export type fp_glDrawTransformFeedbackInstancedEXT = fn(mode: gl_enum, id: uint, instancecount: i32) void; +export type fp_glDrawVkImageNV = fn(vkImage: u64, sampler: uint, x0: f32, y0: f32, x1: f32, y1: f32, z: f32, s0: f32, t0: f32, s1: f32, t1: f32) void; +export type fp_glEGLImageTargetRenderbufferStorageOES = fn(target: gl_enum, image: *const opaque) void; +export type fp_glEGLImageTargetTexStorageEXT = fn(target: gl_enum, image: *const opaque, attrib_list: nullable *const i32) void; +export type fp_glEGLImageTargetTexture2DOES = fn(target: gl_enum, image: *const opaque) void; +export type fp_glEGLImageTargetTextureStorageEXT = fn(texture: uint, image: *const opaque, attrib_list: nullable *const i32) void; +export type fp_glEnable = fn(cap: gl_enum) void; +export type fp_glEnableDriverControlQCOM = fn(driverControl: uint) void; +export type fp_glEnableVertexAttribArray = fn(index: uint) void; +export type fp_glEnablei = fn(target: gl_enum, index: uint) void; +export type fp_glEnableiEXT = fn(target: gl_enum, index: uint) void; +export type fp_glEnableiNV = fn(target: gl_enum, index: uint) void; +export type fp_glEnableiOES = fn(target: gl_enum, index: uint) void; +export type fp_glEndConditionalRenderNV = fn() void; +export type fp_glEndPerfMonitorAMD = fn(monitor: uint) void; +export type fp_glEndPerfQueryINTEL = fn(queryHandle: uint) void; +export type fp_glEndQuery = fn(target: gl_enum) void; +export type fp_glEndQueryEXT = fn(target: gl_enum) void; +export type fp_glEndTilingQCOM = fn(preserveMask: gl_bitfield) void; +export type fp_glEndTransformFeedback = fn() void; +export type fp_glExtGetBufferPointervQCOM = fn(target: gl_enum, params: nullable *nullable *opaque) void; +export type fp_glExtGetBuffersQCOM = fn(buffers: nullable *uint, maxBuffers: i32, numBuffers: nullable *i32) void; +export type fp_glExtGetFramebuffersQCOM = fn(framebuffers: nullable *uint, maxFramebuffers: i32, numFramebuffers: nullable *i32) void; +export type fp_glExtGetProgramBinarySourceQCOM = fn(program: uint, shadertype: gl_enum, source: nullable *i8, length: nullable *i32) void; +export type fp_glExtGetProgramsQCOM = fn(programs: nullable *uint, maxPrograms: i32, numPrograms: nullable *i32) void; +export type fp_glExtGetRenderbuffersQCOM = fn(renderbuffers: nullable *uint, maxRenderbuffers: i32, numRenderbuffers: nullable *i32) void; +export type fp_glExtGetShadersQCOM = fn(shaders: nullable *uint, maxShaders: i32, numShaders: nullable *i32) void; +export type fp_glExtGetTexLevelParameterivQCOM = fn(texture: uint, face: gl_enum, level: i32, pname: gl_enum, params: nullable *i32) void; +export type fp_glExtGetTexSubImageQCOM = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: gl_enum, type_: gl_enum, texels: nullable *opaque) void; +export type fp_glExtGetTexturesQCOM = fn(textures: nullable *uint, maxTextures: i32, numTextures: nullable *i32) void; +export type fp_glExtIsProgramBinaryQCOM = fn(program: uint) u8; +export type fp_glExtTexObjectStateOverrideiQCOM = fn(target: gl_enum, pname: gl_enum, param: i32) void; +export type fp_glExtrapolateTex2DQCOM = fn(src1: uint, src2: uint, output: uint, scaleFactor: f32) void; +export type fp_glFenceSync = fn(condition: gl_enum, flags: gl_bitfield) size; +export type fp_glFenceSyncAPPLE = fn(condition: gl_enum, flags: gl_bitfield) size; +export type fp_glFinish = fn() void; +export type fp_glFinishFenceNV = fn(fence: uint) void; +export type fp_glFlush = fn() void; +export type fp_glFlushMappedBufferRange = fn(target: gl_enum, offset_: size, length: uintptr) void; +export type fp_glFlushMappedBufferRangeEXT = fn(target: gl_enum, offset_: size, length: uintptr) void; +export type fp_glFragmentCoverageColorNV = fn(color: uint) void; +export type fp_glFramebufferFetchBarrierEXT = fn() void; +export type fp_glFramebufferFetchBarrierQCOM = fn() void; +export type fp_glFramebufferFoveationConfigQCOM = fn(framebuffer: uint, numLayers: uint, focalPointsPerLayer: uint, requestedFeatures: uint, providedFeatures: nullable *uint) void; +export type fp_glFramebufferFoveationParametersQCOM = fn(framebuffer: uint, layer: uint, focalPoint: uint, focalX: f32, focalY: f32, gainX: f32, gainY: f32, foveaArea: f32) void; +export type fp_glFramebufferParameteri = fn(target: gl_enum, pname: gl_enum, param: i32) void; +export type fp_glFramebufferParameteriMESA = fn(target: gl_enum, pname: gl_enum, param: i32) void; +export type fp_glFramebufferPixelLocalStorageSizeEXT = fn(target: uint, size_: i32) void; +export type fp_glFramebufferRenderbuffer = fn(target: gl_enum, attachment: gl_enum, renderbuffertarget: gl_enum, renderbuffer: uint) void; +export type fp_glFramebufferSampleLocationsfvNV = fn(target: gl_enum, start: uint, count: i32, v: nullable *const f32) void; +export type fp_glFramebufferShadingRateEXT = fn(target: gl_enum, attachment: gl_enum, texture: uint, baseLayer: i32, numLayers: i32, texelWidth: i32, texelHeight: i32) void; +export type fp_glFramebufferTexture = fn(target: gl_enum, attachment: gl_enum, texture: uint, level: i32) void; +export type fp_glFramebufferTexture2D = fn(target: gl_enum, attachment: gl_enum, textarget: gl_enum, texture: uint, level: i32) void; +export type fp_glFramebufferTexture2DDownsampleIMG = fn(target: gl_enum, attachment: gl_enum, textarget: gl_enum, texture: uint, level: i32, xscale: i32, yscale: i32) void; +export type fp_glFramebufferTexture2DMultisampleEXT = fn(target: gl_enum, attachment: gl_enum, textarget: gl_enum, texture: uint, level: i32, samples: i32) void; +export type fp_glFramebufferTexture2DMultisampleIMG = fn(target: gl_enum, attachment: gl_enum, textarget: gl_enum, texture: uint, level: i32, samples: i32) void; +export type fp_glFramebufferTexture3DOES = fn(target: gl_enum, attachment: gl_enum, textarget: gl_enum, texture: uint, level: i32, zoffset: i32) void; +export type fp_glFramebufferTextureEXT = fn(target: gl_enum, attachment: gl_enum, texture: uint, level: i32) void; +export type fp_glFramebufferTextureLayer = fn(target: gl_enum, attachment: gl_enum, texture: uint, level: i32, layer: i32) void; +export type fp_glFramebufferTextureLayerDownsampleIMG = fn(target: gl_enum, attachment: gl_enum, texture: uint, level: i32, layer: i32, xscale: i32, yscale: i32) void; +export type fp_glFramebufferTextureMultisampleMultiviewOVR = fn(target: gl_enum, attachment: gl_enum, texture: uint, level: i32, samples: i32, baseViewIndex: i32, numViews: i32) void; +export type fp_glFramebufferTextureMultiviewOVR = fn(target: gl_enum, attachment: gl_enum, texture: uint, level: i32, baseViewIndex: i32, numViews: i32) void; +export type fp_glFramebufferTextureOES = fn(target: gl_enum, attachment: gl_enum, texture: uint, level: i32) void; +export type fp_glFrontFace = fn(mode: gl_enum) void; +export type fp_glGenBuffers = fn(n: i32, buffers: nullable *uint) void; +export type fp_glGenFencesNV = fn(n: i32, fences: nullable *uint) void; +export type fp_glGenFramebuffers = fn(n: i32, framebuffers: nullable *uint) void; +export type fp_glGenPathsNV = fn(range: i32) uint; +export type fp_glGenPerfMonitorsAMD = fn(n: i32, monitors: nullable *uint) void; +export type fp_glGenProgramPipelines = fn(n: i32, pipelines: nullable *uint) void; +export type fp_glGenProgramPipelinesEXT = fn(n: i32, pipelines: nullable *uint) void; +export type fp_glGenQueries = fn(n: i32, ids: nullable *uint) void; +export type fp_glGenQueriesEXT = fn(n: i32, ids: nullable *uint) void; +export type fp_glGenRenderbuffers = fn(n: i32, renderbuffers: nullable *uint) void; +export type fp_glGenSamplers = fn(count: i32, samplers: nullable *uint) void; +export type fp_glGenSemaphoresEXT = fn(n: i32, semaphores: nullable *uint) void; +export type fp_glGenTextures = fn(n: i32, textures: nullable *uint) void; +export type fp_glGenTransformFeedbacks = fn(n: i32, ids: nullable *uint) void; +export type fp_glGenVertexArrays = fn(n: i32, arrays: nullable *uint) void; +export type fp_glGenVertexArraysOES = fn(n: i32, arrays: nullable *uint) void; +export type fp_glGenerateMipmap = fn(target: gl_enum) void; +export type fp_glGetActiveAttrib = fn(program: uint, index: uint, bufSize: i32, length: nullable *i32, size_: nullable *i32, type_: nullable *gl_enum, name: nullable *i8) void; +export type fp_glGetActiveUniform = fn(program: uint, index: uint, bufSize: i32, length: nullable *i32, size_: nullable *i32, type_: nullable *gl_enum, name: nullable *i8) void; +export type fp_glGetActiveUniformBlockName = fn(program: uint, uniformBlockIndex: uint, bufSize: i32, length: nullable *i32, uniformBlockName: nullable *i8) void; +export type fp_glGetActiveUniformBlockiv = fn(program: uint, uniformBlockIndex: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetActiveUniformsiv = fn(program: uint, uniformCount: i32, uniformIndices: nullable *const uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetAttachedShaders = fn(program: uint, maxCount: i32, count: nullable *i32, shaders: nullable *uint) void; +export type fp_glGetAttribLocation = fn(program: uint, name: nullable *const i8) i32; +export type fp_glGetBooleani_v = fn(target: gl_enum, index: uint, data: nullable *u8) void; +export type fp_glGetBooleanv = fn(pname: gl_enum, data: nullable *u8) void; +export type fp_glGetBufferParameteri64v = fn(target: gl_enum, pname: gl_enum, params: nullable *i64) void; +export type fp_glGetBufferParameteriv = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetBufferPointerv = fn(target: gl_enum, pname: gl_enum, params: nullable *nullable *opaque) void; +export type fp_glGetBufferPointervOES = fn(target: gl_enum, pname: gl_enum, params: nullable *nullable *opaque) void; +export type fp_glGetCoverageModulationTableNV = fn(bufSize: i32, v: nullable *f32) void; +export type fp_glGetDebugMessageLog = fn(count: uint, bufSize: i32, sources: nullable *gl_enum, types: nullable *gl_enum, ids: nullable *uint, severities: nullable *gl_enum, lengths: nullable *i32, messageLog: nullable *i8) uint; +export type fp_glGetDebugMessageLogKHR = fn(count: uint, bufSize: i32, sources: nullable *gl_enum, types: nullable *gl_enum, ids: nullable *uint, severities: nullable *gl_enum, lengths: nullable *i32, messageLog: nullable *i8) uint; +export type fp_glGetDriverControlStringQCOM = fn(driverControl: uint, bufSize: i32, length: nullable *i32, driverControlString: nullable *i8) void; +export type fp_glGetDriverControlsQCOM = fn(num: nullable *i32, size_: i32, driverControls: nullable *uint) void; +export type fp_glGetError = fn() gl_enum; +export type fp_glGetFenceivNV = fn(fence: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetFirstPerfQueryIdINTEL = fn(queryId: nullable *uint) void; +export type fp_glGetFloati_vNV = fn(target: gl_enum, index: uint, data: nullable *f32) void; +export type fp_glGetFloati_vOES = fn(target: gl_enum, index: uint, data: nullable *f32) void; +export type fp_glGetFloatv = fn(pname: gl_enum, data: nullable *f32) void; +export type fp_glGetFragDataIndexEXT = fn(program: uint, name: nullable *const i8) i32; +export type fp_glGetFragDataLocation = fn(program: uint, name: nullable *const i8) i32; +export type fp_glGetFragmentShadingRatesEXT = fn(samples: i32, maxCount: i32, count: nullable *i32, shadingRates: nullable *gl_enum) void; +export type fp_glGetFramebufferAttachmentParameteriv = fn(target: gl_enum, attachment: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetFramebufferParameteriv = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetFramebufferParameterivMESA = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetFramebufferPixelLocalStorageSizeEXT = fn(target: uint) i32; +export type fp_glGetGraphicsResetStatus = fn() gl_enum; +export type fp_glGetGraphicsResetStatusEXT = fn() gl_enum; +export type fp_glGetGraphicsResetStatusKHR = fn() gl_enum; +export type fp_glGetImageHandleNV = fn(texture: uint, level: i32, layered: u8, layer: i32, format: gl_enum) u64; +export type fp_glGetInteger64i_v = fn(target: gl_enum, index: uint, data: nullable *i64) void; +export type fp_glGetInteger64v = fn(pname: gl_enum, data: nullable *i64) void; +export type fp_glGetInteger64vAPPLE = fn(pname: gl_enum, params: nullable *i64) void; +export type fp_glGetInteger64vEXT = fn(pname: gl_enum, data: nullable *i64) void; +export type fp_glGetIntegeri_v = fn(target: gl_enum, index: uint, data: nullable *i32) void; +export type fp_glGetIntegeri_vEXT = fn(target: gl_enum, index: uint, data: nullable *i32) void; +export type fp_glGetIntegerv = fn(pname: gl_enum, data: nullable *i32) void; +export type fp_glGetInternalformatSampleivNV = fn(target: gl_enum, internalformat: gl_enum, samples: i32, pname: gl_enum, count: i32, params: nullable *i32) void; +export type fp_glGetInternalformativ = fn(target: gl_enum, internalformat: gl_enum, pname: gl_enum, count: i32, params: nullable *i32) void; +export type fp_glGetMemoryObjectDetachedResourcesuivNV = fn(memory: uint, pname: gl_enum, first: i32, count: i32, params: nullable *uint) void; +export type fp_glGetMemoryObjectParameterivEXT = fn(memoryObject: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetMultisamplefv = fn(pname: gl_enum, index: uint, val: nullable *f32) void; +export type fp_glGetNextPerfQueryIdINTEL = fn(queryId: uint, nextQueryId: nullable *uint) void; +export type fp_glGetObjectLabel = fn(identifier: gl_enum, name: uint, bufSize: i32, length: nullable *i32, label: nullable *i8) void; +export type fp_glGetObjectLabelEXT = fn(type_: gl_enum, object: uint, bufSize: i32, length: nullable *i32, label: nullable *i8) void; +export type fp_glGetObjectLabelKHR = fn(identifier: gl_enum, name: uint, bufSize: i32, length: nullable *i32, label: nullable *i8) void; +export type fp_glGetObjectPtrLabel = fn(ptr: nullable *const opaque, bufSize: i32, length: nullable *i32, label: nullable *i8) void; +export type fp_glGetObjectPtrLabelKHR = fn(ptr: nullable *const opaque, bufSize: i32, length: nullable *i32, label: nullable *i8) void; +export type fp_glGetPathCommandsNV = fn(path: uint, commands: nullable *u8) void; +export type fp_glGetPathCoordsNV = fn(path: uint, coords: nullable *f32) void; +export type fp_glGetPathDashArrayNV = fn(path: uint, dashArray: nullable *f32) void; +export type fp_glGetPathLengthNV = fn(path: uint, startSegment: i32, numSegments: i32) f32; +export type fp_glGetPathMetricRangeNV = fn(metricQueryMask: gl_bitfield, firstPathName: uint, numPaths: i32, stride: i32, metrics: nullable *f32) void; +export type fp_glGetPathMetricsNV = fn(metricQueryMask: gl_bitfield, numPaths: i32, pathNameType: gl_enum, paths: nullable *const opaque, pathBase: uint, stride: i32, metrics: nullable *f32) void; +export type fp_glGetPathParameterfvNV = fn(path: uint, pname: gl_enum, value: nullable *f32) void; +export type fp_glGetPathParameterivNV = fn(path: uint, pname: gl_enum, value: nullable *i32) void; +export type fp_glGetPathSpacingNV = fn(pathListMode: gl_enum, numPaths: i32, pathNameType: gl_enum, paths: nullable *const opaque, pathBase: uint, advanceScale: f32, kerningScale: f32, transformType: gl_enum, returnedSpacing: nullable *f32) void; +export type fp_glGetPerfCounterInfoINTEL = fn(queryId: uint, counterId: uint, counterNameLength: uint, counterName: nullable *i8, counterDescLength: uint, counterDesc: nullable *i8, counterOffset: nullable *uint, counterDataSize: nullable *uint, counterTypeEnum: nullable *uint, counterDataTypeEnum: nullable *uint, rawCounterMaxValue: nullable *u64) void; +export type fp_glGetPerfMonitorCounterDataAMD = fn(monitor: uint, pname: gl_enum, dataSize: i32, data: nullable *uint, bytesWritten: nullable *i32) void; +export type fp_glGetPerfMonitorCounterInfoAMD = fn(group: uint, counter: uint, pname: gl_enum, data: nullable *opaque) void; +export type fp_glGetPerfMonitorCounterStringAMD = fn(group: uint, counter: uint, bufSize: i32, length: nullable *i32, counterString: nullable *i8) void; +export type fp_glGetPerfMonitorCountersAMD = fn(group: uint, numCounters: nullable *i32, maxActiveCounters: nullable *i32, counterSize: i32, counters: nullable *uint) void; +export type fp_glGetPerfMonitorGroupStringAMD = fn(group: uint, bufSize: i32, length: nullable *i32, groupString: nullable *i8) void; +export type fp_glGetPerfMonitorGroupsAMD = fn(numGroups: nullable *i32, groupsSize: i32, groups: nullable *uint) void; +export type fp_glGetPerfQueryDataINTEL = fn(queryHandle: uint, flags: uint, dataSize: i32, data: nullable *opaque, bytesWritten: nullable *uint) void; +export type fp_glGetPerfQueryIdByNameINTEL = fn(queryName: nullable *i8, queryId: nullable *uint) void; +export type fp_glGetPerfQueryInfoINTEL = fn(queryId: uint, queryNameLength: uint, queryName: nullable *i8, dataSize: nullable *uint, noCounters: nullable *uint, noInstances: nullable *uint, capsMask: nullable *uint) void; +export type fp_glGetPointerv = fn(pname: gl_enum, params: nullable *nullable *opaque) void; +export type fp_glGetPointervKHR = fn(pname: gl_enum, params: nullable *nullable *opaque) void; +export type fp_glGetProgramBinary = fn(program: uint, bufSize: i32, length: nullable *i32, binaryFormat: nullable *gl_enum, binary: nullable *opaque) void; +export type fp_glGetProgramBinaryOES = fn(program: uint, bufSize: i32, length: nullable *i32, binaryFormat: nullable *gl_enum, binary: nullable *opaque) void; +export type fp_glGetProgramInfoLog = fn(program: uint, bufSize: i32, length: nullable *i32, infoLog: nullable *i8) void; +export type fp_glGetProgramInterfaceiv = fn(program: uint, programInterface: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetProgramPipelineInfoLog = fn(pipeline: uint, bufSize: i32, length: nullable *i32, infoLog: nullable *i8) void; +export type fp_glGetProgramPipelineInfoLogEXT = fn(pipeline: uint, bufSize: i32, length: nullable *i32, infoLog: nullable *i8) void; +export type fp_glGetProgramPipelineiv = fn(pipeline: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetProgramPipelineivEXT = fn(pipeline: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetProgramResourceIndex = fn(program: uint, programInterface: gl_enum, name: nullable *const i8) uint; +export type fp_glGetProgramResourceLocation = fn(program: uint, programInterface: gl_enum, name: nullable *const i8) i32; +export type fp_glGetProgramResourceLocationIndexEXT = fn(program: uint, programInterface: gl_enum, name: nullable *const i8) i32; +export type fp_glGetProgramResourceName = fn(program: uint, programInterface: gl_enum, index: uint, bufSize: i32, length: nullable *i32, name: nullable *i8) void; +export type fp_glGetProgramResourcefvNV = fn(program: uint, programInterface: gl_enum, index: uint, propCount: i32, props: nullable *const gl_enum, count: i32, length: nullable *i32, params: nullable *f32) void; +export type fp_glGetProgramResourceiv = fn(program: uint, programInterface: gl_enum, index: uint, propCount: i32, props: nullable *const gl_enum, count: i32, length: nullable *i32, params: nullable *i32) void; +export type fp_glGetProgramiv = fn(program: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetQueryObjecti64vEXT = fn(id: uint, pname: gl_enum, params: nullable *i64) void; +export type fp_glGetQueryObjectivEXT = fn(id: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetQueryObjectui64vEXT = fn(id: uint, pname: gl_enum, params: nullable *u64) void; +export type fp_glGetQueryObjectuiv = fn(id: uint, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetQueryObjectuivEXT = fn(id: uint, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetQueryiv = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetQueryivEXT = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetRenderbufferParameteriv = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetSamplerParameterIiv = fn(sampler: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetSamplerParameterIivEXT = fn(sampler: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetSamplerParameterIivOES = fn(sampler: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetSamplerParameterIuiv = fn(sampler: uint, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetSamplerParameterIuivEXT = fn(sampler: uint, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetSamplerParameterIuivOES = fn(sampler: uint, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetSamplerParameterfv = fn(sampler: uint, pname: gl_enum, params: nullable *f32) void; +export type fp_glGetSamplerParameteriv = fn(sampler: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetSemaphoreParameterivNV = fn(semaphore: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetSemaphoreParameterui64vEXT = fn(semaphore: uint, pname: gl_enum, params: nullable *u64) void; +export type fp_glGetShaderInfoLog = fn(shader: uint, bufSize: i32, length: nullable *i32, infoLog: nullable *i8) void; +export type fp_glGetShaderPrecisionFormat = fn(shadertype: gl_enum, precisiontype: gl_enum, range: nullable *i32, precision: nullable *i32) void; +export type fp_glGetShaderSource = fn(shader: uint, bufSize: i32, length: nullable *i32, source: nullable *i8) void; +export type fp_glGetShaderiv = fn(shader: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetShadingRateImagePaletteNV = fn(viewport: uint, entry: uint, rate: nullable *gl_enum) void; +export type fp_glGetShadingRateSampleLocationivNV = fn(rate: gl_enum, samples: uint, index: uint, location: nullable *i32) void; +export type fp_glGetString = fn(name: gl_enum) nullable *const u8; +export type fp_glGetStringi = fn(name: gl_enum, index: uint) nullable *const u8; +export type fp_glGetSynciv = fn(sync: size, pname: gl_enum, count: i32, length: nullable *i32, values: nullable *i32) void; +export type fp_glGetSyncivAPPLE = fn(sync: size, pname: gl_enum, count: i32, length: nullable *i32, values: nullable *i32) void; +export type fp_glGetTexLevelParameterfv = fn(target: gl_enum, level: i32, pname: gl_enum, params: nullable *f32) void; +export type fp_glGetTexLevelParameteriv = fn(target: gl_enum, level: i32, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetTexParameterIiv = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetTexParameterIivEXT = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetTexParameterIivOES = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetTexParameterIuiv = fn(target: gl_enum, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetTexParameterIuivEXT = fn(target: gl_enum, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetTexParameterIuivOES = fn(target: gl_enum, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetTexParameterfv = fn(target: gl_enum, pname: gl_enum, params: nullable *f32) void; +export type fp_glGetTexParameteriv = fn(target: gl_enum, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetTextureHandleIMG = fn(texture: uint) u64; +export type fp_glGetTextureHandleNV = fn(texture: uint) u64; +export type fp_glGetTextureSamplerHandleIMG = fn(texture: uint, sampler: uint) u64; +export type fp_glGetTextureSamplerHandleNV = fn(texture: uint, sampler: uint) u64; +export type fp_glGetTransformFeedbackVarying = fn(program: uint, index: uint, bufSize: i32, length: nullable *i32, size_: nullable *i32, type_: nullable *gl_enum, name: nullable *i8) void; +export type fp_glGetTranslatedShaderSourceANGLE = fn(shader: uint, bufSize: i32, length: nullable *i32, source: nullable *i8) void; +export type fp_glGetUniformBlockIndex = fn(program: uint, uniformBlockName: nullable *const i8) uint; +export type fp_glGetUniformIndices = fn(program: uint, uniformCount: i32, uniformNames: nullable *const nullable *const i8, uniformIndices: nullable *uint) void; +export type fp_glGetUniformLocation = fn(program: uint, name: nullable *const i8) i32; +export type fp_glGetUniformfv = fn(program: uint, location: i32, params: nullable *f32) void; +export type fp_glGetUniformi64vNV = fn(program: uint, location: i32, params: nullable *i64) void; +export type fp_glGetUniformiv = fn(program: uint, location: i32, params: nullable *i32) void; +export type fp_glGetUniformuiv = fn(program: uint, location: i32, params: nullable *uint) void; +export type fp_glGetUnsignedBytei_vEXT = fn(target: gl_enum, index: uint, data: nullable *u8) void; +export type fp_glGetUnsignedBytevEXT = fn(pname: gl_enum, data: nullable *u8) void; +export type fp_glGetVertexAttribIiv = fn(index: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetVertexAttribIuiv = fn(index: uint, pname: gl_enum, params: nullable *uint) void; +export type fp_glGetVertexAttribPointerv = fn(index: uint, pname: gl_enum, pointer: nullable *nullable *opaque) void; +export type fp_glGetVertexAttribfv = fn(index: uint, pname: gl_enum, params: nullable *f32) void; +export type fp_glGetVertexAttribiv = fn(index: uint, pname: gl_enum, params: nullable *i32) void; +export type fp_glGetVkProcAddrNV = fn(name: nullable *const i8) GLVULKANPROCNV; +export type fp_glGetnUniformfv = fn(program: uint, location: i32, bufSize: i32, params: nullable *f32) void; +export type fp_glGetnUniformfvEXT = fn(program: uint, location: i32, bufSize: i32, params: nullable *f32) void; +export type fp_glGetnUniformfvKHR = fn(program: uint, location: i32, bufSize: i32, params: nullable *f32) void; +export type fp_glGetnUniformiv = fn(program: uint, location: i32, bufSize: i32, params: nullable *i32) void; +export type fp_glGetnUniformivEXT = fn(program: uint, location: i32, bufSize: i32, params: nullable *i32) void; +export type fp_glGetnUniformivKHR = fn(program: uint, location: i32, bufSize: i32, params: nullable *i32) void; +export type fp_glGetnUniformuiv = fn(program: uint, location: i32, bufSize: i32, params: nullable *uint) void; +export type fp_glGetnUniformuivKHR = fn(program: uint, location: i32, bufSize: i32, params: nullable *uint) void; +export type fp_glHint = fn(target: gl_enum, mode: gl_enum) void; +export type fp_glImportMemoryFdEXT = fn(memory: uint, size_: u64, handleType: gl_enum, fd: i32) void; +export type fp_glImportMemoryWin32HandleEXT = fn(memory: uint, size_: u64, handleType: gl_enum, handle: nullable *opaque) void; +export type fp_glImportMemoryWin32NameEXT = fn(memory: uint, size_: u64, handleType: gl_enum, name: nullable *const opaque) void; +export type fp_glImportSemaphoreFdEXT = fn(semaphore: uint, handleType: gl_enum, fd: i32) void; +export type fp_glImportSemaphoreWin32HandleEXT = fn(semaphore: uint, handleType: gl_enum, handle: nullable *opaque) void; +export type fp_glImportSemaphoreWin32NameEXT = fn(semaphore: uint, handleType: gl_enum, name: nullable *const opaque) void; +export type fp_glInsertEventMarkerEXT = fn(length: i32, marker: nullable *const i8) void; +export type fp_glInterpolatePathsNV = fn(resultPath: uint, pathA: uint, pathB: uint, weight: f32) void; +export type fp_glInvalidateFramebuffer = fn(target: gl_enum, numAttachments: i32, attachments: nullable *const gl_enum) void; +export type fp_glInvalidateSubFramebuffer = fn(target: gl_enum, numAttachments: i32, attachments: nullable *const gl_enum, x: i32, y: i32, width: i32, height: i32) void; +export type fp_glIsBuffer = fn(buffer: uint) u8; +export type fp_glIsEnabled = fn(cap: gl_enum) u8; +export type fp_glIsEnabledi = fn(target: gl_enum, index: uint) u8; +export type fp_glIsEnablediEXT = fn(target: gl_enum, index: uint) u8; +export type fp_glIsEnablediNV = fn(target: gl_enum, index: uint) u8; +export type fp_glIsEnablediOES = fn(target: gl_enum, index: uint) u8; +export type fp_glIsFenceNV = fn(fence: uint) u8; +export type fp_glIsFramebuffer = fn(framebuffer: uint) u8; +export type fp_glIsImageHandleResidentNV = fn(handle: u64) u8; +export type fp_glIsMemoryObjectEXT = fn(memoryObject: uint) u8; +export type fp_glIsPathNV = fn(path: uint) u8; +export type fp_glIsPointInFillPathNV = fn(path: uint, mask: uint, x: f32, y: f32) u8; +export type fp_glIsPointInStrokePathNV = fn(path: uint, x: f32, y: f32) u8; +export type fp_glIsProgram = fn(program: uint) u8; +export type fp_glIsProgramPipeline = fn(pipeline: uint) u8; +export type fp_glIsProgramPipelineEXT = fn(pipeline: uint) u8; +export type fp_glIsQuery = fn(id: uint) u8; +export type fp_glIsQueryEXT = fn(id: uint) u8; +export type fp_glIsRenderbuffer = fn(renderbuffer: uint) u8; +export type fp_glIsSampler = fn(sampler: uint) u8; +export type fp_glIsSemaphoreEXT = fn(semaphore: uint) u8; +export type fp_glIsShader = fn(shader: uint) u8; +export type fp_glIsSync = fn(sync: size) u8; +export type fp_glIsSyncAPPLE = fn(sync: size) u8; +export type fp_glIsTexture = fn(texture: uint) u8; +export type fp_glIsTextureHandleResidentNV = fn(handle: u64) u8; +export type fp_glIsTransformFeedback = fn(id: uint) u8; +export type fp_glIsVertexArray = fn(array: uint) u8; +export type fp_glIsVertexArrayOES = fn(array: uint) u8; +export type fp_glLabelObjectEXT = fn(type_: gl_enum, object: uint, length: i32, label: nullable *const i8) void; +export type fp_glLineWidth = fn(width: f32) void; +export type fp_glLinkProgram = fn(program: uint) void; +export type fp_glMakeImageHandleNonResidentNV = fn(handle: u64) void; +export type fp_glMakeImageHandleResidentNV = fn(handle: u64, access: gl_enum) void; +export type fp_glMakeTextureHandleNonResidentNV = fn(handle: u64) void; +export type fp_glMakeTextureHandleResidentNV = fn(handle: u64) void; +export type fp_glMapBufferOES = fn(target: gl_enum, access: gl_enum) nullable *opaque; +export type fp_glMapBufferRange = fn(target: gl_enum, offset_: size, length: uintptr, access: gl_bitfield) nullable *opaque; +export type fp_glMapBufferRangeEXT = fn(target: gl_enum, offset_: size, length: uintptr, access: gl_bitfield) nullable *opaque; +export type fp_glMatrixFrustumEXT = fn(mode: gl_enum, left: f64, right: f64, bottom: f64, top: f64, zNear: f64, zFar: f64) void; +export type fp_glMatrixLoad3x2fNV = fn(matrixMode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixLoad3x3fNV = fn(matrixMode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixLoadIdentityEXT = fn(mode: gl_enum) void; +export type fp_glMatrixLoadTranspose3x3fNV = fn(matrixMode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixLoadTransposedEXT = fn(mode: gl_enum, m: nullable *const f64) void; +export type fp_glMatrixLoadTransposefEXT = fn(mode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixLoaddEXT = fn(mode: gl_enum, m: nullable *const f64) void; +export type fp_glMatrixLoadfEXT = fn(mode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixMult3x2fNV = fn(matrixMode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixMult3x3fNV = fn(matrixMode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixMultTranspose3x3fNV = fn(matrixMode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixMultTransposedEXT = fn(mode: gl_enum, m: nullable *const f64) void; +export type fp_glMatrixMultTransposefEXT = fn(mode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixMultdEXT = fn(mode: gl_enum, m: nullable *const f64) void; +export type fp_glMatrixMultfEXT = fn(mode: gl_enum, m: nullable *const f32) void; +export type fp_glMatrixOrthoEXT = fn(mode: gl_enum, left: f64, right: f64, bottom: f64, top: f64, zNear: f64, zFar: f64) void; +export type fp_glMatrixPopEXT = fn(mode: gl_enum) void; +export type fp_glMatrixPushEXT = fn(mode: gl_enum) void; +export type fp_glMatrixRotatedEXT = fn(mode: gl_enum, angle: f64, x: f64, y: f64, z: f64) void; +export type fp_glMatrixRotatefEXT = fn(mode: gl_enum, angle: f32, x: f32, y: f32, z: f32) void; +export type fp_glMatrixScaledEXT = fn(mode: gl_enum, x: f64, y: f64, z: f64) void; +export type fp_glMatrixScalefEXT = fn(mode: gl_enum, x: f32, y: f32, z: f32) void; +export type fp_glMatrixTranslatedEXT = fn(mode: gl_enum, x: f64, y: f64, z: f64) void; +export type fp_glMatrixTranslatefEXT = fn(mode: gl_enum, x: f32, y: f32, z: f32) void; +export type fp_glMaxShaderCompilerThreadsKHR = fn(count: uint) void; +export type fp_glMemoryBarrier = fn(barriers: gl_bitfield) void; +export type fp_glMemoryBarrierByRegion = fn(barriers: gl_bitfield) void; +export type fp_glMemoryObjectParameterivEXT = fn(memoryObject: uint, pname: gl_enum, params: nullable *const i32) void; +export type fp_glMinSampleShading = fn(value: f32) void; +export type fp_glMinSampleShadingOES = fn(value: f32) void; +export type fp_glMultiDrawArraysEXT = fn(mode: gl_enum, first: nullable *const i32, count: nullable *const i32, primcount: i32) void; +export type fp_glMultiDrawArraysIndirectEXT = fn(mode: gl_enum, indirect: nullable *const opaque, drawcount: i32, stride: i32) void; +export type fp_glMultiDrawElementsBaseVertexEXT = fn(mode: gl_enum, count: nullable *const i32, type_: gl_enum, indices: nullable *const nullable *const opaque, drawcount: i32, basevertex: nullable *const i32) void; +export type fp_glMultiDrawElementsEXT = fn(mode: gl_enum, count: nullable *const i32, type_: gl_enum, indices: nullable *const nullable *const opaque, primcount: i32) void; +export type fp_glMultiDrawElementsIndirectEXT = fn(mode: gl_enum, type_: gl_enum, indirect: nullable *const opaque, drawcount: i32, stride: i32) void; +export type fp_glMultiDrawMeshTasksIndirectCountNV = fn(indirect: size, drawcount: size, maxdrawcount: i32, stride: i32) void; +export type fp_glMultiDrawMeshTasksIndirectNV = fn(indirect: size, drawcount: i32, stride: i32) void; +export type fp_glNamedBufferAttachMemoryNV = fn(buffer: uint, memory: uint, offset_: u64) void; +export type fp_glNamedBufferPageCommitmentMemNV = fn(buffer: uint, offset_: size, size_: uintptr, memory: uint, memOffset: u64, commit: u8) void; +export type fp_glNamedBufferStorageExternalEXT = fn(buffer: uint, offset_: size, size_: uintptr, clientBuffer: *opaque, flags: gl_bitfield) void; +export type fp_glNamedBufferStorageMemEXT = fn(buffer: uint, size_: uintptr, memory: uint, offset_: u64) void; +export type fp_glNamedFramebufferSampleLocationsfvNV = fn(framebuffer: uint, start: uint, count: i32, v: nullable *const f32) void; +export type fp_glNamedRenderbufferStorageMultisampleAdvancedAMD = fn(renderbuffer: uint, samples: i32, storageSamples: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glObjectLabel = fn(identifier: gl_enum, name: uint, length: i32, label: nullable *const i8) void; +export type fp_glObjectLabelKHR = fn(identifier: gl_enum, name: uint, length: i32, label: nullable *const i8) void; +export type fp_glObjectPtrLabel = fn(ptr: nullable *const opaque, length: i32, label: nullable *const i8) void; +export type fp_glObjectPtrLabelKHR = fn(ptr: nullable *const opaque, length: i32, label: nullable *const i8) void; +export type fp_glPatchParameteri = fn(pname: gl_enum, value: i32) void; +export type fp_glPatchParameteriEXT = fn(pname: gl_enum, value: i32) void; +export type fp_glPatchParameteriOES = fn(pname: gl_enum, value: i32) void; +export type fp_glPathCommandsNV = fn(path: uint, numCommands: i32, commands: nullable *const u8, numCoords: i32, coordType: gl_enum, coords: nullable *const opaque) void; +export type fp_glPathCoordsNV = fn(path: uint, numCoords: i32, coordType: gl_enum, coords: nullable *const opaque) void; +export type fp_glPathCoverDepthFuncNV = fn(func: gl_enum) void; +export type fp_glPathDashArrayNV = fn(path: uint, dashCount: i32, dashArray: nullable *const f32) void; +export type fp_glPathGlyphIndexArrayNV = fn(firstPathName: uint, fontTarget: gl_enum, fontName: nullable *const opaque, fontStyle: gl_bitfield, firstGlyphIndex: uint, numGlyphs: i32, pathParameterTemplate: uint, emScale: f32) gl_enum; +export type fp_glPathGlyphIndexRangeNV = fn(fontTarget: gl_enum, fontName: nullable *const opaque, fontStyle: gl_bitfield, pathParameterTemplate: uint, emScale: f32, baseAndCount: nullable *uint) gl_enum; +export type fp_glPathGlyphRangeNV = fn(firstPathName: uint, fontTarget: gl_enum, fontName: nullable *const opaque, fontStyle: gl_bitfield, firstGlyph: uint, numGlyphs: i32, handleMissingGlyphs: gl_enum, pathParameterTemplate: uint, emScale: f32) void; +export type fp_glPathGlyphsNV = fn(firstPathName: uint, fontTarget: gl_enum, fontName: nullable *const opaque, fontStyle: gl_bitfield, numGlyphs: i32, type_: gl_enum, charcodes: nullable *const opaque, handleMissingGlyphs: gl_enum, pathParameterTemplate: uint, emScale: f32) void; +export type fp_glPathMemoryGlyphIndexArrayNV = fn(firstPathName: uint, fontTarget: gl_enum, fontSize: uintptr, fontData: nullable *const opaque, faceIndex: i32, firstGlyphIndex: uint, numGlyphs: i32, pathParameterTemplate: uint, emScale: f32) gl_enum; +export type fp_glPathParameterfNV = fn(path: uint, pname: gl_enum, value: f32) void; +export type fp_glPathParameterfvNV = fn(path: uint, pname: gl_enum, value: nullable *const f32) void; +export type fp_glPathParameteriNV = fn(path: uint, pname: gl_enum, value: i32) void; +export type fp_glPathParameterivNV = fn(path: uint, pname: gl_enum, value: nullable *const i32) void; +export type fp_glPathStencilDepthOffsetNV = fn(factor: f32, units: f32) void; +export type fp_glPathStencilFuncNV = fn(func: gl_enum, ref: i32, mask: uint) void; +export type fp_glPathStringNV = fn(path: uint, format: gl_enum, length: i32, pathString: nullable *const opaque) void; +export type fp_glPathSubCommandsNV = fn(path: uint, commandStart: i32, commandsToDelete: i32, numCommands: i32, commands: nullable *const u8, numCoords: i32, coordType: gl_enum, coords: nullable *const opaque) void; +export type fp_glPathSubCoordsNV = fn(path: uint, coordStart: i32, numCoords: i32, coordType: gl_enum, coords: nullable *const opaque) void; +export type fp_glPauseTransformFeedback = fn() void; +export type fp_glPixelStorei = fn(pname: gl_enum, param: i32) void; +export type fp_glPointAlongPathNV = fn(path: uint, startSegment: i32, numSegments: i32, distance: f32, x: nullable *f32, y: nullable *f32, tangentX: nullable *f32, tangentY: nullable *f32) u8; +export type fp_glPolygonModeNV = fn(face: gl_enum, mode: gl_enum) void; +export type fp_glPolygonOffset = fn(factor: f32, units: f32) void; +export type fp_glPolygonOffsetClampEXT = fn(factor: f32, units: f32, clamp: f32) void; +export type fp_glPopDebugGroup = fn() void; +export type fp_glPopDebugGroupKHR = fn() void; +export type fp_glPopGroupMarkerEXT = fn() void; +export type fp_glPrimitiveBoundingBox = fn(minX: f32, minY: f32, minZ: f32, minW: f32, maxX: f32, maxY: f32, maxZ: f32, maxW: f32) void; +export type fp_glPrimitiveBoundingBoxEXT = fn(minX: f32, minY: f32, minZ: f32, minW: f32, maxX: f32, maxY: f32, maxZ: f32, maxW: f32) void; +export type fp_glPrimitiveBoundingBoxOES = fn(minX: f32, minY: f32, minZ: f32, minW: f32, maxX: f32, maxY: f32, maxZ: f32, maxW: f32) void; +export type fp_glProgramBinary = fn(program: uint, binaryFormat: gl_enum, binary: nullable *const opaque, length: i32) void; +export type fp_glProgramBinaryOES = fn(program: uint, binaryFormat: gl_enum, binary: nullable *const opaque, length: i32) void; +export type fp_glProgramParameteri = fn(program: uint, pname: gl_enum, value: i32) void; +export type fp_glProgramParameteriEXT = fn(program: uint, pname: gl_enum, value: i32) void; +export type fp_glProgramPathFragmentInputGenNV = fn(program: uint, location: i32, genMode: gl_enum, components: i32, coeffs: nullable *const f32) void; +export type fp_glProgramUniform1f = fn(program: uint, location: i32, v0: f32) void; +export type fp_glProgramUniform1fEXT = fn(program: uint, location: i32, v0: f32) void; +export type fp_glProgramUniform1fv = fn(program: uint, location: i32, count: i32, value: nullable *const f32) void; +export type fp_glProgramUniform1fvEXT = fn(program: uint, location: i32, count: i32, value: nullable *const f32) void; +export type fp_glProgramUniform1i = fn(program: uint, location: i32, v0: i32) void; +export type fp_glProgramUniform1i64NV = fn(program: uint, location: i32, x: i64) void; +export type fp_glProgramUniform1i64vNV = fn(program: uint, location: i32, count: i32, value: nullable *const i64) void; +export type fp_glProgramUniform1iEXT = fn(program: uint, location: i32, v0: i32) void; +export type fp_glProgramUniform1iv = fn(program: uint, location: i32, count: i32, value: nullable *const i32) void; +export type fp_glProgramUniform1ivEXT = fn(program: uint, location: i32, count: i32, value: nullable *const i32) void; +export type fp_glProgramUniform1ui = fn(program: uint, location: i32, v0: uint) void; +export type fp_glProgramUniform1ui64NV = fn(program: uint, location: i32, x: u64) void; +export type fp_glProgramUniform1ui64vNV = fn(program: uint, location: i32, count: i32, value: nullable *const u64) void; +export type fp_glProgramUniform1uiEXT = fn(program: uint, location: i32, v0: uint) void; +export type fp_glProgramUniform1uiv = fn(program: uint, location: i32, count: i32, value: nullable *const uint) void; +export type fp_glProgramUniform1uivEXT = fn(program: uint, location: i32, count: i32, value: nullable *const uint) void; +export type fp_glProgramUniform2f = fn(program: uint, location: i32, v0: f32, v1: f32) void; +export type fp_glProgramUniform2fEXT = fn(program: uint, location: i32, v0: f32, v1: f32) void; +export type fp_glProgramUniform2fv = fn(program: uint, location: i32, count: i32, value: nullable *const f32) void; +export type fp_glProgramUniform2fvEXT = fn(program: uint, location: i32, count: i32, value: nullable *const f32) void; +export type fp_glProgramUniform2i = fn(program: uint, location: i32, v0: i32, v1: i32) void; +export type fp_glProgramUniform2i64NV = fn(program: uint, location: i32, x: i64, y: i64) void; +export type fp_glProgramUniform2i64vNV = fn(program: uint, location: i32, count: i32, value: nullable *const i64) void; +export type fp_glProgramUniform2iEXT = fn(program: uint, location: i32, v0: i32, v1: i32) void; +export type fp_glProgramUniform2iv = fn(program: uint, location: i32, count: i32, value: nullable *const i32) void; +export type fp_glProgramUniform2ivEXT = fn(program: uint, location: i32, count: i32, value: nullable *const i32) void; +export type fp_glProgramUniform2ui = fn(program: uint, location: i32, v0: uint, v1: uint) void; +export type fp_glProgramUniform2ui64NV = fn(program: uint, location: i32, x: u64, y: u64) void; +export type fp_glProgramUniform2ui64vNV = fn(program: uint, location: i32, count: i32, value: nullable *const u64) void; +export type fp_glProgramUniform2uiEXT = fn(program: uint, location: i32, v0: uint, v1: uint) void; +export type fp_glProgramUniform2uiv = fn(program: uint, location: i32, count: i32, value: nullable *const uint) void; +export type fp_glProgramUniform2uivEXT = fn(program: uint, location: i32, count: i32, value: nullable *const uint) void; +export type fp_glProgramUniform3f = fn(program: uint, location: i32, v0: f32, v1: f32, v2: f32) void; +export type fp_glProgramUniform3fEXT = fn(program: uint, location: i32, v0: f32, v1: f32, v2: f32) void; +export type fp_glProgramUniform3fv = fn(program: uint, location: i32, count: i32, value: nullable *const f32) void; +export type fp_glProgramUniform3fvEXT = fn(program: uint, location: i32, count: i32, value: nullable *const f32) void; +export type fp_glProgramUniform3i = fn(program: uint, location: i32, v0: i32, v1: i32, v2: i32) void; +export type fp_glProgramUniform3i64NV = fn(program: uint, location: i32, x: i64, y: i64, z: i64) void; +export type fp_glProgramUniform3i64vNV = fn(program: uint, location: i32, count: i32, value: nullable *const i64) void; +export type fp_glProgramUniform3iEXT = fn(program: uint, location: i32, v0: i32, v1: i32, v2: i32) void; +export type fp_glProgramUniform3iv = fn(program: uint, location: i32, count: i32, value: nullable *const i32) void; +export type fp_glProgramUniform3ivEXT = fn(program: uint, location: i32, count: i32, value: nullable *const i32) void; +export type fp_glProgramUniform3ui = fn(program: uint, location: i32, v0: uint, v1: uint, v2: uint) void; +export type fp_glProgramUniform3ui64NV = fn(program: uint, location: i32, x: u64, y: u64, z: u64) void; +export type fp_glProgramUniform3ui64vNV = fn(program: uint, location: i32, count: i32, value: nullable *const u64) void; +export type fp_glProgramUniform3uiEXT = fn(program: uint, location: i32, v0: uint, v1: uint, v2: uint) void; +export type fp_glProgramUniform3uiv = fn(program: uint, location: i32, count: i32, value: nullable *const uint) void; +export type fp_glProgramUniform3uivEXT = fn(program: uint, location: i32, count: i32, value: nullable *const uint) void; +export type fp_glProgramUniform4f = fn(program: uint, location: i32, v0: f32, v1: f32, v2: f32, v3: f32) void; +export type fp_glProgramUniform4fEXT = fn(program: uint, location: i32, v0: f32, v1: f32, v2: f32, v3: f32) void; +export type fp_glProgramUniform4fv = fn(program: uint, location: i32, count: i32, value: nullable *const f32) void; +export type fp_glProgramUniform4fvEXT = fn(program: uint, location: i32, count: i32, value: nullable *const f32) void; +export type fp_glProgramUniform4i = fn(program: uint, location: i32, v0: i32, v1: i32, v2: i32, v3: i32) void; +export type fp_glProgramUniform4i64NV = fn(program: uint, location: i32, x: i64, y: i64, z: i64, w: i64) void; +export type fp_glProgramUniform4i64vNV = fn(program: uint, location: i32, count: i32, value: nullable *const i64) void; +export type fp_glProgramUniform4iEXT = fn(program: uint, location: i32, v0: i32, v1: i32, v2: i32, v3: i32) void; +export type fp_glProgramUniform4iv = fn(program: uint, location: i32, count: i32, value: nullable *const i32) void; +export type fp_glProgramUniform4ivEXT = fn(program: uint, location: i32, count: i32, value: nullable *const i32) void; +export type fp_glProgramUniform4ui = fn(program: uint, location: i32, v0: uint, v1: uint, v2: uint, v3: uint) void; +export type fp_glProgramUniform4ui64NV = fn(program: uint, location: i32, x: u64, y: u64, z: u64, w: u64) void; +export type fp_glProgramUniform4ui64vNV = fn(program: uint, location: i32, count: i32, value: nullable *const u64) void; +export type fp_glProgramUniform4uiEXT = fn(program: uint, location: i32, v0: uint, v1: uint, v2: uint, v3: uint) void; +export type fp_glProgramUniform4uiv = fn(program: uint, location: i32, count: i32, value: nullable *const uint) void; +export type fp_glProgramUniform4uivEXT = fn(program: uint, location: i32, count: i32, value: nullable *const uint) void; +export type fp_glProgramUniformHandleui64IMG = fn(program: uint, location: i32, value: u64) void; +export type fp_glProgramUniformHandleui64NV = fn(program: uint, location: i32, value: u64) void; +export type fp_glProgramUniformHandleui64vIMG = fn(program: uint, location: i32, count: i32, values: nullable *const u64) void; +export type fp_glProgramUniformHandleui64vNV = fn(program: uint, location: i32, count: i32, values: nullable *const u64) void; +export type fp_glProgramUniformMatrix2fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix2fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix2x3fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix2x3fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix2x4fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix2x4fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix3fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix3fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix3x2fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix3x2fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix3x4fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix3x4fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix4fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix4fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix4x2fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix4x2fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix4x3fv = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glProgramUniformMatrix4x3fvEXT = fn(program: uint, location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glPushDebugGroup = fn(source: gl_enum, id: uint, length: i32, message: nullable *const i8) void; +export type fp_glPushDebugGroupKHR = fn(source: gl_enum, id: uint, length: i32, message: nullable *const i8) void; +export type fp_glPushGroupMarkerEXT = fn(length: i32, marker: nullable *const i8) void; +export type fp_glQueryCounterEXT = fn(id: uint, target: gl_enum) void; +export type fp_glRasterSamplesEXT = fn(samples: uint, fixedsamplelocations: u8) void; +export type fp_glReadBuffer = fn(src: gl_enum) void; +export type fp_glReadBufferIndexedEXT = fn(src: gl_enum, index: i32) void; +export type fp_glReadBufferNV = fn(mode: gl_enum) void; +export type fp_glReadPixels = fn(x: i32, y: i32, width: i32, height: i32, format: gl_enum, type_: gl_enum, pixels: nullable *opaque) void; +export type fp_glReadnPixels = fn(x: i32, y: i32, width: i32, height: i32, format: gl_enum, type_: gl_enum, bufSize: i32, data: nullable *opaque) void; +export type fp_glReadnPixelsEXT = fn(x: i32, y: i32, width: i32, height: i32, format: gl_enum, type_: gl_enum, bufSize: i32, data: nullable *opaque) void; +export type fp_glReadnPixelsKHR = fn(x: i32, y: i32, width: i32, height: i32, format: gl_enum, type_: gl_enum, bufSize: i32, data: nullable *opaque) void; +export type fp_glReleaseKeyedMutexWin32EXT = fn(memory: uint, key: u64) u8; +export type fp_glReleaseShaderCompiler = fn() void; +export type fp_glRenderbufferStorage = fn(target: gl_enum, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glRenderbufferStorageMultisample = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glRenderbufferStorageMultisampleANGLE = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glRenderbufferStorageMultisampleAPPLE = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glRenderbufferStorageMultisampleAdvancedAMD = fn(target: gl_enum, samples: i32, storageSamples: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glRenderbufferStorageMultisampleEXT = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glRenderbufferStorageMultisampleIMG = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glRenderbufferStorageMultisampleNV = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glResetMemoryObjectParameterNV = fn(memory: uint, pname: gl_enum) void; +export type fp_glResolveDepthValuesNV = fn() void; +export type fp_glResolveMultisampleFramebufferAPPLE = fn() void; +export type fp_glResumeTransformFeedback = fn() void; +export type fp_glSampleCoverage = fn(value: f32, invert: u8) void; +export type fp_glSampleMaski = fn(maskNumber: uint, mask: gl_bitfield) void; +export type fp_glSamplerParameterIiv = fn(sampler: uint, pname: gl_enum, param: nullable *const i32) void; +export type fp_glSamplerParameterIivEXT = fn(sampler: uint, pname: gl_enum, param: nullable *const i32) void; +export type fp_glSamplerParameterIivOES = fn(sampler: uint, pname: gl_enum, param: nullable *const i32) void; +export type fp_glSamplerParameterIuiv = fn(sampler: uint, pname: gl_enum, param: nullable *const uint) void; +export type fp_glSamplerParameterIuivEXT = fn(sampler: uint, pname: gl_enum, param: nullable *const uint) void; +export type fp_glSamplerParameterIuivOES = fn(sampler: uint, pname: gl_enum, param: nullable *const uint) void; +export type fp_glSamplerParameterf = fn(sampler: uint, pname: gl_enum, param: f32) void; +export type fp_glSamplerParameterfv = fn(sampler: uint, pname: gl_enum, param: nullable *const f32) void; +export type fp_glSamplerParameteri = fn(sampler: uint, pname: gl_enum, param: i32) void; +export type fp_glSamplerParameteriv = fn(sampler: uint, pname: gl_enum, param: nullable *const i32) void; +export type fp_glScissor = fn(x: i32, y: i32, width: i32, height: i32) void; +export type fp_glScissorArrayvNV = fn(first: uint, count: i32, v: nullable *const i32) void; +export type fp_glScissorArrayvOES = fn(first: uint, count: i32, v: nullable *const i32) void; +export type fp_glScissorExclusiveArrayvNV = fn(first: uint, count: i32, v: nullable *const i32) void; +export type fp_glScissorExclusiveNV = fn(x: i32, y: i32, width: i32, height: i32) void; +export type fp_glScissorIndexedNV = fn(index: uint, left: i32, bottom: i32, width: i32, height: i32) void; +export type fp_glScissorIndexedOES = fn(index: uint, left: i32, bottom: i32, width: i32, height: i32) void; +export type fp_glScissorIndexedvNV = fn(index: uint, v: nullable *const i32) void; +export type fp_glScissorIndexedvOES = fn(index: uint, v: nullable *const i32) void; +export type fp_glSelectPerfMonitorCountersAMD = fn(monitor: uint, enable: u8, group: uint, numCounters: i32, counterList: nullable *uint) void; +export type fp_glSemaphoreParameterivNV = fn(semaphore: uint, pname: gl_enum, params: nullable *const i32) void; +export type fp_glSemaphoreParameterui64vEXT = fn(semaphore: uint, pname: gl_enum, params: nullable *const u64) void; +export type fp_glSetFenceNV = fn(fence: uint, condition: gl_enum) void; +export type fp_glShaderBinary = fn(count: i32, shaders: nullable *const uint, binaryFormat: gl_enum, binary: nullable *const opaque, length: i32) void; +export type fp_glShaderSource = fn(shader: uint, count: i32, string: nullable *const nullable *const i8, length: nullable *const i32) void; +export type fp_glShadingRateCombinerOpsEXT = fn(combinerOp0: gl_enum, combinerOp1: gl_enum) void; +export type fp_glShadingRateEXT = fn(rate: gl_enum) void; +export type fp_glShadingRateImageBarrierNV = fn(synchronize: u8) void; +export type fp_glShadingRateImagePaletteNV = fn(viewport: uint, first: uint, count: i32, rates: nullable *const gl_enum) void; +export type fp_glShadingRateQCOM = fn(rate: gl_enum) void; +export type fp_glShadingRateSampleOrderCustomNV = fn(rate: gl_enum, samples: uint, locations: nullable *const i32) void; +export type fp_glShadingRateSampleOrderNV = fn(order: gl_enum) void; +export type fp_glSignalSemaphoreEXT = fn(semaphore: uint, numBufferBarriers: uint, buffers: nullable *const uint, numTextureBarriers: uint, textures: nullable *const uint, dstLayouts: nullable *const gl_enum) void; +export type fp_glSignalVkFenceNV = fn(vkFence: u64) void; +export type fp_glSignalVkSemaphoreNV = fn(vkSemaphore: u64) void; +export type fp_glStartTilingQCOM = fn(x: uint, y: uint, width: uint, height: uint, preserveMask: gl_bitfield) void; +export type fp_glStencilFillPathInstancedNV = fn(numPaths: i32, pathNameType: gl_enum, paths: nullable *const opaque, pathBase: uint, fillMode: gl_enum, mask: uint, transformType: gl_enum, transformValues: nullable *const f32) void; +export type fp_glStencilFillPathNV = fn(path: uint, fillMode: gl_enum, mask: uint) void; +export type fp_glStencilFunc = fn(func: gl_enum, ref: i32, mask: uint) void; +export type fp_glStencilFuncSeparate = fn(face: gl_enum, func: gl_enum, ref: i32, mask: uint) void; +export type fp_glStencilMask = fn(mask: uint) void; +export type fp_glStencilMaskSeparate = fn(face: gl_enum, mask: uint) void; +export type fp_glStencilOp = fn(fail: gl_enum, zfail: gl_enum, zpass: gl_enum) void; +export type fp_glStencilOpSeparate = fn(face: gl_enum, sfail: gl_enum, dpfail: gl_enum, dppass: gl_enum) void; +export type fp_glStencilStrokePathInstancedNV = fn(numPaths: i32, pathNameType: gl_enum, paths: nullable *const opaque, pathBase: uint, reference: i32, mask: uint, transformType: gl_enum, transformValues: nullable *const f32) void; +export type fp_glStencilStrokePathNV = fn(path: uint, reference: i32, mask: uint) void; +export type fp_glStencilThenCoverFillPathInstancedNV = fn(numPaths: i32, pathNameType: gl_enum, paths: nullable *const opaque, pathBase: uint, fillMode: gl_enum, mask: uint, coverMode: gl_enum, transformType: gl_enum, transformValues: nullable *const f32) void; +export type fp_glStencilThenCoverFillPathNV = fn(path: uint, fillMode: gl_enum, mask: uint, coverMode: gl_enum) void; +export type fp_glStencilThenCoverStrokePathInstancedNV = fn(numPaths: i32, pathNameType: gl_enum, paths: nullable *const opaque, pathBase: uint, reference: i32, mask: uint, coverMode: gl_enum, transformType: gl_enum, transformValues: nullable *const f32) void; +export type fp_glStencilThenCoverStrokePathNV = fn(path: uint, reference: i32, mask: uint, coverMode: gl_enum) void; +export type fp_glSubpixelPrecisionBiasNV = fn(xbits: uint, ybits: uint) void; +export type fp_glTestFenceNV = fn(fence: uint) u8; +export type fp_glTexAttachMemoryNV = fn(target: gl_enum, memory: uint, offset_: u64) void; +export type fp_glTexBuffer = fn(target: gl_enum, internalformat: gl_enum, buffer: uint) void; +export type fp_glTexBufferEXT = fn(target: gl_enum, internalformat: gl_enum, buffer: uint) void; +export type fp_glTexBufferOES = fn(target: gl_enum, internalformat: gl_enum, buffer: uint) void; +export type fp_glTexBufferRange = fn(target: gl_enum, internalformat: gl_enum, buffer: uint, offset_: size, size_: uintptr) void; +export type fp_glTexBufferRangeEXT = fn(target: gl_enum, internalformat: gl_enum, buffer: uint, offset_: size, size_: uintptr) void; +export type fp_glTexBufferRangeOES = fn(target: gl_enum, internalformat: gl_enum, buffer: uint, offset_: size, size_: uintptr) void; +export type fp_glTexEstimateMotionQCOM = fn(ref: uint, target: uint, output: uint) void; +export type fp_glTexEstimateMotionRegionsQCOM = fn(ref: uint, target: uint, output: uint, mask: uint) void; +export type fp_glTexImage2D = fn(target: gl_enum, level: i32, internalformat: i32, width: i32, height: i32, border: i32, format: gl_enum, type_: gl_enum, pixels: nullable *const opaque) void; +export type fp_glTexImage3D = fn(target: gl_enum, level: i32, internalformat: i32, width: i32, height: i32, depth: i32, border: i32, format: gl_enum, type_: gl_enum, pixels: nullable *const opaque) void; +export type fp_glTexImage3DOES = fn(target: gl_enum, level: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32, border: i32, format: gl_enum, type_: gl_enum, pixels: nullable *const opaque) void; +export type fp_glTexPageCommitmentEXT = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, commit: u8) void; +export type fp_glTexPageCommitmentMemNV = fn(target: gl_enum, layer: i32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, memory: uint, offset_: u64, commit: u8) void; +export type fp_glTexParameterIiv = fn(target: gl_enum, pname: gl_enum, params: nullable *const i32) void; +export type fp_glTexParameterIivEXT = fn(target: gl_enum, pname: gl_enum, params: nullable *const i32) void; +export type fp_glTexParameterIivOES = fn(target: gl_enum, pname: gl_enum, params: nullable *const i32) void; +export type fp_glTexParameterIuiv = fn(target: gl_enum, pname: gl_enum, params: nullable *const uint) void; +export type fp_glTexParameterIuivEXT = fn(target: gl_enum, pname: gl_enum, params: nullable *const uint) void; +export type fp_glTexParameterIuivOES = fn(target: gl_enum, pname: gl_enum, params: nullable *const uint) void; +export type fp_glTexParameterf = fn(target: gl_enum, pname: gl_enum, param: f32) void; +export type fp_glTexParameterfv = fn(target: gl_enum, pname: gl_enum, params: nullable *const f32) void; +export type fp_glTexParameteri = fn(target: gl_enum, pname: gl_enum, param: i32) void; +export type fp_glTexParameteriv = fn(target: gl_enum, pname: gl_enum, params: nullable *const i32) void; +export type fp_glTexStorage1DEXT = fn(target: gl_enum, levels: i32, internalformat: gl_enum, width: i32) void; +export type fp_glTexStorage2D = fn(target: gl_enum, levels: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glTexStorage2DEXT = fn(target: gl_enum, levels: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glTexStorage2DMultisample = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32, fixedsamplelocations: u8) void; +export type fp_glTexStorage3D = fn(target: gl_enum, levels: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32) void; +export type fp_glTexStorage3DEXT = fn(target: gl_enum, levels: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32) void; +export type fp_glTexStorage3DMultisample = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32, fixedsamplelocations: u8) void; +export type fp_glTexStorage3DMultisampleOES = fn(target: gl_enum, samples: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32, fixedsamplelocations: u8) void; +export type fp_glTexStorageAttribs2DEXT = fn(target: gl_enum, levels: i32, internalformat: gl_enum, width: i32, height: i32, attrib_list: nullable *const i32) void; +export type fp_glTexStorageAttribs3DEXT = fn(target: gl_enum, levels: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32, attrib_list: nullable *const i32) void; +export type fp_glTexStorageMem2DEXT = fn(target: gl_enum, levels: i32, internalFormat: gl_enum, width: i32, height: i32, memory: uint, offset_: u64) void; +export type fp_glTexStorageMem2DMultisampleEXT = fn(target: gl_enum, samples: i32, internalFormat: gl_enum, width: i32, height: i32, fixedSampleLocations: u8, memory: uint, offset_: u64) void; +export type fp_glTexStorageMem3DEXT = fn(target: gl_enum, levels: i32, internalFormat: gl_enum, width: i32, height: i32, depth: i32, memory: uint, offset_: u64) void; +export type fp_glTexStorageMem3DMultisampleEXT = fn(target: gl_enum, samples: i32, internalFormat: gl_enum, width: i32, height: i32, depth: i32, fixedSampleLocations: u8, memory: uint, offset_: u64) void; +export type fp_glTexSubImage2D = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, width: i32, height: i32, format: gl_enum, type_: gl_enum, pixels: nullable *const opaque) void; +export type fp_glTexSubImage3D = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: gl_enum, type_: gl_enum, pixels: nullable *const opaque) void; +export type fp_glTexSubImage3DOES = fn(target: gl_enum, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: gl_enum, type_: gl_enum, pixels: nullable *const opaque) void; +export type fp_glTextureAttachMemoryNV = fn(texture: uint, memory: uint, offset_: u64) void; +export type fp_glTextureFoveationParametersQCOM = fn(texture: uint, layer: uint, focalPoint: uint, focalX: f32, focalY: f32, gainX: f32, gainY: f32, foveaArea: f32) void; +export type fp_glTexturePageCommitmentMemNV = fn(texture: uint, layer: i32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, memory: uint, offset_: u64, commit: u8) void; +export type fp_glTextureStorage1DEXT = fn(texture: uint, target: gl_enum, levels: i32, internalformat: gl_enum, width: i32) void; +export type fp_glTextureStorage2DEXT = fn(texture: uint, target: gl_enum, levels: i32, internalformat: gl_enum, width: i32, height: i32) void; +export type fp_glTextureStorage3DEXT = fn(texture: uint, target: gl_enum, levels: i32, internalformat: gl_enum, width: i32, height: i32, depth: i32) void; +export type fp_glTextureStorageMem2DEXT = fn(texture: uint, levels: i32, internalFormat: gl_enum, width: i32, height: i32, memory: uint, offset_: u64) void; +export type fp_glTextureStorageMem2DMultisampleEXT = fn(texture: uint, samples: i32, internalFormat: gl_enum, width: i32, height: i32, fixedSampleLocations: u8, memory: uint, offset_: u64) void; +export type fp_glTextureStorageMem3DEXT = fn(texture: uint, levels: i32, internalFormat: gl_enum, width: i32, height: i32, depth: i32, memory: uint, offset_: u64) void; +export type fp_glTextureStorageMem3DMultisampleEXT = fn(texture: uint, samples: i32, internalFormat: gl_enum, width: i32, height: i32, depth: i32, fixedSampleLocations: u8, memory: uint, offset_: u64) void; +export type fp_glTextureViewEXT = fn(texture: uint, target: gl_enum, origtexture: uint, internalformat: gl_enum, minlevel: uint, numlevels: uint, minlayer: uint, numlayers: uint) void; +export type fp_glTextureViewOES = fn(texture: uint, target: gl_enum, origtexture: uint, internalformat: gl_enum, minlevel: uint, numlevels: uint, minlayer: uint, numlayers: uint) void; +export type fp_glTransformFeedbackVaryings = fn(program: uint, count: i32, varyings: nullable *const nullable *const i8, bufferMode: gl_enum) void; +export type fp_glTransformPathNV = fn(resultPath: uint, srcPath: uint, transformType: gl_enum, transformValues: nullable *const f32) void; +export type fp_glUniform1f = fn(location: i32, v0: f32) void; +export type fp_glUniform1fv = fn(location: i32, count: i32, value: nullable *const f32) void; +export type fp_glUniform1i = fn(location: i32, v0: i32) void; +export type fp_glUniform1i64NV = fn(location: i32, x: i64) void; +export type fp_glUniform1i64vNV = fn(location: i32, count: i32, value: nullable *const i64) void; +export type fp_glUniform1iv = fn(location: i32, count: i32, value: nullable *const i32) void; +export type fp_glUniform1ui = fn(location: i32, v0: uint) void; +export type fp_glUniform1ui64NV = fn(location: i32, x: u64) void; +export type fp_glUniform1ui64vNV = fn(location: i32, count: i32, value: nullable *const u64) void; +export type fp_glUniform1uiv = fn(location: i32, count: i32, value: nullable *const uint) void; +export type fp_glUniform2f = fn(location: i32, v0: f32, v1: f32) void; +export type fp_glUniform2fv = fn(location: i32, count: i32, value: nullable *const f32) void; +export type fp_glUniform2i = fn(location: i32, v0: i32, v1: i32) void; +export type fp_glUniform2i64NV = fn(location: i32, x: i64, y: i64) void; +export type fp_glUniform2i64vNV = fn(location: i32, count: i32, value: nullable *const i64) void; +export type fp_glUniform2iv = fn(location: i32, count: i32, value: nullable *const i32) void; +export type fp_glUniform2ui = fn(location: i32, v0: uint, v1: uint) void; +export type fp_glUniform2ui64NV = fn(location: i32, x: u64, y: u64) void; +export type fp_glUniform2ui64vNV = fn(location: i32, count: i32, value: nullable *const u64) void; +export type fp_glUniform2uiv = fn(location: i32, count: i32, value: nullable *const uint) void; +export type fp_glUniform3f = fn(location: i32, v0: f32, v1: f32, v2: f32) void; +export type fp_glUniform3fv = fn(location: i32, count: i32, value: nullable *const f32) void; +export type fp_glUniform3i = fn(location: i32, v0: i32, v1: i32, v2: i32) void; +export type fp_glUniform3i64NV = fn(location: i32, x: i64, y: i64, z: i64) void; +export type fp_glUniform3i64vNV = fn(location: i32, count: i32, value: nullable *const i64) void; +export type fp_glUniform3iv = fn(location: i32, count: i32, value: nullable *const i32) void; +export type fp_glUniform3ui = fn(location: i32, v0: uint, v1: uint, v2: uint) void; +export type fp_glUniform3ui64NV = fn(location: i32, x: u64, y: u64, z: u64) void; +export type fp_glUniform3ui64vNV = fn(location: i32, count: i32, value: nullable *const u64) void; +export type fp_glUniform3uiv = fn(location: i32, count: i32, value: nullable *const uint) void; +export type fp_glUniform4f = fn(location: i32, v0: f32, v1: f32, v2: f32, v3: f32) void; +export type fp_glUniform4fv = fn(location: i32, count: i32, value: nullable *const f32) void; +export type fp_glUniform4i = fn(location: i32, v0: i32, v1: i32, v2: i32, v3: i32) void; +export type fp_glUniform4i64NV = fn(location: i32, x: i64, y: i64, z: i64, w: i64) void; +export type fp_glUniform4i64vNV = fn(location: i32, count: i32, value: nullable *const i64) void; +export type fp_glUniform4iv = fn(location: i32, count: i32, value: nullable *const i32) void; +export type fp_glUniform4ui = fn(location: i32, v0: uint, v1: uint, v2: uint, v3: uint) void; +export type fp_glUniform4ui64NV = fn(location: i32, x: u64, y: u64, z: u64, w: u64) void; +export type fp_glUniform4ui64vNV = fn(location: i32, count: i32, value: nullable *const u64) void; +export type fp_glUniform4uiv = fn(location: i32, count: i32, value: nullable *const uint) void; +export type fp_glUniformBlockBinding = fn(program: uint, uniformBlockIndex: uint, uniformBlockBinding: uint) void; +export type fp_glUniformHandleui64IMG = fn(location: i32, value: u64) void; +export type fp_glUniformHandleui64NV = fn(location: i32, value: u64) void; +export type fp_glUniformHandleui64vIMG = fn(location: i32, count: i32, value: nullable *const u64) void; +export type fp_glUniformHandleui64vNV = fn(location: i32, count: i32, value: nullable *const u64) void; +export type fp_glUniformMatrix2fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix2x3fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix2x3fvNV = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix2x4fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix2x4fvNV = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix3fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix3x2fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix3x2fvNV = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix3x4fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix3x4fvNV = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix4fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix4x2fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix4x2fvNV = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix4x3fv = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUniformMatrix4x3fvNV = fn(location: i32, count: i32, transpose: u8, value: nullable *const f32) void; +export type fp_glUnmapBuffer = fn(target: gl_enum) u8; +export type fp_glUnmapBufferOES = fn(target: gl_enum) u8; +export type fp_glUseProgram = fn(program: uint) void; +export type fp_glUseProgramStages = fn(pipeline: uint, stages: gl_bitfield, program: uint) void; +export type fp_glUseProgramStagesEXT = fn(pipeline: uint, stages: gl_bitfield, program: uint) void; +export type fp_glValidateProgram = fn(program: uint) void; +export type fp_glValidateProgramPipeline = fn(pipeline: uint) void; +export type fp_glValidateProgramPipelineEXT = fn(pipeline: uint) void; +export type fp_glVertexAttrib1f = fn(index: uint, x: f32) void; +export type fp_glVertexAttrib1fv = fn(index: uint, v: nullable *const f32) void; +export type fp_glVertexAttrib2f = fn(index: uint, x: f32, y: f32) void; +export type fp_glVertexAttrib2fv = fn(index: uint, v: nullable *const f32) void; +export type fp_glVertexAttrib3f = fn(index: uint, x: f32, y: f32, z: f32) void; +export type fp_glVertexAttrib3fv = fn(index: uint, v: nullable *const f32) void; +export type fp_glVertexAttrib4f = fn(index: uint, x: f32, y: f32, z: f32, w: f32) void; +export type fp_glVertexAttrib4fv = fn(index: uint, v: nullable *const f32) void; +export type fp_glVertexAttribBinding = fn(attribindex: uint, bindingindex: uint) void; +export type fp_glVertexAttribDivisor = fn(index: uint, divisor: uint) void; +export type fp_glVertexAttribDivisorANGLE = fn(index: uint, divisor: uint) void; +export type fp_glVertexAttribDivisorEXT = fn(index: uint, divisor: uint) void; +export type fp_glVertexAttribDivisorNV = fn(index: uint, divisor: uint) void; +export type fp_glVertexAttribFormat = fn(attribindex: uint, size_: i32, type_: gl_enum, normalized: u8, relativeoffset: uint) void; +export type fp_glVertexAttribI4i = fn(index: uint, x: i32, y: i32, z: i32, w: i32) void; +export type fp_glVertexAttribI4iv = fn(index: uint, v: nullable *const i32) void; +export type fp_glVertexAttribI4ui = fn(index: uint, x: uint, y: uint, z: uint, w: uint) void; +export type fp_glVertexAttribI4uiv = fn(index: uint, v: nullable *const uint) void; +export type fp_glVertexAttribIFormat = fn(attribindex: uint, size_: i32, type_: gl_enum, relativeoffset: uint) void; +export type fp_glVertexAttribIPointer = fn(index: uint, size_: i32, type_: gl_enum, stride: i32, pointer: nullable *const opaque) void; +export type fp_glVertexAttribPointer = fn(index: uint, size_: i32, type_: gl_enum, normalized: u8, stride: i32, pointer: nullable *const opaque) void; +export type fp_glVertexBindingDivisor = fn(bindingindex: uint, divisor: uint) void; +export type fp_glViewport = fn(x: i32, y: i32, width: i32, height: i32) void; +export type fp_glViewportArrayvNV = fn(first: uint, count: i32, v: nullable *const f32) void; +export type fp_glViewportArrayvOES = fn(first: uint, count: i32, v: nullable *const f32) void; +export type fp_glViewportIndexedfNV = fn(index: uint, x: f32, y: f32, w: f32, h: f32) void; +export type fp_glViewportIndexedfOES = fn(index: uint, x: f32, y: f32, w: f32, h: f32) void; +export type fp_glViewportIndexedfvNV = fn(index: uint, v: nullable *const f32) void; +export type fp_glViewportIndexedfvOES = fn(index: uint, v: nullable *const f32) void; +export type fp_glViewportPositionWScaleNV = fn(index: uint, xcoeff: f32, ycoeff: f32) void; +export type fp_glViewportSwizzleNV = fn(index: uint, swizzlex: gl_enum, swizzley: gl_enum, swizzlez: gl_enum, swizzlew: gl_enum) void; +export type fp_glWaitSemaphoreEXT = fn(semaphore: uint, numBufferBarriers: uint, buffers: nullable *const uint, numTextureBarriers: uint, textures: nullable *const uint, srcLayouts: nullable *const gl_enum) void; +export type fp_glWaitSync = fn(sync: size, flags: gl_bitfield, timeout: u64) void; +export type fp_glWaitSyncAPPLE = fn(sync: size, flags: gl_bitfield, timeout: u64) void; +export type fp_glWaitVkSemaphoreNV = fn(vkSemaphore: u64) void; +export type fp_glWeightPathsNV = fn(resultPath: uint, numPaths: i32, paths: nullable *const uint, weights: nullable *const f32) void; +export type fp_glWindowRectanglesEXT = fn(mode: gl_enum, count: i32, box: nullable *const i32) void; + +// Functions +export let glAcquireKeyedMutexWin32EXT: *fp_glAcquireKeyedMutexWin32EXT = +	null: *fp_glAcquireKeyedMutexWin32EXT; +export let glActiveShaderProgram: *fp_glActiveShaderProgram = +	null: *fp_glActiveShaderProgram; +export let glActiveShaderProgramEXT: *fp_glActiveShaderProgramEXT = +	null: *fp_glActiveShaderProgramEXT; +export let glActiveTexture: *fp_glActiveTexture = +	null: *fp_glActiveTexture; +export let glAlphaFuncQCOM: *fp_glAlphaFuncQCOM = +	null: *fp_glAlphaFuncQCOM; +export let glApplyFramebufferAttachmentCMAAINTEL: *fp_glApplyFramebufferAttachmentCMAAINTEL = +	null: *fp_glApplyFramebufferAttachmentCMAAINTEL; +export let glAttachShader: *fp_glAttachShader = +	null: *fp_glAttachShader; +export let glBeginConditionalRenderNV: *fp_glBeginConditionalRenderNV = +	null: *fp_glBeginConditionalRenderNV; +export let glBeginPerfMonitorAMD: *fp_glBeginPerfMonitorAMD = +	null: *fp_glBeginPerfMonitorAMD; +export let glBeginPerfQueryINTEL: *fp_glBeginPerfQueryINTEL = +	null: *fp_glBeginPerfQueryINTEL; +export let glBeginQuery: *fp_glBeginQuery = +	null: *fp_glBeginQuery; +export let glBeginQueryEXT: *fp_glBeginQueryEXT = +	null: *fp_glBeginQueryEXT; +export let glBeginTransformFeedback: *fp_glBeginTransformFeedback = +	null: *fp_glBeginTransformFeedback; +export let glBindAttribLocation: *fp_glBindAttribLocation = +	null: *fp_glBindAttribLocation; +export let glBindBuffer: *fp_glBindBuffer = +	null: *fp_glBindBuffer; +export let glBindBufferBase: *fp_glBindBufferBase = +	null: *fp_glBindBufferBase; +export let glBindBufferRange: *fp_glBindBufferRange = +	null: *fp_glBindBufferRange; +export let glBindFragDataLocationEXT: *fp_glBindFragDataLocationEXT = +	null: *fp_glBindFragDataLocationEXT; +export let glBindFragDataLocationIndexedEXT: *fp_glBindFragDataLocationIndexedEXT = +	null: *fp_glBindFragDataLocationIndexedEXT; +export let glBindFramebuffer: *fp_glBindFramebuffer = +	null: *fp_glBindFramebuffer; +export let glBindImageTexture: *fp_glBindImageTexture = +	null: *fp_glBindImageTexture; +export let glBindProgramPipeline: *fp_glBindProgramPipeline = +	null: *fp_glBindProgramPipeline; +export let glBindProgramPipelineEXT: *fp_glBindProgramPipelineEXT = +	null: *fp_glBindProgramPipelineEXT; +export let glBindRenderbuffer: *fp_glBindRenderbuffer = +	null: *fp_glBindRenderbuffer; +export let glBindSampler: *fp_glBindSampler = +	null: *fp_glBindSampler; +export let glBindShadingRateImageNV: *fp_glBindShadingRateImageNV = +	null: *fp_glBindShadingRateImageNV; +export let glBindTexture: *fp_glBindTexture = +	null: *fp_glBindTexture; +export let glBindTransformFeedback: *fp_glBindTransformFeedback = +	null: *fp_glBindTransformFeedback; +export let glBindVertexArray: *fp_glBindVertexArray = +	null: *fp_glBindVertexArray; +export let glBindVertexArrayOES: *fp_glBindVertexArrayOES = +	null: *fp_glBindVertexArrayOES; +export let glBindVertexBuffer: *fp_glBindVertexBuffer = +	null: *fp_glBindVertexBuffer; +export let glBlendBarrier: *fp_glBlendBarrier = +	null: *fp_glBlendBarrier; +export let glBlendBarrierKHR: *fp_glBlendBarrierKHR = +	null: *fp_glBlendBarrierKHR; +export let glBlendBarrierNV: *fp_glBlendBarrierNV = +	null: *fp_glBlendBarrierNV; +export let glBlendColor: *fp_glBlendColor = +	null: *fp_glBlendColor; +export let glBlendEquation: *fp_glBlendEquation = +	null: *fp_glBlendEquation; +export let glBlendEquationSeparate: *fp_glBlendEquationSeparate = +	null: *fp_glBlendEquationSeparate; +export let glBlendEquationSeparatei: *fp_glBlendEquationSeparatei = +	null: *fp_glBlendEquationSeparatei; +export let glBlendEquationSeparateiEXT: *fp_glBlendEquationSeparateiEXT = +	null: *fp_glBlendEquationSeparateiEXT; +export let glBlendEquationSeparateiOES: *fp_glBlendEquationSeparateiOES = +	null: *fp_glBlendEquationSeparateiOES; +export let glBlendEquationi: *fp_glBlendEquationi = +	null: *fp_glBlendEquationi; +export let glBlendEquationiEXT: *fp_glBlendEquationiEXT = +	null: *fp_glBlendEquationiEXT; +export let glBlendEquationiOES: *fp_glBlendEquationiOES = +	null: *fp_glBlendEquationiOES; +export let glBlendFunc: *fp_glBlendFunc = +	null: *fp_glBlendFunc; +export let glBlendFuncSeparate: *fp_glBlendFuncSeparate = +	null: *fp_glBlendFuncSeparate; +export let glBlendFuncSeparatei: *fp_glBlendFuncSeparatei = +	null: *fp_glBlendFuncSeparatei; +export let glBlendFuncSeparateiEXT: *fp_glBlendFuncSeparateiEXT = +	null: *fp_glBlendFuncSeparateiEXT; +export let glBlendFuncSeparateiOES: *fp_glBlendFuncSeparateiOES = +	null: *fp_glBlendFuncSeparateiOES; +export let glBlendFunci: *fp_glBlendFunci = +	null: *fp_glBlendFunci; +export let glBlendFunciEXT: *fp_glBlendFunciEXT = +	null: *fp_glBlendFunciEXT; +export let glBlendFunciOES: *fp_glBlendFunciOES = +	null: *fp_glBlendFunciOES; +export let glBlendParameteriNV: *fp_glBlendParameteriNV = +	null: *fp_glBlendParameteriNV; +export let glBlitFramebuffer: *fp_glBlitFramebuffer = +	null: *fp_glBlitFramebuffer; +export let glBlitFramebufferANGLE: *fp_glBlitFramebufferANGLE = +	null: *fp_glBlitFramebufferANGLE; +export let glBlitFramebufferNV: *fp_glBlitFramebufferNV = +	null: *fp_glBlitFramebufferNV; +export let glBufferAttachMemoryNV: *fp_glBufferAttachMemoryNV = +	null: *fp_glBufferAttachMemoryNV; +export let glBufferData: *fp_glBufferData = +	null: *fp_glBufferData; +export let glBufferPageCommitmentMemNV: *fp_glBufferPageCommitmentMemNV = +	null: *fp_glBufferPageCommitmentMemNV; +export let glBufferStorageEXT: *fp_glBufferStorageEXT = +	null: *fp_glBufferStorageEXT; +export let glBufferStorageExternalEXT: *fp_glBufferStorageExternalEXT = +	null: *fp_glBufferStorageExternalEXT; +export let glBufferStorageMemEXT: *fp_glBufferStorageMemEXT = +	null: *fp_glBufferStorageMemEXT; +export let glBufferSubData: *fp_glBufferSubData = +	null: *fp_glBufferSubData; +export let glCheckFramebufferStatus: *fp_glCheckFramebufferStatus = +	null: *fp_glCheckFramebufferStatus; +export let glClear: *fp_glClear = +	null: *fp_glClear; +export let glClearBufferfi: *fp_glClearBufferfi = +	null: *fp_glClearBufferfi; +export let glClearBufferfv: *fp_glClearBufferfv = +	null: *fp_glClearBufferfv; +export let glClearBufferiv: *fp_glClearBufferiv = +	null: *fp_glClearBufferiv; +export let glClearBufferuiv: *fp_glClearBufferuiv = +	null: *fp_glClearBufferuiv; +export let glClearColor: *fp_glClearColor = +	null: *fp_glClearColor; +export let glClearDepthf: *fp_glClearDepthf = +	null: *fp_glClearDepthf; +export let glClearPixelLocalStorageuiEXT: *fp_glClearPixelLocalStorageuiEXT = +	null: *fp_glClearPixelLocalStorageuiEXT; +export let glClearStencil: *fp_glClearStencil = +	null: *fp_glClearStencil; +export let glClearTexImageEXT: *fp_glClearTexImageEXT = +	null: *fp_glClearTexImageEXT; +export let glClearTexSubImageEXT: *fp_glClearTexSubImageEXT = +	null: *fp_glClearTexSubImageEXT; +export let glClientWaitSync: *fp_glClientWaitSync = +	null: *fp_glClientWaitSync; +export let glClientWaitSyncAPPLE: *fp_glClientWaitSyncAPPLE = +	null: *fp_glClientWaitSyncAPPLE; +export let glClipControlEXT: *fp_glClipControlEXT = +	null: *fp_glClipControlEXT; +export let glColorMask: *fp_glColorMask = +	null: *fp_glColorMask; +export let glColorMaski: *fp_glColorMaski = +	null: *fp_glColorMaski; +export let glColorMaskiEXT: *fp_glColorMaskiEXT = +	null: *fp_glColorMaskiEXT; +export let glColorMaskiOES: *fp_glColorMaskiOES = +	null: *fp_glColorMaskiOES; +export let glCompileShader: *fp_glCompileShader = +	null: *fp_glCompileShader; +export let glCompressedTexImage2D: *fp_glCompressedTexImage2D = +	null: *fp_glCompressedTexImage2D; +export let glCompressedTexImage3D: *fp_glCompressedTexImage3D = +	null: *fp_glCompressedTexImage3D; +export let glCompressedTexImage3DOES: *fp_glCompressedTexImage3DOES = +	null: *fp_glCompressedTexImage3DOES; +export let glCompressedTexSubImage2D: *fp_glCompressedTexSubImage2D = +	null: *fp_glCompressedTexSubImage2D; +export let glCompressedTexSubImage3D: *fp_glCompressedTexSubImage3D = +	null: *fp_glCompressedTexSubImage3D; +export let glCompressedTexSubImage3DOES: *fp_glCompressedTexSubImage3DOES = +	null: *fp_glCompressedTexSubImage3DOES; +export let glConservativeRasterParameteriNV: *fp_glConservativeRasterParameteriNV = +	null: *fp_glConservativeRasterParameteriNV; +export let glCopyBufferSubData: *fp_glCopyBufferSubData = +	null: *fp_glCopyBufferSubData; +export let glCopyBufferSubDataNV: *fp_glCopyBufferSubDataNV = +	null: *fp_glCopyBufferSubDataNV; +export let glCopyImageSubData: *fp_glCopyImageSubData = +	null: *fp_glCopyImageSubData; +export let glCopyImageSubDataEXT: *fp_glCopyImageSubDataEXT = +	null: *fp_glCopyImageSubDataEXT; +export let glCopyImageSubDataOES: *fp_glCopyImageSubDataOES = +	null: *fp_glCopyImageSubDataOES; +export let glCopyPathNV: *fp_glCopyPathNV = +	null: *fp_glCopyPathNV; +export let glCopyTexImage2D: *fp_glCopyTexImage2D = +	null: *fp_glCopyTexImage2D; +export let glCopyTexSubImage2D: *fp_glCopyTexSubImage2D = +	null: *fp_glCopyTexSubImage2D; +export let glCopyTexSubImage3D: *fp_glCopyTexSubImage3D = +	null: *fp_glCopyTexSubImage3D; +export let glCopyTexSubImage3DOES: *fp_glCopyTexSubImage3DOES = +	null: *fp_glCopyTexSubImage3DOES; +export let glCopyTextureLevelsAPPLE: *fp_glCopyTextureLevelsAPPLE = +	null: *fp_glCopyTextureLevelsAPPLE; +export let glCoverFillPathInstancedNV: *fp_glCoverFillPathInstancedNV = +	null: *fp_glCoverFillPathInstancedNV; +export let glCoverFillPathNV: *fp_glCoverFillPathNV = +	null: *fp_glCoverFillPathNV; +export let glCoverStrokePathInstancedNV: *fp_glCoverStrokePathInstancedNV = +	null: *fp_glCoverStrokePathInstancedNV; +export let glCoverStrokePathNV: *fp_glCoverStrokePathNV = +	null: *fp_glCoverStrokePathNV; +export let glCoverageMaskNV: *fp_glCoverageMaskNV = +	null: *fp_glCoverageMaskNV; +export let glCoverageModulationNV: *fp_glCoverageModulationNV = +	null: *fp_glCoverageModulationNV; +export let glCoverageModulationTableNV: *fp_glCoverageModulationTableNV = +	null: *fp_glCoverageModulationTableNV; +export let glCoverageOperationNV: *fp_glCoverageOperationNV = +	null: *fp_glCoverageOperationNV; +export let glCreateMemoryObjectsEXT: *fp_glCreateMemoryObjectsEXT = +	null: *fp_glCreateMemoryObjectsEXT; +export let glCreatePerfQueryINTEL: *fp_glCreatePerfQueryINTEL = +	null: *fp_glCreatePerfQueryINTEL; +export let glCreateProgram: *fp_glCreateProgram = +	null: *fp_glCreateProgram; +export let glCreateSemaphoresNV: *fp_glCreateSemaphoresNV = +	null: *fp_glCreateSemaphoresNV; +export let glCreateShader: *fp_glCreateShader = +	null: *fp_glCreateShader; +export let glCreateShaderProgramv: *fp_glCreateShaderProgramv = +	null: *fp_glCreateShaderProgramv; +export let glCreateShaderProgramvEXT: *fp_glCreateShaderProgramvEXT = +	null: *fp_glCreateShaderProgramvEXT; +export let glCullFace: *fp_glCullFace = +	null: *fp_glCullFace; +export let glDebugMessageCallback: *fp_glDebugMessageCallback = +	null: *fp_glDebugMessageCallback; +export let glDebugMessageCallbackKHR: *fp_glDebugMessageCallbackKHR = +	null: *fp_glDebugMessageCallbackKHR; +export let glDebugMessageControl: *fp_glDebugMessageControl = +	null: *fp_glDebugMessageControl; +export let glDebugMessageControlKHR: *fp_glDebugMessageControlKHR = +	null: *fp_glDebugMessageControlKHR; +export let glDebugMessageInsert: *fp_glDebugMessageInsert = +	null: *fp_glDebugMessageInsert; +export let glDebugMessageInsertKHR: *fp_glDebugMessageInsertKHR = +	null: *fp_glDebugMessageInsertKHR; +export let glDeleteBuffers: *fp_glDeleteBuffers = +	null: *fp_glDeleteBuffers; +export let glDeleteFencesNV: *fp_glDeleteFencesNV = +	null: *fp_glDeleteFencesNV; +export let glDeleteFramebuffers: *fp_glDeleteFramebuffers = +	null: *fp_glDeleteFramebuffers; +export let glDeleteMemoryObjectsEXT: *fp_glDeleteMemoryObjectsEXT = +	null: *fp_glDeleteMemoryObjectsEXT; +export let glDeletePathsNV: *fp_glDeletePathsNV = +	null: *fp_glDeletePathsNV; +export let glDeletePerfMonitorsAMD: *fp_glDeletePerfMonitorsAMD = +	null: *fp_glDeletePerfMonitorsAMD; +export let glDeletePerfQueryINTEL: *fp_glDeletePerfQueryINTEL = +	null: *fp_glDeletePerfQueryINTEL; +export let glDeleteProgram: *fp_glDeleteProgram = +	null: *fp_glDeleteProgram; +export let glDeleteProgramPipelines: *fp_glDeleteProgramPipelines = +	null: *fp_glDeleteProgramPipelines; +export let glDeleteProgramPipelinesEXT: *fp_glDeleteProgramPipelinesEXT = +	null: *fp_glDeleteProgramPipelinesEXT; +export let glDeleteQueries: *fp_glDeleteQueries = +	null: *fp_glDeleteQueries; +export let glDeleteQueriesEXT: *fp_glDeleteQueriesEXT = +	null: *fp_glDeleteQueriesEXT; +export let glDeleteRenderbuffers: *fp_glDeleteRenderbuffers = +	null: *fp_glDeleteRenderbuffers; +export let glDeleteSamplers: *fp_glDeleteSamplers = +	null: *fp_glDeleteSamplers; +export let glDeleteSemaphoresEXT: *fp_glDeleteSemaphoresEXT = +	null: *fp_glDeleteSemaphoresEXT; +export let glDeleteShader: *fp_glDeleteShader = +	null: *fp_glDeleteShader; +export let glDeleteSync: *fp_glDeleteSync = +	null: *fp_glDeleteSync; +export let glDeleteSyncAPPLE: *fp_glDeleteSyncAPPLE = +	null: *fp_glDeleteSyncAPPLE; +export let glDeleteTextures: *fp_glDeleteTextures = +	null: *fp_glDeleteTextures; +export let glDeleteTransformFeedbacks: *fp_glDeleteTransformFeedbacks = +	null: *fp_glDeleteTransformFeedbacks; +export let glDeleteVertexArrays: *fp_glDeleteVertexArrays = +	null: *fp_glDeleteVertexArrays; +export let glDeleteVertexArraysOES: *fp_glDeleteVertexArraysOES = +	null: *fp_glDeleteVertexArraysOES; +export let glDepthFunc: *fp_glDepthFunc = +	null: *fp_glDepthFunc; +export let glDepthMask: *fp_glDepthMask = +	null: *fp_glDepthMask; +export let glDepthRangeArrayfvNV: *fp_glDepthRangeArrayfvNV = +	null: *fp_glDepthRangeArrayfvNV; +export let glDepthRangeArrayfvOES: *fp_glDepthRangeArrayfvOES = +	null: *fp_glDepthRangeArrayfvOES; +export let glDepthRangeIndexedfNV: *fp_glDepthRangeIndexedfNV = +	null: *fp_glDepthRangeIndexedfNV; +export let glDepthRangeIndexedfOES: *fp_glDepthRangeIndexedfOES = +	null: *fp_glDepthRangeIndexedfOES; +export let glDepthRangef: *fp_glDepthRangef = +	null: *fp_glDepthRangef; +export let glDetachShader: *fp_glDetachShader = +	null: *fp_glDetachShader; +export let glDisable: *fp_glDisable = +	null: *fp_glDisable; +export let glDisableDriverControlQCOM: *fp_glDisableDriverControlQCOM = +	null: *fp_glDisableDriverControlQCOM; +export let glDisableVertexAttribArray: *fp_glDisableVertexAttribArray = +	null: *fp_glDisableVertexAttribArray; +export let glDisablei: *fp_glDisablei = +	null: *fp_glDisablei; +export let glDisableiEXT: *fp_glDisableiEXT = +	null: *fp_glDisableiEXT; +export let glDisableiNV: *fp_glDisableiNV = +	null: *fp_glDisableiNV; +export let glDisableiOES: *fp_glDisableiOES = +	null: *fp_glDisableiOES; +export let glDiscardFramebufferEXT: *fp_glDiscardFramebufferEXT = +	null: *fp_glDiscardFramebufferEXT; +export let glDispatchCompute: *fp_glDispatchCompute = +	null: *fp_glDispatchCompute; +export let glDispatchComputeIndirect: *fp_glDispatchComputeIndirect = +	null: *fp_glDispatchComputeIndirect; +export let glDrawArrays: *fp_glDrawArrays = +	null: *fp_glDrawArrays; +export let glDrawArraysIndirect: *fp_glDrawArraysIndirect = +	null: *fp_glDrawArraysIndirect; +export let glDrawArraysInstanced: *fp_glDrawArraysInstanced = +	null: *fp_glDrawArraysInstanced; +export let glDrawArraysInstancedANGLE: *fp_glDrawArraysInstancedANGLE = +	null: *fp_glDrawArraysInstancedANGLE; +export let glDrawArraysInstancedBaseInstanceEXT: *fp_glDrawArraysInstancedBaseInstanceEXT = +	null: *fp_glDrawArraysInstancedBaseInstanceEXT; +export let glDrawArraysInstancedEXT: *fp_glDrawArraysInstancedEXT = +	null: *fp_glDrawArraysInstancedEXT; +export let glDrawArraysInstancedNV: *fp_glDrawArraysInstancedNV = +	null: *fp_glDrawArraysInstancedNV; +export let glDrawBuffers: *fp_glDrawBuffers = +	null: *fp_glDrawBuffers; +export let glDrawBuffersEXT: *fp_glDrawBuffersEXT = +	null: *fp_glDrawBuffersEXT; +export let glDrawBuffersIndexedEXT: *fp_glDrawBuffersIndexedEXT = +	null: *fp_glDrawBuffersIndexedEXT; +export let glDrawBuffersNV: *fp_glDrawBuffersNV = +	null: *fp_glDrawBuffersNV; +export let glDrawElements: *fp_glDrawElements = +	null: *fp_glDrawElements; +export let glDrawElementsBaseVertex: *fp_glDrawElementsBaseVertex = +	null: *fp_glDrawElementsBaseVertex; +export let glDrawElementsBaseVertexEXT: *fp_glDrawElementsBaseVertexEXT = +	null: *fp_glDrawElementsBaseVertexEXT; +export let glDrawElementsBaseVertexOES: *fp_glDrawElementsBaseVertexOES = +	null: *fp_glDrawElementsBaseVertexOES; +export let glDrawElementsIndirect: *fp_glDrawElementsIndirect = +	null: *fp_glDrawElementsIndirect; +export let glDrawElementsInstanced: *fp_glDrawElementsInstanced = +	null: *fp_glDrawElementsInstanced; +export let glDrawElementsInstancedANGLE: *fp_glDrawElementsInstancedANGLE = +	null: *fp_glDrawElementsInstancedANGLE; +export let glDrawElementsInstancedBaseInstanceEXT: *fp_glDrawElementsInstancedBaseInstanceEXT = +	null: *fp_glDrawElementsInstancedBaseInstanceEXT; +export let glDrawElementsInstancedBaseVertex: *fp_glDrawElementsInstancedBaseVertex = +	null: *fp_glDrawElementsInstancedBaseVertex; +export let glDrawElementsInstancedBaseVertexBaseInstanceEXT: *fp_glDrawElementsInstancedBaseVertexBaseInstanceEXT = +	null: *fp_glDrawElementsInstancedBaseVertexBaseInstanceEXT; +export let glDrawElementsInstancedBaseVertexEXT: *fp_glDrawElementsInstancedBaseVertexEXT = +	null: *fp_glDrawElementsInstancedBaseVertexEXT; +export let glDrawElementsInstancedBaseVertexOES: *fp_glDrawElementsInstancedBaseVertexOES = +	null: *fp_glDrawElementsInstancedBaseVertexOES; +export let glDrawElementsInstancedEXT: *fp_glDrawElementsInstancedEXT = +	null: *fp_glDrawElementsInstancedEXT; +export let glDrawElementsInstancedNV: *fp_glDrawElementsInstancedNV = +	null: *fp_glDrawElementsInstancedNV; +export let glDrawMeshTasksIndirectNV: *fp_glDrawMeshTasksIndirectNV = +	null: *fp_glDrawMeshTasksIndirectNV; +export let glDrawMeshTasksNV: *fp_glDrawMeshTasksNV = +	null: *fp_glDrawMeshTasksNV; +export let glDrawRangeElements: *fp_glDrawRangeElements = +	null: *fp_glDrawRangeElements; +export let glDrawRangeElementsBaseVertex: *fp_glDrawRangeElementsBaseVertex = +	null: *fp_glDrawRangeElementsBaseVertex; +export let glDrawRangeElementsBaseVertexEXT: *fp_glDrawRangeElementsBaseVertexEXT = +	null: *fp_glDrawRangeElementsBaseVertexEXT; +export let glDrawRangeElementsBaseVertexOES: *fp_glDrawRangeElementsBaseVertexOES = +	null: *fp_glDrawRangeElementsBaseVertexOES; +export let glDrawTransformFeedbackEXT: *fp_glDrawTransformFeedbackEXT = +	null: *fp_glDrawTransformFeedbackEXT; +export let glDrawTransformFeedbackInstancedEXT: *fp_glDrawTransformFeedbackInstancedEXT = +	null: *fp_glDrawTransformFeedbackInstancedEXT; +export let glDrawVkImageNV: *fp_glDrawVkImageNV = +	null: *fp_glDrawVkImageNV; +export let glEGLImageTargetRenderbufferStorageOES: *fp_glEGLImageTargetRenderbufferStorageOES = +	null: *fp_glEGLImageTargetRenderbufferStorageOES; +export let glEGLImageTargetTexStorageEXT: *fp_glEGLImageTargetTexStorageEXT = +	null: *fp_glEGLImageTargetTexStorageEXT; +export let glEGLImageTargetTexture2DOES: *fp_glEGLImageTargetTexture2DOES = +	null: *fp_glEGLImageTargetTexture2DOES; +export let glEGLImageTargetTextureStorageEXT: *fp_glEGLImageTargetTextureStorageEXT = +	null: *fp_glEGLImageTargetTextureStorageEXT; +export let glEnable: *fp_glEnable = +	null: *fp_glEnable; +export let glEnableDriverControlQCOM: *fp_glEnableDriverControlQCOM = +	null: *fp_glEnableDriverControlQCOM; +export let glEnableVertexAttribArray: *fp_glEnableVertexAttribArray = +	null: *fp_glEnableVertexAttribArray; +export let glEnablei: *fp_glEnablei = +	null: *fp_glEnablei; +export let glEnableiEXT: *fp_glEnableiEXT = +	null: *fp_glEnableiEXT; +export let glEnableiNV: *fp_glEnableiNV = +	null: *fp_glEnableiNV; +export let glEnableiOES: *fp_glEnableiOES = +	null: *fp_glEnableiOES; +export let glEndConditionalRenderNV: *fp_glEndConditionalRenderNV = +	null: *fp_glEndConditionalRenderNV; +export let glEndPerfMonitorAMD: *fp_glEndPerfMonitorAMD = +	null: *fp_glEndPerfMonitorAMD; +export let glEndPerfQueryINTEL: *fp_glEndPerfQueryINTEL = +	null: *fp_glEndPerfQueryINTEL; +export let glEndQuery: *fp_glEndQuery = +	null: *fp_glEndQuery; +export let glEndQueryEXT: *fp_glEndQueryEXT = +	null: *fp_glEndQueryEXT; +export let glEndTilingQCOM: *fp_glEndTilingQCOM = +	null: *fp_glEndTilingQCOM; +export let glEndTransformFeedback: *fp_glEndTransformFeedback = +	null: *fp_glEndTransformFeedback; +export let glExtGetBufferPointervQCOM: *fp_glExtGetBufferPointervQCOM = +	null: *fp_glExtGetBufferPointervQCOM; +export let glExtGetBuffersQCOM: *fp_glExtGetBuffersQCOM = +	null: *fp_glExtGetBuffersQCOM; +export let glExtGetFramebuffersQCOM: *fp_glExtGetFramebuffersQCOM = +	null: *fp_glExtGetFramebuffersQCOM; +export let glExtGetProgramBinarySourceQCOM: *fp_glExtGetProgramBinarySourceQCOM = +	null: *fp_glExtGetProgramBinarySourceQCOM; +export let glExtGetProgramsQCOM: *fp_glExtGetProgramsQCOM = +	null: *fp_glExtGetProgramsQCOM; +export let glExtGetRenderbuffersQCOM: *fp_glExtGetRenderbuffersQCOM = +	null: *fp_glExtGetRenderbuffersQCOM; +export let glExtGetShadersQCOM: *fp_glExtGetShadersQCOM = +	null: *fp_glExtGetShadersQCOM; +export let glExtGetTexLevelParameterivQCOM: *fp_glExtGetTexLevelParameterivQCOM = +	null: *fp_glExtGetTexLevelParameterivQCOM; +export let glExtGetTexSubImageQCOM: *fp_glExtGetTexSubImageQCOM = +	null: *fp_glExtGetTexSubImageQCOM; +export let glExtGetTexturesQCOM: *fp_glExtGetTexturesQCOM = +	null: *fp_glExtGetTexturesQCOM; +export let glExtIsProgramBinaryQCOM: *fp_glExtIsProgramBinaryQCOM = +	null: *fp_glExtIsProgramBinaryQCOM; +export let glExtTexObjectStateOverrideiQCOM: *fp_glExtTexObjectStateOverrideiQCOM = +	null: *fp_glExtTexObjectStateOverrideiQCOM; +export let glExtrapolateTex2DQCOM: *fp_glExtrapolateTex2DQCOM = +	null: *fp_glExtrapolateTex2DQCOM; +export let glFenceSync: *fp_glFenceSync = +	null: *fp_glFenceSync; +export let glFenceSyncAPPLE: *fp_glFenceSyncAPPLE = +	null: *fp_glFenceSyncAPPLE; +export let glFinish: *fp_glFinish = +	null: *fp_glFinish; +export let glFinishFenceNV: *fp_glFinishFenceNV = +	null: *fp_glFinishFenceNV; +export let glFlush: *fp_glFlush = +	null: *fp_glFlush; +export let glFlushMappedBufferRange: *fp_glFlushMappedBufferRange = +	null: *fp_glFlushMappedBufferRange; +export let glFlushMappedBufferRangeEXT: *fp_glFlushMappedBufferRangeEXT = +	null: *fp_glFlushMappedBufferRangeEXT; +export let glFragmentCoverageColorNV: *fp_glFragmentCoverageColorNV = +	null: *fp_glFragmentCoverageColorNV; +export let glFramebufferFetchBarrierEXT: *fp_glFramebufferFetchBarrierEXT = +	null: *fp_glFramebufferFetchBarrierEXT; +export let glFramebufferFetchBarrierQCOM: *fp_glFramebufferFetchBarrierQCOM = +	null: *fp_glFramebufferFetchBarrierQCOM; +export let glFramebufferFoveationConfigQCOM: *fp_glFramebufferFoveationConfigQCOM = +	null: *fp_glFramebufferFoveationConfigQCOM; +export let glFramebufferFoveationParametersQCOM: *fp_glFramebufferFoveationParametersQCOM = +	null: *fp_glFramebufferFoveationParametersQCOM; +export let glFramebufferParameteri: *fp_glFramebufferParameteri = +	null: *fp_glFramebufferParameteri; +export let glFramebufferParameteriMESA: *fp_glFramebufferParameteriMESA = +	null: *fp_glFramebufferParameteriMESA; +export let glFramebufferPixelLocalStorageSizeEXT: *fp_glFramebufferPixelLocalStorageSizeEXT = +	null: *fp_glFramebufferPixelLocalStorageSizeEXT; +export let glFramebufferRenderbuffer: *fp_glFramebufferRenderbuffer = +	null: *fp_glFramebufferRenderbuffer; +export let glFramebufferSampleLocationsfvNV: *fp_glFramebufferSampleLocationsfvNV = +	null: *fp_glFramebufferSampleLocationsfvNV; +export let glFramebufferShadingRateEXT: *fp_glFramebufferShadingRateEXT = +	null: *fp_glFramebufferShadingRateEXT; +export let glFramebufferTexture: *fp_glFramebufferTexture = +	null: *fp_glFramebufferTexture; +export let glFramebufferTexture2D: *fp_glFramebufferTexture2D = +	null: *fp_glFramebufferTexture2D; +export let glFramebufferTexture2DDownsampleIMG: *fp_glFramebufferTexture2DDownsampleIMG = +	null: *fp_glFramebufferTexture2DDownsampleIMG; +export let glFramebufferTexture2DMultisampleEXT: *fp_glFramebufferTexture2DMultisampleEXT = +	null: *fp_glFramebufferTexture2DMultisampleEXT; +export let glFramebufferTexture2DMultisampleIMG: *fp_glFramebufferTexture2DMultisampleIMG = +	null: *fp_glFramebufferTexture2DMultisampleIMG; +export let glFramebufferTexture3DOES: *fp_glFramebufferTexture3DOES = +	null: *fp_glFramebufferTexture3DOES; +export let glFramebufferTextureEXT: *fp_glFramebufferTextureEXT = +	null: *fp_glFramebufferTextureEXT; +export let glFramebufferTextureLayer: *fp_glFramebufferTextureLayer = +	null: *fp_glFramebufferTextureLayer; +export let glFramebufferTextureLayerDownsampleIMG: *fp_glFramebufferTextureLayerDownsampleIMG = +	null: *fp_glFramebufferTextureLayerDownsampleIMG; +export let glFramebufferTextureMultisampleMultiviewOVR: *fp_glFramebufferTextureMultisampleMultiviewOVR = +	null: *fp_glFramebufferTextureMultisampleMultiviewOVR; +export let glFramebufferTextureMultiviewOVR: *fp_glFramebufferTextureMultiviewOVR = +	null: *fp_glFramebufferTextureMultiviewOVR; +export let glFramebufferTextureOES: *fp_glFramebufferTextureOES = +	null: *fp_glFramebufferTextureOES; +export let glFrontFace: *fp_glFrontFace = +	null: *fp_glFrontFace; +export let glGenBuffers: *fp_glGenBuffers = +	null: *fp_glGenBuffers; +export let glGenFencesNV: *fp_glGenFencesNV = +	null: *fp_glGenFencesNV; +export let glGenFramebuffers: *fp_glGenFramebuffers = +	null: *fp_glGenFramebuffers; +export let glGenPathsNV: *fp_glGenPathsNV = +	null: *fp_glGenPathsNV; +export let glGenPerfMonitorsAMD: *fp_glGenPerfMonitorsAMD = +	null: *fp_glGenPerfMonitorsAMD; +export let glGenProgramPipelines: *fp_glGenProgramPipelines = +	null: *fp_glGenProgramPipelines; +export let glGenProgramPipelinesEXT: *fp_glGenProgramPipelinesEXT = +	null: *fp_glGenProgramPipelinesEXT; +export let glGenQueries: *fp_glGenQueries = +	null: *fp_glGenQueries; +export let glGenQueriesEXT: *fp_glGenQueriesEXT = +	null: *fp_glGenQueriesEXT; +export let glGenRenderbuffers: *fp_glGenRenderbuffers = +	null: *fp_glGenRenderbuffers; +export let glGenSamplers: *fp_glGenSamplers = +	null: *fp_glGenSamplers; +export let glGenSemaphoresEXT: *fp_glGenSemaphoresEXT = +	null: *fp_glGenSemaphoresEXT; +export let glGenTextures: *fp_glGenTextures = +	null: *fp_glGenTextures; +export let glGenTransformFeedbacks: *fp_glGenTransformFeedbacks = +	null: *fp_glGenTransformFeedbacks; +export let glGenVertexArrays: *fp_glGenVertexArrays = +	null: *fp_glGenVertexArrays; +export let glGenVertexArraysOES: *fp_glGenVertexArraysOES = +	null: *fp_glGenVertexArraysOES; +export let glGenerateMipmap: *fp_glGenerateMipmap = +	null: *fp_glGenerateMipmap; +export let glGetActiveAttrib: *fp_glGetActiveAttrib = +	null: *fp_glGetActiveAttrib; +export let glGetActiveUniform: *fp_glGetActiveUniform = +	null: *fp_glGetActiveUniform; +export let glGetActiveUniformBlockName: *fp_glGetActiveUniformBlockName = +	null: *fp_glGetActiveUniformBlockName; +export let glGetActiveUniformBlockiv: *fp_glGetActiveUniformBlockiv = +	null: *fp_glGetActiveUniformBlockiv; +export let glGetActiveUniformsiv: *fp_glGetActiveUniformsiv = +	null: *fp_glGetActiveUniformsiv; +export let glGetAttachedShaders: *fp_glGetAttachedShaders = +	null: *fp_glGetAttachedShaders; +export let glGetAttribLocation: *fp_glGetAttribLocation = +	null: *fp_glGetAttribLocation; +export let glGetBooleani_v: *fp_glGetBooleani_v = +	null: *fp_glGetBooleani_v; +export let glGetBooleanv: *fp_glGetBooleanv = +	null: *fp_glGetBooleanv; +export let glGetBufferParameteri64v: *fp_glGetBufferParameteri64v = +	null: *fp_glGetBufferParameteri64v; +export let glGetBufferParameteriv: *fp_glGetBufferParameteriv = +	null: *fp_glGetBufferParameteriv; +export let glGetBufferPointerv: *fp_glGetBufferPointerv = +	null: *fp_glGetBufferPointerv; +export let glGetBufferPointervOES: *fp_glGetBufferPointervOES = +	null: *fp_glGetBufferPointervOES; +export let glGetCoverageModulationTableNV: *fp_glGetCoverageModulationTableNV = +	null: *fp_glGetCoverageModulationTableNV; +export let glGetDebugMessageLog: *fp_glGetDebugMessageLog = +	null: *fp_glGetDebugMessageLog; +export let glGetDebugMessageLogKHR: *fp_glGetDebugMessageLogKHR = +	null: *fp_glGetDebugMessageLogKHR; +export let glGetDriverControlStringQCOM: *fp_glGetDriverControlStringQCOM = +	null: *fp_glGetDriverControlStringQCOM; +export let glGetDriverControlsQCOM: *fp_glGetDriverControlsQCOM = +	null: *fp_glGetDriverControlsQCOM; +export let glGetError: *fp_glGetError = +	null: *fp_glGetError; +export let glGetFenceivNV: *fp_glGetFenceivNV = +	null: *fp_glGetFenceivNV; +export let glGetFirstPerfQueryIdINTEL: *fp_glGetFirstPerfQueryIdINTEL = +	null: *fp_glGetFirstPerfQueryIdINTEL; +export let glGetFloati_vNV: *fp_glGetFloati_vNV = +	null: *fp_glGetFloati_vNV; +export let glGetFloati_vOES: *fp_glGetFloati_vOES = +	null: *fp_glGetFloati_vOES; +export let glGetFloatv: *fp_glGetFloatv = +	null: *fp_glGetFloatv; +export let glGetFragDataIndexEXT: *fp_glGetFragDataIndexEXT = +	null: *fp_glGetFragDataIndexEXT; +export let glGetFragDataLocation: *fp_glGetFragDataLocation = +	null: *fp_glGetFragDataLocation; +export let glGetFragmentShadingRatesEXT: *fp_glGetFragmentShadingRatesEXT = +	null: *fp_glGetFragmentShadingRatesEXT; +export let glGetFramebufferAttachmentParameteriv: *fp_glGetFramebufferAttachmentParameteriv = +	null: *fp_glGetFramebufferAttachmentParameteriv; +export let glGetFramebufferParameteriv: *fp_glGetFramebufferParameteriv = +	null: *fp_glGetFramebufferParameteriv; +export let glGetFramebufferParameterivMESA: *fp_glGetFramebufferParameterivMESA = +	null: *fp_glGetFramebufferParameterivMESA; +export let glGetFramebufferPixelLocalStorageSizeEXT: *fp_glGetFramebufferPixelLocalStorageSizeEXT = +	null: *fp_glGetFramebufferPixelLocalStorageSizeEXT; +export let glGetGraphicsResetStatus: *fp_glGetGraphicsResetStatus = +	null: *fp_glGetGraphicsResetStatus; +export let glGetGraphicsResetStatusEXT: *fp_glGetGraphicsResetStatusEXT = +	null: *fp_glGetGraphicsResetStatusEXT; +export let glGetGraphicsResetStatusKHR: *fp_glGetGraphicsResetStatusKHR = +	null: *fp_glGetGraphicsResetStatusKHR; +export let glGetImageHandleNV: *fp_glGetImageHandleNV = +	null: *fp_glGetImageHandleNV; +export let glGetInteger64i_v: *fp_glGetInteger64i_v = +	null: *fp_glGetInteger64i_v; +export let glGetInteger64v: *fp_glGetInteger64v = +	null: *fp_glGetInteger64v; +export let glGetInteger64vAPPLE: *fp_glGetInteger64vAPPLE = +	null: *fp_glGetInteger64vAPPLE; +export let glGetInteger64vEXT: *fp_glGetInteger64vEXT = +	null: *fp_glGetInteger64vEXT; +export let glGetIntegeri_v: *fp_glGetIntegeri_v = +	null: *fp_glGetIntegeri_v; +export let glGetIntegeri_vEXT: *fp_glGetIntegeri_vEXT = +	null: *fp_glGetIntegeri_vEXT; +export let glGetIntegerv: *fp_glGetIntegerv = +	null: *fp_glGetIntegerv; +export let glGetInternalformatSampleivNV: *fp_glGetInternalformatSampleivNV = +	null: *fp_glGetInternalformatSampleivNV; +export let glGetInternalformativ: *fp_glGetInternalformativ = +	null: *fp_glGetInternalformativ; +export let glGetMemoryObjectDetachedResourcesuivNV: *fp_glGetMemoryObjectDetachedResourcesuivNV = +	null: *fp_glGetMemoryObjectDetachedResourcesuivNV; +export let glGetMemoryObjectParameterivEXT: *fp_glGetMemoryObjectParameterivEXT = +	null: *fp_glGetMemoryObjectParameterivEXT; +export let glGetMultisamplefv: *fp_glGetMultisamplefv = +	null: *fp_glGetMultisamplefv; +export let glGetNextPerfQueryIdINTEL: *fp_glGetNextPerfQueryIdINTEL = +	null: *fp_glGetNextPerfQueryIdINTEL; +export let glGetObjectLabel: *fp_glGetObjectLabel = +	null: *fp_glGetObjectLabel; +export let glGetObjectLabelEXT: *fp_glGetObjectLabelEXT = +	null: *fp_glGetObjectLabelEXT; +export let glGetObjectLabelKHR: *fp_glGetObjectLabelKHR = +	null: *fp_glGetObjectLabelKHR; +export let glGetObjectPtrLabel: *fp_glGetObjectPtrLabel = +	null: *fp_glGetObjectPtrLabel; +export let glGetObjectPtrLabelKHR: *fp_glGetObjectPtrLabelKHR = +	null: *fp_glGetObjectPtrLabelKHR; +export let glGetPathCommandsNV: *fp_glGetPathCommandsNV = +	null: *fp_glGetPathCommandsNV; +export let glGetPathCoordsNV: *fp_glGetPathCoordsNV = +	null: *fp_glGetPathCoordsNV; +export let glGetPathDashArrayNV: *fp_glGetPathDashArrayNV = +	null: *fp_glGetPathDashArrayNV; +export let glGetPathLengthNV: *fp_glGetPathLengthNV = +	null: *fp_glGetPathLengthNV; +export let glGetPathMetricRangeNV: *fp_glGetPathMetricRangeNV = +	null: *fp_glGetPathMetricRangeNV; +export let glGetPathMetricsNV: *fp_glGetPathMetricsNV = +	null: *fp_glGetPathMetricsNV; +export let glGetPathParameterfvNV: *fp_glGetPathParameterfvNV = +	null: *fp_glGetPathParameterfvNV; +export let glGetPathParameterivNV: *fp_glGetPathParameterivNV = +	null: *fp_glGetPathParameterivNV; +export let glGetPathSpacingNV: *fp_glGetPathSpacingNV = +	null: *fp_glGetPathSpacingNV; +export let glGetPerfCounterInfoINTEL: *fp_glGetPerfCounterInfoINTEL = +	null: *fp_glGetPerfCounterInfoINTEL; +export let glGetPerfMonitorCounterDataAMD: *fp_glGetPerfMonitorCounterDataAMD = +	null: *fp_glGetPerfMonitorCounterDataAMD; +export let glGetPerfMonitorCounterInfoAMD: *fp_glGetPerfMonitorCounterInfoAMD = +	null: *fp_glGetPerfMonitorCounterInfoAMD; +export let glGetPerfMonitorCounterStringAMD: *fp_glGetPerfMonitorCounterStringAMD = +	null: *fp_glGetPerfMonitorCounterStringAMD; +export let glGetPerfMonitorCountersAMD: *fp_glGetPerfMonitorCountersAMD = +	null: *fp_glGetPerfMonitorCountersAMD; +export let glGetPerfMonitorGroupStringAMD: *fp_glGetPerfMonitorGroupStringAMD = +	null: *fp_glGetPerfMonitorGroupStringAMD; +export let glGetPerfMonitorGroupsAMD: *fp_glGetPerfMonitorGroupsAMD = +	null: *fp_glGetPerfMonitorGroupsAMD; +export let glGetPerfQueryDataINTEL: *fp_glGetPerfQueryDataINTEL = +	null: *fp_glGetPerfQueryDataINTEL; +export let glGetPerfQueryIdByNameINTEL: *fp_glGetPerfQueryIdByNameINTEL = +	null: *fp_glGetPerfQueryIdByNameINTEL; +export let glGetPerfQueryInfoINTEL: *fp_glGetPerfQueryInfoINTEL = +	null: *fp_glGetPerfQueryInfoINTEL; +export let glGetPointerv: *fp_glGetPointerv = +	null: *fp_glGetPointerv; +export let glGetPointervKHR: *fp_glGetPointervKHR = +	null: *fp_glGetPointervKHR; +export let glGetProgramBinary: *fp_glGetProgramBinary = +	null: *fp_glGetProgramBinary; +export let glGetProgramBinaryOES: *fp_glGetProgramBinaryOES = +	null: *fp_glGetProgramBinaryOES; +export let glGetProgramInfoLog: *fp_glGetProgramInfoLog = +	null: *fp_glGetProgramInfoLog; +export let glGetProgramInterfaceiv: *fp_glGetProgramInterfaceiv = +	null: *fp_glGetProgramInterfaceiv; +export let glGetProgramPipelineInfoLog: *fp_glGetProgramPipelineInfoLog = +	null: *fp_glGetProgramPipelineInfoLog; +export let glGetProgramPipelineInfoLogEXT: *fp_glGetProgramPipelineInfoLogEXT = +	null: *fp_glGetProgramPipelineInfoLogEXT; +export let glGetProgramPipelineiv: *fp_glGetProgramPipelineiv = +	null: *fp_glGetProgramPipelineiv; +export let glGetProgramPipelineivEXT: *fp_glGetProgramPipelineivEXT = +	null: *fp_glGetProgramPipelineivEXT; +export let glGetProgramResourceIndex: *fp_glGetProgramResourceIndex = +	null: *fp_glGetProgramResourceIndex; +export let glGetProgramResourceLocation: *fp_glGetProgramResourceLocation = +	null: *fp_glGetProgramResourceLocation; +export let glGetProgramResourceLocationIndexEXT: *fp_glGetProgramResourceLocationIndexEXT = +	null: *fp_glGetProgramResourceLocationIndexEXT; +export let glGetProgramResourceName: *fp_glGetProgramResourceName = +	null: *fp_glGetProgramResourceName; +export let glGetProgramResourcefvNV: *fp_glGetProgramResourcefvNV = +	null: *fp_glGetProgramResourcefvNV; +export let glGetProgramResourceiv: *fp_glGetProgramResourceiv = +	null: *fp_glGetProgramResourceiv; +export let glGetProgramiv: *fp_glGetProgramiv = +	null: *fp_glGetProgramiv; +export let glGetQueryObjecti64vEXT: *fp_glGetQueryObjecti64vEXT = +	null: *fp_glGetQueryObjecti64vEXT; +export let glGetQueryObjectivEXT: *fp_glGetQueryObjectivEXT = +	null: *fp_glGetQueryObjectivEXT; +export let glGetQueryObjectui64vEXT: *fp_glGetQueryObjectui64vEXT = +	null: *fp_glGetQueryObjectui64vEXT; +export let glGetQueryObjectuiv: *fp_glGetQueryObjectuiv = +	null: *fp_glGetQueryObjectuiv; +export let glGetQueryObjectuivEXT: *fp_glGetQueryObjectuivEXT = +	null: *fp_glGetQueryObjectuivEXT; +export let glGetQueryiv: *fp_glGetQueryiv = +	null: *fp_glGetQueryiv; +export let glGetQueryivEXT: *fp_glGetQueryivEXT = +	null: *fp_glGetQueryivEXT; +export let glGetRenderbufferParameteriv: *fp_glGetRenderbufferParameteriv = +	null: *fp_glGetRenderbufferParameteriv; +export let glGetSamplerParameterIiv: *fp_glGetSamplerParameterIiv = +	null: *fp_glGetSamplerParameterIiv; +export let glGetSamplerParameterIivEXT: *fp_glGetSamplerParameterIivEXT = +	null: *fp_glGetSamplerParameterIivEXT; +export let glGetSamplerParameterIivOES: *fp_glGetSamplerParameterIivOES = +	null: *fp_glGetSamplerParameterIivOES; +export let glGetSamplerParameterIuiv: *fp_glGetSamplerParameterIuiv = +	null: *fp_glGetSamplerParameterIuiv; +export let glGetSamplerParameterIuivEXT: *fp_glGetSamplerParameterIuivEXT = +	null: *fp_glGetSamplerParameterIuivEXT; +export let glGetSamplerParameterIuivOES: *fp_glGetSamplerParameterIuivOES = +	null: *fp_glGetSamplerParameterIuivOES; +export let glGetSamplerParameterfv: *fp_glGetSamplerParameterfv = +	null: *fp_glGetSamplerParameterfv; +export let glGetSamplerParameteriv: *fp_glGetSamplerParameteriv = +	null: *fp_glGetSamplerParameteriv; +export let glGetSemaphoreParameterivNV: *fp_glGetSemaphoreParameterivNV = +	null: *fp_glGetSemaphoreParameterivNV; +export let glGetSemaphoreParameterui64vEXT: *fp_glGetSemaphoreParameterui64vEXT = +	null: *fp_glGetSemaphoreParameterui64vEXT; +export let glGetShaderInfoLog: *fp_glGetShaderInfoLog = +	null: *fp_glGetShaderInfoLog; +export let glGetShaderPrecisionFormat: *fp_glGetShaderPrecisionFormat = +	null: *fp_glGetShaderPrecisionFormat; +export let glGetShaderSource: *fp_glGetShaderSource = +	null: *fp_glGetShaderSource; +export let glGetShaderiv: *fp_glGetShaderiv = +	null: *fp_glGetShaderiv; +export let glGetShadingRateImagePaletteNV: *fp_glGetShadingRateImagePaletteNV = +	null: *fp_glGetShadingRateImagePaletteNV; +export let glGetShadingRateSampleLocationivNV: *fp_glGetShadingRateSampleLocationivNV = +	null: *fp_glGetShadingRateSampleLocationivNV; +export let glGetString: *fp_glGetString = +	null: *fp_glGetString; +export let glGetStringi: *fp_glGetStringi = +	null: *fp_glGetStringi; +export let glGetSynciv: *fp_glGetSynciv = +	null: *fp_glGetSynciv; +export let glGetSyncivAPPLE: *fp_glGetSyncivAPPLE = +	null: *fp_glGetSyncivAPPLE; +export let glGetTexLevelParameterfv: *fp_glGetTexLevelParameterfv = +	null: *fp_glGetTexLevelParameterfv; +export let glGetTexLevelParameteriv: *fp_glGetTexLevelParameteriv = +	null: *fp_glGetTexLevelParameteriv; +export let glGetTexParameterIiv: *fp_glGetTexParameterIiv = +	null: *fp_glGetTexParameterIiv; +export let glGetTexParameterIivEXT: *fp_glGetTexParameterIivEXT = +	null: *fp_glGetTexParameterIivEXT; +export let glGetTexParameterIivOES: *fp_glGetTexParameterIivOES = +	null: *fp_glGetTexParameterIivOES; +export let glGetTexParameterIuiv: *fp_glGetTexParameterIuiv = +	null: *fp_glGetTexParameterIuiv; +export let glGetTexParameterIuivEXT: *fp_glGetTexParameterIuivEXT = +	null: *fp_glGetTexParameterIuivEXT; +export let glGetTexParameterIuivOES: *fp_glGetTexParameterIuivOES = +	null: *fp_glGetTexParameterIuivOES; +export let glGetTexParameterfv: *fp_glGetTexParameterfv = +	null: *fp_glGetTexParameterfv; +export let glGetTexParameteriv: *fp_glGetTexParameteriv = +	null: *fp_glGetTexParameteriv; +export let glGetTextureHandleIMG: *fp_glGetTextureHandleIMG = +	null: *fp_glGetTextureHandleIMG; +export let glGetTextureHandleNV: *fp_glGetTextureHandleNV = +	null: *fp_glGetTextureHandleNV; +export let glGetTextureSamplerHandleIMG: *fp_glGetTextureSamplerHandleIMG = +	null: *fp_glGetTextureSamplerHandleIMG; +export let glGetTextureSamplerHandleNV: *fp_glGetTextureSamplerHandleNV = +	null: *fp_glGetTextureSamplerHandleNV; +export let glGetTransformFeedbackVarying: *fp_glGetTransformFeedbackVarying = +	null: *fp_glGetTransformFeedbackVarying; +export let glGetTranslatedShaderSourceANGLE: *fp_glGetTranslatedShaderSourceANGLE = +	null: *fp_glGetTranslatedShaderSourceANGLE; +export let glGetUniformBlockIndex: *fp_glGetUniformBlockIndex = +	null: *fp_glGetUniformBlockIndex; +export let glGetUniformIndices: *fp_glGetUniformIndices = +	null: *fp_glGetUniformIndices; +export let glGetUniformLocation: *fp_glGetUniformLocation = +	null: *fp_glGetUniformLocation; +export let glGetUniformfv: *fp_glGetUniformfv = +	null: *fp_glGetUniformfv; +export let glGetUniformi64vNV: *fp_glGetUniformi64vNV = +	null: *fp_glGetUniformi64vNV; +export let glGetUniformiv: *fp_glGetUniformiv = +	null: *fp_glGetUniformiv; +export let glGetUniformuiv: *fp_glGetUniformuiv = +	null: *fp_glGetUniformuiv; +export let glGetUnsignedBytei_vEXT: *fp_glGetUnsignedBytei_vEXT = +	null: *fp_glGetUnsignedBytei_vEXT; +export let glGetUnsignedBytevEXT: *fp_glGetUnsignedBytevEXT = +	null: *fp_glGetUnsignedBytevEXT; +export let glGetVertexAttribIiv: *fp_glGetVertexAttribIiv = +	null: *fp_glGetVertexAttribIiv; +export let glGetVertexAttribIuiv: *fp_glGetVertexAttribIuiv = +	null: *fp_glGetVertexAttribIuiv; +export let glGetVertexAttribPointerv: *fp_glGetVertexAttribPointerv = +	null: *fp_glGetVertexAttribPointerv; +export let glGetVertexAttribfv: *fp_glGetVertexAttribfv = +	null: *fp_glGetVertexAttribfv; +export let glGetVertexAttribiv: *fp_glGetVertexAttribiv = +	null: *fp_glGetVertexAttribiv; +export let glGetVkProcAddrNV: *fp_glGetVkProcAddrNV = +	null: *fp_glGetVkProcAddrNV; +export let glGetnUniformfv: *fp_glGetnUniformfv = +	null: *fp_glGetnUniformfv; +export let glGetnUniformfvEXT: *fp_glGetnUniformfvEXT = +	null: *fp_glGetnUniformfvEXT; +export let glGetnUniformfvKHR: *fp_glGetnUniformfvKHR = +	null: *fp_glGetnUniformfvKHR; +export let glGetnUniformiv: *fp_glGetnUniformiv = +	null: *fp_glGetnUniformiv; +export let glGetnUniformivEXT: *fp_glGetnUniformivEXT = +	null: *fp_glGetnUniformivEXT; +export let glGetnUniformivKHR: *fp_glGetnUniformivKHR = +	null: *fp_glGetnUniformivKHR; +export let glGetnUniformuiv: *fp_glGetnUniformuiv = +	null: *fp_glGetnUniformuiv; +export let glGetnUniformuivKHR: *fp_glGetnUniformuivKHR = +	null: *fp_glGetnUniformuivKHR; +export let glHint: *fp_glHint = +	null: *fp_glHint; +export let glImportMemoryFdEXT: *fp_glImportMemoryFdEXT = +	null: *fp_glImportMemoryFdEXT; +export let glImportMemoryWin32HandleEXT: *fp_glImportMemoryWin32HandleEXT = +	null: *fp_glImportMemoryWin32HandleEXT; +export let glImportMemoryWin32NameEXT: *fp_glImportMemoryWin32NameEXT = +	null: *fp_glImportMemoryWin32NameEXT; +export let glImportSemaphoreFdEXT: *fp_glImportSemaphoreFdEXT = +	null: *fp_glImportSemaphoreFdEXT; +export let glImportSemaphoreWin32HandleEXT: *fp_glImportSemaphoreWin32HandleEXT = +	null: *fp_glImportSemaphoreWin32HandleEXT; +export let glImportSemaphoreWin32NameEXT: *fp_glImportSemaphoreWin32NameEXT = +	null: *fp_glImportSemaphoreWin32NameEXT; +export let glInsertEventMarkerEXT: *fp_glInsertEventMarkerEXT = +	null: *fp_glInsertEventMarkerEXT; +export let glInterpolatePathsNV: *fp_glInterpolatePathsNV = +	null: *fp_glInterpolatePathsNV; +export let glInvalidateFramebuffer: *fp_glInvalidateFramebuffer = +	null: *fp_glInvalidateFramebuffer; +export let glInvalidateSubFramebuffer: *fp_glInvalidateSubFramebuffer = +	null: *fp_glInvalidateSubFramebuffer; +export let glIsBuffer: *fp_glIsBuffer = +	null: *fp_glIsBuffer; +export let glIsEnabled: *fp_glIsEnabled = +	null: *fp_glIsEnabled; +export let glIsEnabledi: *fp_glIsEnabledi = +	null: *fp_glIsEnabledi; +export let glIsEnablediEXT: *fp_glIsEnablediEXT = +	null: *fp_glIsEnablediEXT; +export let glIsEnablediNV: *fp_glIsEnablediNV = +	null: *fp_glIsEnablediNV; +export let glIsEnablediOES: *fp_glIsEnablediOES = +	null: *fp_glIsEnablediOES; +export let glIsFenceNV: *fp_glIsFenceNV = +	null: *fp_glIsFenceNV; +export let glIsFramebuffer: *fp_glIsFramebuffer = +	null: *fp_glIsFramebuffer; +export let glIsImageHandleResidentNV: *fp_glIsImageHandleResidentNV = +	null: *fp_glIsImageHandleResidentNV; +export let glIsMemoryObjectEXT: *fp_glIsMemoryObjectEXT = +	null: *fp_glIsMemoryObjectEXT; +export let glIsPathNV: *fp_glIsPathNV = +	null: *fp_glIsPathNV; +export let glIsPointInFillPathNV: *fp_glIsPointInFillPathNV = +	null: *fp_glIsPointInFillPathNV; +export let glIsPointInStrokePathNV: *fp_glIsPointInStrokePathNV = +	null: *fp_glIsPointInStrokePathNV; +export let glIsProgram: *fp_glIsProgram = +	null: *fp_glIsProgram; +export let glIsProgramPipeline: *fp_glIsProgramPipeline = +	null: *fp_glIsProgramPipeline; +export let glIsProgramPipelineEXT: *fp_glIsProgramPipelineEXT = +	null: *fp_glIsProgramPipelineEXT; +export let glIsQuery: *fp_glIsQuery = +	null: *fp_glIsQuery; +export let glIsQueryEXT: *fp_glIsQueryEXT = +	null: *fp_glIsQueryEXT; +export let glIsRenderbuffer: *fp_glIsRenderbuffer = +	null: *fp_glIsRenderbuffer; +export let glIsSampler: *fp_glIsSampler = +	null: *fp_glIsSampler; +export let glIsSemaphoreEXT: *fp_glIsSemaphoreEXT = +	null: *fp_glIsSemaphoreEXT; +export let glIsShader: *fp_glIsShader = +	null: *fp_glIsShader; +export let glIsSync: *fp_glIsSync = +	null: *fp_glIsSync; +export let glIsSyncAPPLE: *fp_glIsSyncAPPLE = +	null: *fp_glIsSyncAPPLE; +export let glIsTexture: *fp_glIsTexture = +	null: *fp_glIsTexture; +export let glIsTextureHandleResidentNV: *fp_glIsTextureHandleResidentNV = +	null: *fp_glIsTextureHandleResidentNV; +export let glIsTransformFeedback: *fp_glIsTransformFeedback = +	null: *fp_glIsTransformFeedback; +export let glIsVertexArray: *fp_glIsVertexArray = +	null: *fp_glIsVertexArray; +export let glIsVertexArrayOES: *fp_glIsVertexArrayOES = +	null: *fp_glIsVertexArrayOES; +export let glLabelObjectEXT: *fp_glLabelObjectEXT = +	null: *fp_glLabelObjectEXT; +export let glLineWidth: *fp_glLineWidth = +	null: *fp_glLineWidth; +export let glLinkProgram: *fp_glLinkProgram = +	null: *fp_glLinkProgram; +export let glMakeImageHandleNonResidentNV: *fp_glMakeImageHandleNonResidentNV = +	null: *fp_glMakeImageHandleNonResidentNV; +export let glMakeImageHandleResidentNV: *fp_glMakeImageHandleResidentNV = +	null: *fp_glMakeImageHandleResidentNV; +export let glMakeTextureHandleNonResidentNV: *fp_glMakeTextureHandleNonResidentNV = +	null: *fp_glMakeTextureHandleNonResidentNV; +export let glMakeTextureHandleResidentNV: *fp_glMakeTextureHandleResidentNV = +	null: *fp_glMakeTextureHandleResidentNV; +export let glMapBufferOES: *fp_glMapBufferOES = +	null: *fp_glMapBufferOES; +export let glMapBufferRange: *fp_glMapBufferRange = +	null: *fp_glMapBufferRange; +export let glMapBufferRangeEXT: *fp_glMapBufferRangeEXT = +	null: *fp_glMapBufferRangeEXT; +export let glMatrixFrustumEXT: *fp_glMatrixFrustumEXT = +	null: *fp_glMatrixFrustumEXT; +export let glMatrixLoad3x2fNV: *fp_glMatrixLoad3x2fNV = +	null: *fp_glMatrixLoad3x2fNV; +export let glMatrixLoad3x3fNV: *fp_glMatrixLoad3x3fNV = +	null: *fp_glMatrixLoad3x3fNV; +export let glMatrixLoadIdentityEXT: *fp_glMatrixLoadIdentityEXT = +	null: *fp_glMatrixLoadIdentityEXT; +export let glMatrixLoadTranspose3x3fNV: *fp_glMatrixLoadTranspose3x3fNV = +	null: *fp_glMatrixLoadTranspose3x3fNV; +export let glMatrixLoadTransposedEXT: *fp_glMatrixLoadTransposedEXT = +	null: *fp_glMatrixLoadTransposedEXT; +export let glMatrixLoadTransposefEXT: *fp_glMatrixLoadTransposefEXT = +	null: *fp_glMatrixLoadTransposefEXT; +export let glMatrixLoaddEXT: *fp_glMatrixLoaddEXT = +	null: *fp_glMatrixLoaddEXT; +export let glMatrixLoadfEXT: *fp_glMatrixLoadfEXT = +	null: *fp_glMatrixLoadfEXT; +export let glMatrixMult3x2fNV: *fp_glMatrixMult3x2fNV = +	null: *fp_glMatrixMult3x2fNV; +export let glMatrixMult3x3fNV: *fp_glMatrixMult3x3fNV = +	null: *fp_glMatrixMult3x3fNV; +export let glMatrixMultTranspose3x3fNV: *fp_glMatrixMultTranspose3x3fNV = +	null: *fp_glMatrixMultTranspose3x3fNV; +export let glMatrixMultTransposedEXT: *fp_glMatrixMultTransposedEXT = +	null: *fp_glMatrixMultTransposedEXT; +export let glMatrixMultTransposefEXT: *fp_glMatrixMultTransposefEXT = +	null: *fp_glMatrixMultTransposefEXT; +export let glMatrixMultdEXT: *fp_glMatrixMultdEXT = +	null: *fp_glMatrixMultdEXT; +export let glMatrixMultfEXT: *fp_glMatrixMultfEXT = +	null: *fp_glMatrixMultfEXT; +export let glMatrixOrthoEXT: *fp_glMatrixOrthoEXT = +	null: *fp_glMatrixOrthoEXT; +export let glMatrixPopEXT: *fp_glMatrixPopEXT = +	null: *fp_glMatrixPopEXT; +export let glMatrixPushEXT: *fp_glMatrixPushEXT = +	null: *fp_glMatrixPushEXT; +export let glMatrixRotatedEXT: *fp_glMatrixRotatedEXT = +	null: *fp_glMatrixRotatedEXT; +export let glMatrixRotatefEXT: *fp_glMatrixRotatefEXT = +	null: *fp_glMatrixRotatefEXT; +export let glMatrixScaledEXT: *fp_glMatrixScaledEXT = +	null: *fp_glMatrixScaledEXT; +export let glMatrixScalefEXT: *fp_glMatrixScalefEXT = +	null: *fp_glMatrixScalefEXT; +export let glMatrixTranslatedEXT: *fp_glMatrixTranslatedEXT = +	null: *fp_glMatrixTranslatedEXT; +export let glMatrixTranslatefEXT: *fp_glMatrixTranslatefEXT = +	null: *fp_glMatrixTranslatefEXT; +export let glMaxShaderCompilerThreadsKHR: *fp_glMaxShaderCompilerThreadsKHR = +	null: *fp_glMaxShaderCompilerThreadsKHR; +export let glMemoryBarrier: *fp_glMemoryBarrier = +	null: *fp_glMemoryBarrier; +export let glMemoryBarrierByRegion: *fp_glMemoryBarrierByRegion = +	null: *fp_glMemoryBarrierByRegion; +export let glMemoryObjectParameterivEXT: *fp_glMemoryObjectParameterivEXT = +	null: *fp_glMemoryObjectParameterivEXT; +export let glMinSampleShading: *fp_glMinSampleShading = +	null: *fp_glMinSampleShading; +export let glMinSampleShadingOES: *fp_glMinSampleShadingOES = +	null: *fp_glMinSampleShadingOES; +export let glMultiDrawArraysEXT: *fp_glMultiDrawArraysEXT = +	null: *fp_glMultiDrawArraysEXT; +export let glMultiDrawArraysIndirectEXT: *fp_glMultiDrawArraysIndirectEXT = +	null: *fp_glMultiDrawArraysIndirectEXT; +export let glMultiDrawElementsBaseVertexEXT: *fp_glMultiDrawElementsBaseVertexEXT = +	null: *fp_glMultiDrawElementsBaseVertexEXT; +export let glMultiDrawElementsEXT: *fp_glMultiDrawElementsEXT = +	null: *fp_glMultiDrawElementsEXT; +export let glMultiDrawElementsIndirectEXT: *fp_glMultiDrawElementsIndirectEXT = +	null: *fp_glMultiDrawElementsIndirectEXT; +export let glMultiDrawMeshTasksIndirectCountNV: *fp_glMultiDrawMeshTasksIndirectCountNV = +	null: *fp_glMultiDrawMeshTasksIndirectCountNV; +export let glMultiDrawMeshTasksIndirectNV: *fp_glMultiDrawMeshTasksIndirectNV = +	null: *fp_glMultiDrawMeshTasksIndirectNV; +export let glNamedBufferAttachMemoryNV: *fp_glNamedBufferAttachMemoryNV = +	null: *fp_glNamedBufferAttachMemoryNV; +export let glNamedBufferPageCommitmentMemNV: *fp_glNamedBufferPageCommitmentMemNV = +	null: *fp_glNamedBufferPageCommitmentMemNV; +export let glNamedBufferStorageExternalEXT: *fp_glNamedBufferStorageExternalEXT = +	null: *fp_glNamedBufferStorageExternalEXT; +export let glNamedBufferStorageMemEXT: *fp_glNamedBufferStorageMemEXT = +	null: *fp_glNamedBufferStorageMemEXT; +export let glNamedFramebufferSampleLocationsfvNV: *fp_glNamedFramebufferSampleLocationsfvNV = +	null: *fp_glNamedFramebufferSampleLocationsfvNV; +export let glNamedRenderbufferStorageMultisampleAdvancedAMD: *fp_glNamedRenderbufferStorageMultisampleAdvancedAMD = +	null: *fp_glNamedRenderbufferStorageMultisampleAdvancedAMD; +export let glObjectLabel: *fp_glObjectLabel = +	null: *fp_glObjectLabel; +export let glObjectLabelKHR: *fp_glObjectLabelKHR = +	null: *fp_glObjectLabelKHR; +export let glObjectPtrLabel: *fp_glObjectPtrLabel = +	null: *fp_glObjectPtrLabel; +export let glObjectPtrLabelKHR: *fp_glObjectPtrLabelKHR = +	null: *fp_glObjectPtrLabelKHR; +export let glPatchParameteri: *fp_glPatchParameteri = +	null: *fp_glPatchParameteri; +export let glPatchParameteriEXT: *fp_glPatchParameteriEXT = +	null: *fp_glPatchParameteriEXT; +export let glPatchParameteriOES: *fp_glPatchParameteriOES = +	null: *fp_glPatchParameteriOES; +export let glPathCommandsNV: *fp_glPathCommandsNV = +	null: *fp_glPathCommandsNV; +export let glPathCoordsNV: *fp_glPathCoordsNV = +	null: *fp_glPathCoordsNV; +export let glPathCoverDepthFuncNV: *fp_glPathCoverDepthFuncNV = +	null: *fp_glPathCoverDepthFuncNV; +export let glPathDashArrayNV: *fp_glPathDashArrayNV = +	null: *fp_glPathDashArrayNV; +export let glPathGlyphIndexArrayNV: *fp_glPathGlyphIndexArrayNV = +	null: *fp_glPathGlyphIndexArrayNV; +export let glPathGlyphIndexRangeNV: *fp_glPathGlyphIndexRangeNV = +	null: *fp_glPathGlyphIndexRangeNV; +export let glPathGlyphRangeNV: *fp_glPathGlyphRangeNV = +	null: *fp_glPathGlyphRangeNV; +export let glPathGlyphsNV: *fp_glPathGlyphsNV = +	null: *fp_glPathGlyphsNV; +export let glPathMemoryGlyphIndexArrayNV: *fp_glPathMemoryGlyphIndexArrayNV = +	null: *fp_glPathMemoryGlyphIndexArrayNV; +export let glPathParameterfNV: *fp_glPathParameterfNV = +	null: *fp_glPathParameterfNV; +export let glPathParameterfvNV: *fp_glPathParameterfvNV = +	null: *fp_glPathParameterfvNV; +export let glPathParameteriNV: *fp_glPathParameteriNV = +	null: *fp_glPathParameteriNV; +export let glPathParameterivNV: *fp_glPathParameterivNV = +	null: *fp_glPathParameterivNV; +export let glPathStencilDepthOffsetNV: *fp_glPathStencilDepthOffsetNV = +	null: *fp_glPathStencilDepthOffsetNV; +export let glPathStencilFuncNV: *fp_glPathStencilFuncNV = +	null: *fp_glPathStencilFuncNV; +export let glPathStringNV: *fp_glPathStringNV = +	null: *fp_glPathStringNV; +export let glPathSubCommandsNV: *fp_glPathSubCommandsNV = +	null: *fp_glPathSubCommandsNV; +export let glPathSubCoordsNV: *fp_glPathSubCoordsNV = +	null: *fp_glPathSubCoordsNV; +export let glPauseTransformFeedback: *fp_glPauseTransformFeedback = +	null: *fp_glPauseTransformFeedback; +export let glPixelStorei: *fp_glPixelStorei = +	null: *fp_glPixelStorei; +export let glPointAlongPathNV: *fp_glPointAlongPathNV = +	null: *fp_glPointAlongPathNV; +export let glPolygonModeNV: *fp_glPolygonModeNV = +	null: *fp_glPolygonModeNV; +export let glPolygonOffset: *fp_glPolygonOffset = +	null: *fp_glPolygonOffset; +export let glPolygonOffsetClampEXT: *fp_glPolygonOffsetClampEXT = +	null: *fp_glPolygonOffsetClampEXT; +export let glPopDebugGroup: *fp_glPopDebugGroup = +	null: *fp_glPopDebugGroup; +export let glPopDebugGroupKHR: *fp_glPopDebugGroupKHR = +	null: *fp_glPopDebugGroupKHR; +export let glPopGroupMarkerEXT: *fp_glPopGroupMarkerEXT = +	null: *fp_glPopGroupMarkerEXT; +export let glPrimitiveBoundingBox: *fp_glPrimitiveBoundingBox = +	null: *fp_glPrimitiveBoundingBox; +export let glPrimitiveBoundingBoxEXT: *fp_glPrimitiveBoundingBoxEXT = +	null: *fp_glPrimitiveBoundingBoxEXT; +export let glPrimitiveBoundingBoxOES: *fp_glPrimitiveBoundingBoxOES = +	null: *fp_glPrimitiveBoundingBoxOES; +export let glProgramBinary: *fp_glProgramBinary = +	null: *fp_glProgramBinary; +export let glProgramBinaryOES: *fp_glProgramBinaryOES = +	null: *fp_glProgramBinaryOES; +export let glProgramParameteri: *fp_glProgramParameteri = +	null: *fp_glProgramParameteri; +export let glProgramParameteriEXT: *fp_glProgramParameteriEXT = +	null: *fp_glProgramParameteriEXT; +export let glProgramPathFragmentInputGenNV: *fp_glProgramPathFragmentInputGenNV = +	null: *fp_glProgramPathFragmentInputGenNV; +export let glProgramUniform1f: *fp_glProgramUniform1f = +	null: *fp_glProgramUniform1f; +export let glProgramUniform1fEXT: *fp_glProgramUniform1fEXT = +	null: *fp_glProgramUniform1fEXT; +export let glProgramUniform1fv: *fp_glProgramUniform1fv = +	null: *fp_glProgramUniform1fv; +export let glProgramUniform1fvEXT: *fp_glProgramUniform1fvEXT = +	null: *fp_glProgramUniform1fvEXT; +export let glProgramUniform1i: *fp_glProgramUniform1i = +	null: *fp_glProgramUniform1i; +export let glProgramUniform1i64NV: *fp_glProgramUniform1i64NV = +	null: *fp_glProgramUniform1i64NV; +export let glProgramUniform1i64vNV: *fp_glProgramUniform1i64vNV = +	null: *fp_glProgramUniform1i64vNV; +export let glProgramUniform1iEXT: *fp_glProgramUniform1iEXT = +	null: *fp_glProgramUniform1iEXT; +export let glProgramUniform1iv: *fp_glProgramUniform1iv = +	null: *fp_glProgramUniform1iv; +export let glProgramUniform1ivEXT: *fp_glProgramUniform1ivEXT = +	null: *fp_glProgramUniform1ivEXT; +export let glProgramUniform1ui: *fp_glProgramUniform1ui = +	null: *fp_glProgramUniform1ui; +export let glProgramUniform1ui64NV: *fp_glProgramUniform1ui64NV = +	null: *fp_glProgramUniform1ui64NV; +export let glProgramUniform1ui64vNV: *fp_glProgramUniform1ui64vNV = +	null: *fp_glProgramUniform1ui64vNV; +export let glProgramUniform1uiEXT: *fp_glProgramUniform1uiEXT = +	null: *fp_glProgramUniform1uiEXT; +export let glProgramUniform1uiv: *fp_glProgramUniform1uiv = +	null: *fp_glProgramUniform1uiv; +export let glProgramUniform1uivEXT: *fp_glProgramUniform1uivEXT = +	null: *fp_glProgramUniform1uivEXT; +export let glProgramUniform2f: *fp_glProgramUniform2f = +	null: *fp_glProgramUniform2f; +export let glProgramUniform2fEXT: *fp_glProgramUniform2fEXT = +	null: *fp_glProgramUniform2fEXT; +export let glProgramUniform2fv: *fp_glProgramUniform2fv = +	null: *fp_glProgramUniform2fv; +export let glProgramUniform2fvEXT: *fp_glProgramUniform2fvEXT = +	null: *fp_glProgramUniform2fvEXT; +export let glProgramUniform2i: *fp_glProgramUniform2i = +	null: *fp_glProgramUniform2i; +export let glProgramUniform2i64NV: *fp_glProgramUniform2i64NV = +	null: *fp_glProgramUniform2i64NV; +export let glProgramUniform2i64vNV: *fp_glProgramUniform2i64vNV = +	null: *fp_glProgramUniform2i64vNV; +export let glProgramUniform2iEXT: *fp_glProgramUniform2iEXT = +	null: *fp_glProgramUniform2iEXT; +export let glProgramUniform2iv: *fp_glProgramUniform2iv = +	null: *fp_glProgramUniform2iv; +export let glProgramUniform2ivEXT: *fp_glProgramUniform2ivEXT = +	null: *fp_glProgramUniform2ivEXT; +export let glProgramUniform2ui: *fp_glProgramUniform2ui = +	null: *fp_glProgramUniform2ui; +export let glProgramUniform2ui64NV: *fp_glProgramUniform2ui64NV = +	null: *fp_glProgramUniform2ui64NV; +export let glProgramUniform2ui64vNV: *fp_glProgramUniform2ui64vNV = +	null: *fp_glProgramUniform2ui64vNV; +export let glProgramUniform2uiEXT: *fp_glProgramUniform2uiEXT = +	null: *fp_glProgramUniform2uiEXT; +export let glProgramUniform2uiv: *fp_glProgramUniform2uiv = +	null: *fp_glProgramUniform2uiv; +export let glProgramUniform2uivEXT: *fp_glProgramUniform2uivEXT = +	null: *fp_glProgramUniform2uivEXT; +export let glProgramUniform3f: *fp_glProgramUniform3f = +	null: *fp_glProgramUniform3f; +export let glProgramUniform3fEXT: *fp_glProgramUniform3fEXT = +	null: *fp_glProgramUniform3fEXT; +export let glProgramUniform3fv: *fp_glProgramUniform3fv = +	null: *fp_glProgramUniform3fv; +export let glProgramUniform3fvEXT: *fp_glProgramUniform3fvEXT = +	null: *fp_glProgramUniform3fvEXT; +export let glProgramUniform3i: *fp_glProgramUniform3i = +	null: *fp_glProgramUniform3i; +export let glProgramUniform3i64NV: *fp_glProgramUniform3i64NV = +	null: *fp_glProgramUniform3i64NV; +export let glProgramUniform3i64vNV: *fp_glProgramUniform3i64vNV = +	null: *fp_glProgramUniform3i64vNV; +export let glProgramUniform3iEXT: *fp_glProgramUniform3iEXT = +	null: *fp_glProgramUniform3iEXT; +export let glProgramUniform3iv: *fp_glProgramUniform3iv = +	null: *fp_glProgramUniform3iv; +export let glProgramUniform3ivEXT: *fp_glProgramUniform3ivEXT = +	null: *fp_glProgramUniform3ivEXT; +export let glProgramUniform3ui: *fp_glProgramUniform3ui = +	null: *fp_glProgramUniform3ui; +export let glProgramUniform3ui64NV: *fp_glProgramUniform3ui64NV = +	null: *fp_glProgramUniform3ui64NV; +export let glProgramUniform3ui64vNV: *fp_glProgramUniform3ui64vNV = +	null: *fp_glProgramUniform3ui64vNV; +export let glProgramUniform3uiEXT: *fp_glProgramUniform3uiEXT = +	null: *fp_glProgramUniform3uiEXT; +export let glProgramUniform3uiv: *fp_glProgramUniform3uiv = +	null: *fp_glProgramUniform3uiv; +export let glProgramUniform3uivEXT: *fp_glProgramUniform3uivEXT = +	null: *fp_glProgramUniform3uivEXT; +export let glProgramUniform4f: *fp_glProgramUniform4f = +	null: *fp_glProgramUniform4f; +export let glProgramUniform4fEXT: *fp_glProgramUniform4fEXT = +	null: *fp_glProgramUniform4fEXT; +export let glProgramUniform4fv: *fp_glProgramUniform4fv = +	null: *fp_glProgramUniform4fv; +export let glProgramUniform4fvEXT: *fp_glProgramUniform4fvEXT = +	null: *fp_glProgramUniform4fvEXT; +export let glProgramUniform4i: *fp_glProgramUniform4i = +	null: *fp_glProgramUniform4i; +export let glProgramUniform4i64NV: *fp_glProgramUniform4i64NV = +	null: *fp_glProgramUniform4i64NV; +export let glProgramUniform4i64vNV: *fp_glProgramUniform4i64vNV = +	null: *fp_glProgramUniform4i64vNV; +export let glProgramUniform4iEXT: *fp_glProgramUniform4iEXT = +	null: *fp_glProgramUniform4iEXT; +export let glProgramUniform4iv: *fp_glProgramUniform4iv = +	null: *fp_glProgramUniform4iv; +export let glProgramUniform4ivEXT: *fp_glProgramUniform4ivEXT = +	null: *fp_glProgramUniform4ivEXT; +export let glProgramUniform4ui: *fp_glProgramUniform4ui = +	null: *fp_glProgramUniform4ui; +export let glProgramUniform4ui64NV: *fp_glProgramUniform4ui64NV = +	null: *fp_glProgramUniform4ui64NV; +export let glProgramUniform4ui64vNV: *fp_glProgramUniform4ui64vNV = +	null: *fp_glProgramUniform4ui64vNV; +export let glProgramUniform4uiEXT: *fp_glProgramUniform4uiEXT = +	null: *fp_glProgramUniform4uiEXT; +export let glProgramUniform4uiv: *fp_glProgramUniform4uiv = +	null: *fp_glProgramUniform4uiv; +export let glProgramUniform4uivEXT: *fp_glProgramUniform4uivEXT = +	null: *fp_glProgramUniform4uivEXT; +export let glProgramUniformHandleui64IMG: *fp_glProgramUniformHandleui64IMG = +	null: *fp_glProgramUniformHandleui64IMG; +export let glProgramUniformHandleui64NV: *fp_glProgramUniformHandleui64NV = +	null: *fp_glProgramUniformHandleui64NV; +export let glProgramUniformHandleui64vIMG: *fp_glProgramUniformHandleui64vIMG = +	null: *fp_glProgramUniformHandleui64vIMG; +export let glProgramUniformHandleui64vNV: *fp_glProgramUniformHandleui64vNV = +	null: *fp_glProgramUniformHandleui64vNV; +export let glProgramUniformMatrix2fv: *fp_glProgramUniformMatrix2fv = +	null: *fp_glProgramUniformMatrix2fv; +export let glProgramUniformMatrix2fvEXT: *fp_glProgramUniformMatrix2fvEXT = +	null: *fp_glProgramUniformMatrix2fvEXT; +export let glProgramUniformMatrix2x3fv: *fp_glProgramUniformMatrix2x3fv = +	null: *fp_glProgramUniformMatrix2x3fv; +export let glProgramUniformMatrix2x3fvEXT: *fp_glProgramUniformMatrix2x3fvEXT = +	null: *fp_glProgramUniformMatrix2x3fvEXT; +export let glProgramUniformMatrix2x4fv: *fp_glProgramUniformMatrix2x4fv = +	null: *fp_glProgramUniformMatrix2x4fv; +export let glProgramUniformMatrix2x4fvEXT: *fp_glProgramUniformMatrix2x4fvEXT = +	null: *fp_glProgramUniformMatrix2x4fvEXT; +export let glProgramUniformMatrix3fv: *fp_glProgramUniformMatrix3fv = +	null: *fp_glProgramUniformMatrix3fv; +export let glProgramUniformMatrix3fvEXT: *fp_glProgramUniformMatrix3fvEXT = +	null: *fp_glProgramUniformMatrix3fvEXT; +export let glProgramUniformMatrix3x2fv: *fp_glProgramUniformMatrix3x2fv = +	null: *fp_glProgramUniformMatrix3x2fv; +export let glProgramUniformMatrix3x2fvEXT: *fp_glProgramUniformMatrix3x2fvEXT = +	null: *fp_glProgramUniformMatrix3x2fvEXT; +export let glProgramUniformMatrix3x4fv: *fp_glProgramUniformMatrix3x4fv = +	null: *fp_glProgramUniformMatrix3x4fv; +export let glProgramUniformMatrix3x4fvEXT: *fp_glProgramUniformMatrix3x4fvEXT = +	null: *fp_glProgramUniformMatrix3x4fvEXT; +export let glProgramUniformMatrix4fv: *fp_glProgramUniformMatrix4fv = +	null: *fp_glProgramUniformMatrix4fv; +export let glProgramUniformMatrix4fvEXT: *fp_glProgramUniformMatrix4fvEXT = +	null: *fp_glProgramUniformMatrix4fvEXT; +export let glProgramUniformMatrix4x2fv: *fp_glProgramUniformMatrix4x2fv = +	null: *fp_glProgramUniformMatrix4x2fv; +export let glProgramUniformMatrix4x2fvEXT: *fp_glProgramUniformMatrix4x2fvEXT = +	null: *fp_glProgramUniformMatrix4x2fvEXT; +export let glProgramUniformMatrix4x3fv: *fp_glProgramUniformMatrix4x3fv = +	null: *fp_glProgramUniformMatrix4x3fv; +export let glProgramUniformMatrix4x3fvEXT: *fp_glProgramUniformMatrix4x3fvEXT = +	null: *fp_glProgramUniformMatrix4x3fvEXT; +export let glPushDebugGroup: *fp_glPushDebugGroup = +	null: *fp_glPushDebugGroup; +export let glPushDebugGroupKHR: *fp_glPushDebugGroupKHR = +	null: *fp_glPushDebugGroupKHR; +export let glPushGroupMarkerEXT: *fp_glPushGroupMarkerEXT = +	null: *fp_glPushGroupMarkerEXT; +export let glQueryCounterEXT: *fp_glQueryCounterEXT = +	null: *fp_glQueryCounterEXT; +export let glRasterSamplesEXT: *fp_glRasterSamplesEXT = +	null: *fp_glRasterSamplesEXT; +export let glReadBuffer: *fp_glReadBuffer = +	null: *fp_glReadBuffer; +export let glReadBufferIndexedEXT: *fp_glReadBufferIndexedEXT = +	null: *fp_glReadBufferIndexedEXT; +export let glReadBufferNV: *fp_glReadBufferNV = +	null: *fp_glReadBufferNV; +export let glReadPixels: *fp_glReadPixels = +	null: *fp_glReadPixels; +export let glReadnPixels: *fp_glReadnPixels = +	null: *fp_glReadnPixels; +export let glReadnPixelsEXT: *fp_glReadnPixelsEXT = +	null: *fp_glReadnPixelsEXT; +export let glReadnPixelsKHR: *fp_glReadnPixelsKHR = +	null: *fp_glReadnPixelsKHR; +export let glReleaseKeyedMutexWin32EXT: *fp_glReleaseKeyedMutexWin32EXT = +	null: *fp_glReleaseKeyedMutexWin32EXT; +export let glReleaseShaderCompiler: *fp_glReleaseShaderCompiler = +	null: *fp_glReleaseShaderCompiler; +export let glRenderbufferStorage: *fp_glRenderbufferStorage = +	null: *fp_glRenderbufferStorage; +export let glRenderbufferStorageMultisample: *fp_glRenderbufferStorageMultisample = +	null: *fp_glRenderbufferStorageMultisample; +export let glRenderbufferStorageMultisampleANGLE: *fp_glRenderbufferStorageMultisampleANGLE = +	null: *fp_glRenderbufferStorageMultisampleANGLE; +export let glRenderbufferStorageMultisampleAPPLE: *fp_glRenderbufferStorageMultisampleAPPLE = +	null: *fp_glRenderbufferStorageMultisampleAPPLE; +export let glRenderbufferStorageMultisampleAdvancedAMD: *fp_glRenderbufferStorageMultisampleAdvancedAMD = +	null: *fp_glRenderbufferStorageMultisampleAdvancedAMD; +export let glRenderbufferStorageMultisampleEXT: *fp_glRenderbufferStorageMultisampleEXT = +	null: *fp_glRenderbufferStorageMultisampleEXT; +export let glRenderbufferStorageMultisampleIMG: *fp_glRenderbufferStorageMultisampleIMG = +	null: *fp_glRenderbufferStorageMultisampleIMG; +export let glRenderbufferStorageMultisampleNV: *fp_glRenderbufferStorageMultisampleNV = +	null: *fp_glRenderbufferStorageMultisampleNV; +export let glResetMemoryObjectParameterNV: *fp_glResetMemoryObjectParameterNV = +	null: *fp_glResetMemoryObjectParameterNV; +export let glResolveDepthValuesNV: *fp_glResolveDepthValuesNV = +	null: *fp_glResolveDepthValuesNV; +export let glResolveMultisampleFramebufferAPPLE: *fp_glResolveMultisampleFramebufferAPPLE = +	null: *fp_glResolveMultisampleFramebufferAPPLE; +export let glResumeTransformFeedback: *fp_glResumeTransformFeedback = +	null: *fp_glResumeTransformFeedback; +export let glSampleCoverage: *fp_glSampleCoverage = +	null: *fp_glSampleCoverage; +export let glSampleMaski: *fp_glSampleMaski = +	null: *fp_glSampleMaski; +export let glSamplerParameterIiv: *fp_glSamplerParameterIiv = +	null: *fp_glSamplerParameterIiv; +export let glSamplerParameterIivEXT: *fp_glSamplerParameterIivEXT = +	null: *fp_glSamplerParameterIivEXT; +export let glSamplerParameterIivOES: *fp_glSamplerParameterIivOES = +	null: *fp_glSamplerParameterIivOES; +export let glSamplerParameterIuiv: *fp_glSamplerParameterIuiv = +	null: *fp_glSamplerParameterIuiv; +export let glSamplerParameterIuivEXT: *fp_glSamplerParameterIuivEXT = +	null: *fp_glSamplerParameterIuivEXT; +export let glSamplerParameterIuivOES: *fp_glSamplerParameterIuivOES = +	null: *fp_glSamplerParameterIuivOES; +export let glSamplerParameterf: *fp_glSamplerParameterf = +	null: *fp_glSamplerParameterf; +export let glSamplerParameterfv: *fp_glSamplerParameterfv = +	null: *fp_glSamplerParameterfv; +export let glSamplerParameteri: *fp_glSamplerParameteri = +	null: *fp_glSamplerParameteri; +export let glSamplerParameteriv: *fp_glSamplerParameteriv = +	null: *fp_glSamplerParameteriv; +export let glScissor: *fp_glScissor = +	null: *fp_glScissor; +export let glScissorArrayvNV: *fp_glScissorArrayvNV = +	null: *fp_glScissorArrayvNV; +export let glScissorArrayvOES: *fp_glScissorArrayvOES = +	null: *fp_glScissorArrayvOES; +export let glScissorExclusiveArrayvNV: *fp_glScissorExclusiveArrayvNV = +	null: *fp_glScissorExclusiveArrayvNV; +export let glScissorExclusiveNV: *fp_glScissorExclusiveNV = +	null: *fp_glScissorExclusiveNV; +export let glScissorIndexedNV: *fp_glScissorIndexedNV = +	null: *fp_glScissorIndexedNV; +export let glScissorIndexedOES: *fp_glScissorIndexedOES = +	null: *fp_glScissorIndexedOES; +export let glScissorIndexedvNV: *fp_glScissorIndexedvNV = +	null: *fp_glScissorIndexedvNV; +export let glScissorIndexedvOES: *fp_glScissorIndexedvOES = +	null: *fp_glScissorIndexedvOES; +export let glSelectPerfMonitorCountersAMD: *fp_glSelectPerfMonitorCountersAMD = +	null: *fp_glSelectPerfMonitorCountersAMD; +export let glSemaphoreParameterivNV: *fp_glSemaphoreParameterivNV = +	null: *fp_glSemaphoreParameterivNV; +export let glSemaphoreParameterui64vEXT: *fp_glSemaphoreParameterui64vEXT = +	null: *fp_glSemaphoreParameterui64vEXT; +export let glSetFenceNV: *fp_glSetFenceNV = +	null: *fp_glSetFenceNV; +export let glShaderBinary: *fp_glShaderBinary = +	null: *fp_glShaderBinary; +export let glShaderSource: *fp_glShaderSource = +	null: *fp_glShaderSource; +export let glShadingRateCombinerOpsEXT: *fp_glShadingRateCombinerOpsEXT = +	null: *fp_glShadingRateCombinerOpsEXT; +export let glShadingRateEXT: *fp_glShadingRateEXT = +	null: *fp_glShadingRateEXT; +export let glShadingRateImageBarrierNV: *fp_glShadingRateImageBarrierNV = +	null: *fp_glShadingRateImageBarrierNV; +export let glShadingRateImagePaletteNV: *fp_glShadingRateImagePaletteNV = +	null: *fp_glShadingRateImagePaletteNV; +export let glShadingRateQCOM: *fp_glShadingRateQCOM = +	null: *fp_glShadingRateQCOM; +export let glShadingRateSampleOrderCustomNV: *fp_glShadingRateSampleOrderCustomNV = +	null: *fp_glShadingRateSampleOrderCustomNV; +export let glShadingRateSampleOrderNV: *fp_glShadingRateSampleOrderNV = +	null: *fp_glShadingRateSampleOrderNV; +export let glSignalSemaphoreEXT: *fp_glSignalSemaphoreEXT = +	null: *fp_glSignalSemaphoreEXT; +export let glSignalVkFenceNV: *fp_glSignalVkFenceNV = +	null: *fp_glSignalVkFenceNV; +export let glSignalVkSemaphoreNV: *fp_glSignalVkSemaphoreNV = +	null: *fp_glSignalVkSemaphoreNV; +export let glStartTilingQCOM: *fp_glStartTilingQCOM = +	null: *fp_glStartTilingQCOM; +export let glStencilFillPathInstancedNV: *fp_glStencilFillPathInstancedNV = +	null: *fp_glStencilFillPathInstancedNV; +export let glStencilFillPathNV: *fp_glStencilFillPathNV = +	null: *fp_glStencilFillPathNV; +export let glStencilFunc: *fp_glStencilFunc = +	null: *fp_glStencilFunc; +export let glStencilFuncSeparate: *fp_glStencilFuncSeparate = +	null: *fp_glStencilFuncSeparate; +export let glStencilMask: *fp_glStencilMask = +	null: *fp_glStencilMask; +export let glStencilMaskSeparate: *fp_glStencilMaskSeparate = +	null: *fp_glStencilMaskSeparate; +export let glStencilOp: *fp_glStencilOp = +	null: *fp_glStencilOp; +export let glStencilOpSeparate: *fp_glStencilOpSeparate = +	null: *fp_glStencilOpSeparate; +export let glStencilStrokePathInstancedNV: *fp_glStencilStrokePathInstancedNV = +	null: *fp_glStencilStrokePathInstancedNV; +export let glStencilStrokePathNV: *fp_glStencilStrokePathNV = +	null: *fp_glStencilStrokePathNV; +export let glStencilThenCoverFillPathInstancedNV: *fp_glStencilThenCoverFillPathInstancedNV = +	null: *fp_glStencilThenCoverFillPathInstancedNV; +export let glStencilThenCoverFillPathNV: *fp_glStencilThenCoverFillPathNV = +	null: *fp_glStencilThenCoverFillPathNV; +export let glStencilThenCoverStrokePathInstancedNV: *fp_glStencilThenCoverStrokePathInstancedNV = +	null: *fp_glStencilThenCoverStrokePathInstancedNV; +export let glStencilThenCoverStrokePathNV: *fp_glStencilThenCoverStrokePathNV = +	null: *fp_glStencilThenCoverStrokePathNV; +export let glSubpixelPrecisionBiasNV: *fp_glSubpixelPrecisionBiasNV = +	null: *fp_glSubpixelPrecisionBiasNV; +export let glTestFenceNV: *fp_glTestFenceNV = +	null: *fp_glTestFenceNV; +export let glTexAttachMemoryNV: *fp_glTexAttachMemoryNV = +	null: *fp_glTexAttachMemoryNV; +export let glTexBuffer: *fp_glTexBuffer = +	null: *fp_glTexBuffer; +export let glTexBufferEXT: *fp_glTexBufferEXT = +	null: *fp_glTexBufferEXT; +export let glTexBufferOES: *fp_glTexBufferOES = +	null: *fp_glTexBufferOES; +export let glTexBufferRange: *fp_glTexBufferRange = +	null: *fp_glTexBufferRange; +export let glTexBufferRangeEXT: *fp_glTexBufferRangeEXT = +	null: *fp_glTexBufferRangeEXT; +export let glTexBufferRangeOES: *fp_glTexBufferRangeOES = +	null: *fp_glTexBufferRangeOES; +export let glTexEstimateMotionQCOM: *fp_glTexEstimateMotionQCOM = +	null: *fp_glTexEstimateMotionQCOM; +export let glTexEstimateMotionRegionsQCOM: *fp_glTexEstimateMotionRegionsQCOM = +	null: *fp_glTexEstimateMotionRegionsQCOM; +export let glTexImage2D: *fp_glTexImage2D = +	null: *fp_glTexImage2D; +export let glTexImage3D: *fp_glTexImage3D = +	null: *fp_glTexImage3D; +export let glTexImage3DOES: *fp_glTexImage3DOES = +	null: *fp_glTexImage3DOES; +export let glTexPageCommitmentEXT: *fp_glTexPageCommitmentEXT = +	null: *fp_glTexPageCommitmentEXT; +export let glTexPageCommitmentMemNV: *fp_glTexPageCommitmentMemNV = +	null: *fp_glTexPageCommitmentMemNV; +export let glTexParameterIiv: *fp_glTexParameterIiv = +	null: *fp_glTexParameterIiv; +export let glTexParameterIivEXT: *fp_glTexParameterIivEXT = +	null: *fp_glTexParameterIivEXT; +export let glTexParameterIivOES: *fp_glTexParameterIivOES = +	null: *fp_glTexParameterIivOES; +export let glTexParameterIuiv: *fp_glTexParameterIuiv = +	null: *fp_glTexParameterIuiv; +export let glTexParameterIuivEXT: *fp_glTexParameterIuivEXT = +	null: *fp_glTexParameterIuivEXT; +export let glTexParameterIuivOES: *fp_glTexParameterIuivOES = +	null: *fp_glTexParameterIuivOES; +export let glTexParameterf: *fp_glTexParameterf = +	null: *fp_glTexParameterf; +export let glTexParameterfv: *fp_glTexParameterfv = +	null: *fp_glTexParameterfv; +export let glTexParameteri: *fp_glTexParameteri = +	null: *fp_glTexParameteri; +export let glTexParameteriv: *fp_glTexParameteriv = +	null: *fp_glTexParameteriv; +export let glTexStorage1DEXT: *fp_glTexStorage1DEXT = +	null: *fp_glTexStorage1DEXT; +export let glTexStorage2D: *fp_glTexStorage2D = +	null: *fp_glTexStorage2D; +export let glTexStorage2DEXT: *fp_glTexStorage2DEXT = +	null: *fp_glTexStorage2DEXT; +export let glTexStorage2DMultisample: *fp_glTexStorage2DMultisample = +	null: *fp_glTexStorage2DMultisample; +export let glTexStorage3D: *fp_glTexStorage3D = +	null: *fp_glTexStorage3D; +export let glTexStorage3DEXT: *fp_glTexStorage3DEXT = +	null: *fp_glTexStorage3DEXT; +export let glTexStorage3DMultisample: *fp_glTexStorage3DMultisample = +	null: *fp_glTexStorage3DMultisample; +export let glTexStorage3DMultisampleOES: *fp_glTexStorage3DMultisampleOES = +	null: *fp_glTexStorage3DMultisampleOES; +export let glTexStorageAttribs2DEXT: *fp_glTexStorageAttribs2DEXT = +	null: *fp_glTexStorageAttribs2DEXT; +export let glTexStorageAttribs3DEXT: *fp_glTexStorageAttribs3DEXT = +	null: *fp_glTexStorageAttribs3DEXT; +export let glTexStorageMem2DEXT: *fp_glTexStorageMem2DEXT = +	null: *fp_glTexStorageMem2DEXT; +export let glTexStorageMem2DMultisampleEXT: *fp_glTexStorageMem2DMultisampleEXT = +	null: *fp_glTexStorageMem2DMultisampleEXT; +export let glTexStorageMem3DEXT: *fp_glTexStorageMem3DEXT = +	null: *fp_glTexStorageMem3DEXT; +export let glTexStorageMem3DMultisampleEXT: *fp_glTexStorageMem3DMultisampleEXT = +	null: *fp_glTexStorageMem3DMultisampleEXT; +export let glTexSubImage2D: *fp_glTexSubImage2D = +	null: *fp_glTexSubImage2D; +export let glTexSubImage3D: *fp_glTexSubImage3D = +	null: *fp_glTexSubImage3D; +export let glTexSubImage3DOES: *fp_glTexSubImage3DOES = +	null: *fp_glTexSubImage3DOES; +export let glTextureAttachMemoryNV: *fp_glTextureAttachMemoryNV = +	null: *fp_glTextureAttachMemoryNV; +export let glTextureFoveationParametersQCOM: *fp_glTextureFoveationParametersQCOM = +	null: *fp_glTextureFoveationParametersQCOM; +export let glTexturePageCommitmentMemNV: *fp_glTexturePageCommitmentMemNV = +	null: *fp_glTexturePageCommitmentMemNV; +export let glTextureStorage1DEXT: *fp_glTextureStorage1DEXT = +	null: *fp_glTextureStorage1DEXT; +export let glTextureStorage2DEXT: *fp_glTextureStorage2DEXT = +	null: *fp_glTextureStorage2DEXT; +export let glTextureStorage3DEXT: *fp_glTextureStorage3DEXT = +	null: *fp_glTextureStorage3DEXT; +export let glTextureStorageMem2DEXT: *fp_glTextureStorageMem2DEXT = +	null: *fp_glTextureStorageMem2DEXT; +export let glTextureStorageMem2DMultisampleEXT: *fp_glTextureStorageMem2DMultisampleEXT = +	null: *fp_glTextureStorageMem2DMultisampleEXT; +export let glTextureStorageMem3DEXT: *fp_glTextureStorageMem3DEXT = +	null: *fp_glTextureStorageMem3DEXT; +export let glTextureStorageMem3DMultisampleEXT: *fp_glTextureStorageMem3DMultisampleEXT = +	null: *fp_glTextureStorageMem3DMultisampleEXT; +export let glTextureViewEXT: *fp_glTextureViewEXT = +	null: *fp_glTextureViewEXT; +export let glTextureViewOES: *fp_glTextureViewOES = +	null: *fp_glTextureViewOES; +export let glTransformFeedbackVaryings: *fp_glTransformFeedbackVaryings = +	null: *fp_glTransformFeedbackVaryings; +export let glTransformPathNV: *fp_glTransformPathNV = +	null: *fp_glTransformPathNV; +export let glUniform1f: *fp_glUniform1f = +	null: *fp_glUniform1f; +export let glUniform1fv: *fp_glUniform1fv = +	null: *fp_glUniform1fv; +export let glUniform1i: *fp_glUniform1i = +	null: *fp_glUniform1i; +export let glUniform1i64NV: *fp_glUniform1i64NV = +	null: *fp_glUniform1i64NV; +export let glUniform1i64vNV: *fp_glUniform1i64vNV = +	null: *fp_glUniform1i64vNV; +export let glUniform1iv: *fp_glUniform1iv = +	null: *fp_glUniform1iv; +export let glUniform1ui: *fp_glUniform1ui = +	null: *fp_glUniform1ui; +export let glUniform1ui64NV: *fp_glUniform1ui64NV = +	null: *fp_glUniform1ui64NV; +export let glUniform1ui64vNV: *fp_glUniform1ui64vNV = +	null: *fp_glUniform1ui64vNV; +export let glUniform1uiv: *fp_glUniform1uiv = +	null: *fp_glUniform1uiv; +export let glUniform2f: *fp_glUniform2f = +	null: *fp_glUniform2f; +export let glUniform2fv: *fp_glUniform2fv = +	null: *fp_glUniform2fv; +export let glUniform2i: *fp_glUniform2i = +	null: *fp_glUniform2i; +export let glUniform2i64NV: *fp_glUniform2i64NV = +	null: *fp_glUniform2i64NV; +export let glUniform2i64vNV: *fp_glUniform2i64vNV = +	null: *fp_glUniform2i64vNV; +export let glUniform2iv: *fp_glUniform2iv = +	null: *fp_glUniform2iv; +export let glUniform2ui: *fp_glUniform2ui = +	null: *fp_glUniform2ui; +export let glUniform2ui64NV: *fp_glUniform2ui64NV = +	null: *fp_glUniform2ui64NV; +export let glUniform2ui64vNV: *fp_glUniform2ui64vNV = +	null: *fp_glUniform2ui64vNV; +export let glUniform2uiv: *fp_glUniform2uiv = +	null: *fp_glUniform2uiv; +export let glUniform3f: *fp_glUniform3f = +	null: *fp_glUniform3f; +export let glUniform3fv: *fp_glUniform3fv = +	null: *fp_glUniform3fv; +export let glUniform3i: *fp_glUniform3i = +	null: *fp_glUniform3i; +export let glUniform3i64NV: *fp_glUniform3i64NV = +	null: *fp_glUniform3i64NV; +export let glUniform3i64vNV: *fp_glUniform3i64vNV = +	null: *fp_glUniform3i64vNV; +export let glUniform3iv: *fp_glUniform3iv = +	null: *fp_glUniform3iv; +export let glUniform3ui: *fp_glUniform3ui = +	null: *fp_glUniform3ui; +export let glUniform3ui64NV: *fp_glUniform3ui64NV = +	null: *fp_glUniform3ui64NV; +export let glUniform3ui64vNV: *fp_glUniform3ui64vNV = +	null: *fp_glUniform3ui64vNV; +export let glUniform3uiv: *fp_glUniform3uiv = +	null: *fp_glUniform3uiv; +export let glUniform4f: *fp_glUniform4f = +	null: *fp_glUniform4f; +export let glUniform4fv: *fp_glUniform4fv = +	null: *fp_glUniform4fv; +export let glUniform4i: *fp_glUniform4i = +	null: *fp_glUniform4i; +export let glUniform4i64NV: *fp_glUniform4i64NV = +	null: *fp_glUniform4i64NV; +export let glUniform4i64vNV: *fp_glUniform4i64vNV = +	null: *fp_glUniform4i64vNV; +export let glUniform4iv: *fp_glUniform4iv = +	null: *fp_glUniform4iv; +export let glUniform4ui: *fp_glUniform4ui = +	null: *fp_glUniform4ui; +export let glUniform4ui64NV: *fp_glUniform4ui64NV = +	null: *fp_glUniform4ui64NV; +export let glUniform4ui64vNV: *fp_glUniform4ui64vNV = +	null: *fp_glUniform4ui64vNV; +export let glUniform4uiv: *fp_glUniform4uiv = +	null: *fp_glUniform4uiv; +export let glUniformBlockBinding: *fp_glUniformBlockBinding = +	null: *fp_glUniformBlockBinding; +export let glUniformHandleui64IMG: *fp_glUniformHandleui64IMG = +	null: *fp_glUniformHandleui64IMG; +export let glUniformHandleui64NV: *fp_glUniformHandleui64NV = +	null: *fp_glUniformHandleui64NV; +export let glUniformHandleui64vIMG: *fp_glUniformHandleui64vIMG = +	null: *fp_glUniformHandleui64vIMG; +export let glUniformHandleui64vNV: *fp_glUniformHandleui64vNV = +	null: *fp_glUniformHandleui64vNV; +export let glUniformMatrix2fv: *fp_glUniformMatrix2fv = +	null: *fp_glUniformMatrix2fv; +export let glUniformMatrix2x3fv: *fp_glUniformMatrix2x3fv = +	null: *fp_glUniformMatrix2x3fv; +export let glUniformMatrix2x3fvNV: *fp_glUniformMatrix2x3fvNV = +	null: *fp_glUniformMatrix2x3fvNV; +export let glUniformMatrix2x4fv: *fp_glUniformMatrix2x4fv = +	null: *fp_glUniformMatrix2x4fv; +export let glUniformMatrix2x4fvNV: *fp_glUniformMatrix2x4fvNV = +	null: *fp_glUniformMatrix2x4fvNV; +export let glUniformMatrix3fv: *fp_glUniformMatrix3fv = +	null: *fp_glUniformMatrix3fv; +export let glUniformMatrix3x2fv: *fp_glUniformMatrix3x2fv = +	null: *fp_glUniformMatrix3x2fv; +export let glUniformMatrix3x2fvNV: *fp_glUniformMatrix3x2fvNV = +	null: *fp_glUniformMatrix3x2fvNV; +export let glUniformMatrix3x4fv: *fp_glUniformMatrix3x4fv = +	null: *fp_glUniformMatrix3x4fv; +export let glUniformMatrix3x4fvNV: *fp_glUniformMatrix3x4fvNV = +	null: *fp_glUniformMatrix3x4fvNV; +export let glUniformMatrix4fv: *fp_glUniformMatrix4fv = +	null: *fp_glUniformMatrix4fv; +export let glUniformMatrix4x2fv: *fp_glUniformMatrix4x2fv = +	null: *fp_glUniformMatrix4x2fv; +export let glUniformMatrix4x2fvNV: *fp_glUniformMatrix4x2fvNV = +	null: *fp_glUniformMatrix4x2fvNV; +export let glUniformMatrix4x3fv: *fp_glUniformMatrix4x3fv = +	null: *fp_glUniformMatrix4x3fv; +export let glUniformMatrix4x3fvNV: *fp_glUniformMatrix4x3fvNV = +	null: *fp_glUniformMatrix4x3fvNV; +export let glUnmapBuffer: *fp_glUnmapBuffer = +	null: *fp_glUnmapBuffer; +export let glUnmapBufferOES: *fp_glUnmapBufferOES = +	null: *fp_glUnmapBufferOES; +export let glUseProgram: *fp_glUseProgram = +	null: *fp_glUseProgram; +export let glUseProgramStages: *fp_glUseProgramStages = +	null: *fp_glUseProgramStages; +export let glUseProgramStagesEXT: *fp_glUseProgramStagesEXT = +	null: *fp_glUseProgramStagesEXT; +export let glValidateProgram: *fp_glValidateProgram = +	null: *fp_glValidateProgram; +export let glValidateProgramPipeline: *fp_glValidateProgramPipeline = +	null: *fp_glValidateProgramPipeline; +export let glValidateProgramPipelineEXT: *fp_glValidateProgramPipelineEXT = +	null: *fp_glValidateProgramPipelineEXT; +export let glVertexAttrib1f: *fp_glVertexAttrib1f = +	null: *fp_glVertexAttrib1f; +export let glVertexAttrib1fv: *fp_glVertexAttrib1fv = +	null: *fp_glVertexAttrib1fv; +export let glVertexAttrib2f: *fp_glVertexAttrib2f = +	null: *fp_glVertexAttrib2f; +export let glVertexAttrib2fv: *fp_glVertexAttrib2fv = +	null: *fp_glVertexAttrib2fv; +export let glVertexAttrib3f: *fp_glVertexAttrib3f = +	null: *fp_glVertexAttrib3f; +export let glVertexAttrib3fv: *fp_glVertexAttrib3fv = +	null: *fp_glVertexAttrib3fv; +export let glVertexAttrib4f: *fp_glVertexAttrib4f = +	null: *fp_glVertexAttrib4f; +export let glVertexAttrib4fv: *fp_glVertexAttrib4fv = +	null: *fp_glVertexAttrib4fv; +export let glVertexAttribBinding: *fp_glVertexAttribBinding = +	null: *fp_glVertexAttribBinding; +export let glVertexAttribDivisor: *fp_glVertexAttribDivisor = +	null: *fp_glVertexAttribDivisor; +export let glVertexAttribDivisorANGLE: *fp_glVertexAttribDivisorANGLE = +	null: *fp_glVertexAttribDivisorANGLE; +export let glVertexAttribDivisorEXT: *fp_glVertexAttribDivisorEXT = +	null: *fp_glVertexAttribDivisorEXT; +export let glVertexAttribDivisorNV: *fp_glVertexAttribDivisorNV = +	null: *fp_glVertexAttribDivisorNV; +export let glVertexAttribFormat: *fp_glVertexAttribFormat = +	null: *fp_glVertexAttribFormat; +export let glVertexAttribI4i: *fp_glVertexAttribI4i = +	null: *fp_glVertexAttribI4i; +export let glVertexAttribI4iv: *fp_glVertexAttribI4iv = +	null: *fp_glVertexAttribI4iv; +export let glVertexAttribI4ui: *fp_glVertexAttribI4ui = +	null: *fp_glVertexAttribI4ui; +export let glVertexAttribI4uiv: *fp_glVertexAttribI4uiv = +	null: *fp_glVertexAttribI4uiv; +export let glVertexAttribIFormat: *fp_glVertexAttribIFormat = +	null: *fp_glVertexAttribIFormat; +export let glVertexAttribIPointer: *fp_glVertexAttribIPointer = +	null: *fp_glVertexAttribIPointer; +export let glVertexAttribPointer: *fp_glVertexAttribPointer = +	null: *fp_glVertexAttribPointer; +export let glVertexBindingDivisor: *fp_glVertexBindingDivisor = +	null: *fp_glVertexBindingDivisor; +export let glViewport: *fp_glViewport = +	null: *fp_glViewport; +export let glViewportArrayvNV: *fp_glViewportArrayvNV = +	null: *fp_glViewportArrayvNV; +export let glViewportArrayvOES: *fp_glViewportArrayvOES = +	null: *fp_glViewportArrayvOES; +export let glViewportIndexedfNV: *fp_glViewportIndexedfNV = +	null: *fp_glViewportIndexedfNV; +export let glViewportIndexedfOES: *fp_glViewportIndexedfOES = +	null: *fp_glViewportIndexedfOES; +export let glViewportIndexedfvNV: *fp_glViewportIndexedfvNV = +	null: *fp_glViewportIndexedfvNV; +export let glViewportIndexedfvOES: *fp_glViewportIndexedfvOES = +	null: *fp_glViewportIndexedfvOES; +export let glViewportPositionWScaleNV: *fp_glViewportPositionWScaleNV = +	null: *fp_glViewportPositionWScaleNV; +export let glViewportSwizzleNV: *fp_glViewportSwizzleNV = +	null: *fp_glViewportSwizzleNV; +export let glWaitSemaphoreEXT: *fp_glWaitSemaphoreEXT = +	null: *fp_glWaitSemaphoreEXT; +export let glWaitSync: *fp_glWaitSync = +	null: *fp_glWaitSync; +export let glWaitSyncAPPLE: *fp_glWaitSyncAPPLE = +	null: *fp_glWaitSyncAPPLE; +export let glWaitVkSemaphoreNV: *fp_glWaitVkSemaphoreNV = +	null: *fp_glWaitVkSemaphoreNV; +export let glWeightPathsNV: *fp_glWeightPathsNV = +	null: *fp_glWeightPathsNV; +export let glWindowRectanglesEXT: *fp_glWindowRectanglesEXT = +	null: *fp_glWindowRectanglesEXT; + +// Function loading with user loader +export type fp_get_proc_address = fn(procName: *const char) *opaque; + +fn call_user_get_proc_address(user_get_proc_address: *fp_get_proc_address, proc_name: str) *opaque = { +	let cstr = ((&proc_name): *types::string).data: *const char; +	return user_get_proc_address(cstr); +}; + +export fn load_with_fn(user_get_proc_address: *fp_get_proc_address) void = { +	glAcquireKeyedMutexWin32EXT = call_user_get_proc_address(user_get_proc_address, "glAcquireKeyedMutexWin32EXT\0"): *fp_glAcquireKeyedMutexWin32EXT; +	glActiveShaderProgram = call_user_get_proc_address(user_get_proc_address, "glActiveShaderProgram\0"): *fp_glActiveShaderProgram; +	glActiveShaderProgramEXT = call_user_get_proc_address(user_get_proc_address, "glActiveShaderProgramEXT\0"): *fp_glActiveShaderProgramEXT; +	glActiveTexture = call_user_get_proc_address(user_get_proc_address, "glActiveTexture\0"): *fp_glActiveTexture; +	glAlphaFuncQCOM = call_user_get_proc_address(user_get_proc_address, "glAlphaFuncQCOM\0"): *fp_glAlphaFuncQCOM; +	glApplyFramebufferAttachmentCMAAINTEL = call_user_get_proc_address(user_get_proc_address, "glApplyFramebufferAttachmentCMAAINTEL\0"): *fp_glApplyFramebufferAttachmentCMAAINTEL; +	glAttachShader = call_user_get_proc_address(user_get_proc_address, "glAttachShader\0"): *fp_glAttachShader; +	glBeginConditionalRenderNV = call_user_get_proc_address(user_get_proc_address, "glBeginConditionalRenderNV\0"): *fp_glBeginConditionalRenderNV; +	glBeginPerfMonitorAMD = call_user_get_proc_address(user_get_proc_address, "glBeginPerfMonitorAMD\0"): *fp_glBeginPerfMonitorAMD; +	glBeginPerfQueryINTEL = call_user_get_proc_address(user_get_proc_address, "glBeginPerfQueryINTEL\0"): *fp_glBeginPerfQueryINTEL; +	glBeginQuery = call_user_get_proc_address(user_get_proc_address, "glBeginQuery\0"): *fp_glBeginQuery; +	glBeginQueryEXT = call_user_get_proc_address(user_get_proc_address, "glBeginQueryEXT\0"): *fp_glBeginQueryEXT; +	glBeginTransformFeedback = call_user_get_proc_address(user_get_proc_address, "glBeginTransformFeedback\0"): *fp_glBeginTransformFeedback; +	glBindAttribLocation = call_user_get_proc_address(user_get_proc_address, "glBindAttribLocation\0"): *fp_glBindAttribLocation; +	glBindBuffer = call_user_get_proc_address(user_get_proc_address, "glBindBuffer\0"): *fp_glBindBuffer; +	glBindBufferBase = call_user_get_proc_address(user_get_proc_address, "glBindBufferBase\0"): *fp_glBindBufferBase; +	glBindBufferRange = call_user_get_proc_address(user_get_proc_address, "glBindBufferRange\0"): *fp_glBindBufferRange; +	glBindFragDataLocationEXT = call_user_get_proc_address(user_get_proc_address, "glBindFragDataLocationEXT\0"): *fp_glBindFragDataLocationEXT; +	glBindFragDataLocationIndexedEXT = call_user_get_proc_address(user_get_proc_address, "glBindFragDataLocationIndexedEXT\0"): *fp_glBindFragDataLocationIndexedEXT; +	glBindFramebuffer = call_user_get_proc_address(user_get_proc_address, "glBindFramebuffer\0"): *fp_glBindFramebuffer; +	glBindImageTexture = call_user_get_proc_address(user_get_proc_address, "glBindImageTexture\0"): *fp_glBindImageTexture; +	glBindProgramPipeline = call_user_get_proc_address(user_get_proc_address, "glBindProgramPipeline\0"): *fp_glBindProgramPipeline; +	glBindProgramPipelineEXT = call_user_get_proc_address(user_get_proc_address, "glBindProgramPipelineEXT\0"): *fp_glBindProgramPipelineEXT; +	glBindRenderbuffer = call_user_get_proc_address(user_get_proc_address, "glBindRenderbuffer\0"): *fp_glBindRenderbuffer; +	glBindSampler = call_user_get_proc_address(user_get_proc_address, "glBindSampler\0"): *fp_glBindSampler; +	glBindShadingRateImageNV = call_user_get_proc_address(user_get_proc_address, "glBindShadingRateImageNV\0"): *fp_glBindShadingRateImageNV; +	glBindTexture = call_user_get_proc_address(user_get_proc_address, "glBindTexture\0"): *fp_glBindTexture; +	glBindTransformFeedback = call_user_get_proc_address(user_get_proc_address, "glBindTransformFeedback\0"): *fp_glBindTransformFeedback; +	glBindVertexArray = call_user_get_proc_address(user_get_proc_address, "glBindVertexArray\0"): *fp_glBindVertexArray; +	glBindVertexArrayOES = call_user_get_proc_address(user_get_proc_address, "glBindVertexArrayOES\0"): *fp_glBindVertexArrayOES; +	glBindVertexBuffer = call_user_get_proc_address(user_get_proc_address, "glBindVertexBuffer\0"): *fp_glBindVertexBuffer; +	glBlendBarrier = call_user_get_proc_address(user_get_proc_address, "glBlendBarrier\0"): *fp_glBlendBarrier; +	glBlendBarrierKHR = call_user_get_proc_address(user_get_proc_address, "glBlendBarrierKHR\0"): *fp_glBlendBarrierKHR; +	glBlendBarrierNV = call_user_get_proc_address(user_get_proc_address, "glBlendBarrierNV\0"): *fp_glBlendBarrierNV; +	glBlendColor = call_user_get_proc_address(user_get_proc_address, "glBlendColor\0"): *fp_glBlendColor; +	glBlendEquation = call_user_get_proc_address(user_get_proc_address, "glBlendEquation\0"): *fp_glBlendEquation; +	glBlendEquationSeparate = call_user_get_proc_address(user_get_proc_address, "glBlendEquationSeparate\0"): *fp_glBlendEquationSeparate; +	glBlendEquationSeparatei = call_user_get_proc_address(user_get_proc_address, "glBlendEquationSeparatei\0"): *fp_glBlendEquationSeparatei; +	glBlendEquationSeparateiEXT = call_user_get_proc_address(user_get_proc_address, "glBlendEquationSeparateiEXT\0"): *fp_glBlendEquationSeparateiEXT; +	glBlendEquationSeparateiOES = call_user_get_proc_address(user_get_proc_address, "glBlendEquationSeparateiOES\0"): *fp_glBlendEquationSeparateiOES; +	glBlendEquationi = call_user_get_proc_address(user_get_proc_address, "glBlendEquationi\0"): *fp_glBlendEquationi; +	glBlendEquationiEXT = call_user_get_proc_address(user_get_proc_address, "glBlendEquationiEXT\0"): *fp_glBlendEquationiEXT; +	glBlendEquationiOES = call_user_get_proc_address(user_get_proc_address, "glBlendEquationiOES\0"): *fp_glBlendEquationiOES; +	glBlendFunc = call_user_get_proc_address(user_get_proc_address, "glBlendFunc\0"): *fp_glBlendFunc; +	glBlendFuncSeparate = call_user_get_proc_address(user_get_proc_address, "glBlendFuncSeparate\0"): *fp_glBlendFuncSeparate; +	glBlendFuncSeparatei = call_user_get_proc_address(user_get_proc_address, "glBlendFuncSeparatei\0"): *fp_glBlendFuncSeparatei; +	glBlendFuncSeparateiEXT = call_user_get_proc_address(user_get_proc_address, "glBlendFuncSeparateiEXT\0"): *fp_glBlendFuncSeparateiEXT; +	glBlendFuncSeparateiOES = call_user_get_proc_address(user_get_proc_address, "glBlendFuncSeparateiOES\0"): *fp_glBlendFuncSeparateiOES; +	glBlendFunci = call_user_get_proc_address(user_get_proc_address, "glBlendFunci\0"): *fp_glBlendFunci; +	glBlendFunciEXT = call_user_get_proc_address(user_get_proc_address, "glBlendFunciEXT\0"): *fp_glBlendFunciEXT; +	glBlendFunciOES = call_user_get_proc_address(user_get_proc_address, "glBlendFunciOES\0"): *fp_glBlendFunciOES; +	glBlendParameteriNV = call_user_get_proc_address(user_get_proc_address, "glBlendParameteriNV\0"): *fp_glBlendParameteriNV; +	glBlitFramebuffer = call_user_get_proc_address(user_get_proc_address, "glBlitFramebuffer\0"): *fp_glBlitFramebuffer; +	glBlitFramebufferANGLE = call_user_get_proc_address(user_get_proc_address, "glBlitFramebufferANGLE\0"): *fp_glBlitFramebufferANGLE; +	glBlitFramebufferNV = call_user_get_proc_address(user_get_proc_address, "glBlitFramebufferNV\0"): *fp_glBlitFramebufferNV; +	glBufferAttachMemoryNV = call_user_get_proc_address(user_get_proc_address, "glBufferAttachMemoryNV\0"): *fp_glBufferAttachMemoryNV; +	glBufferData = call_user_get_proc_address(user_get_proc_address, "glBufferData\0"): *fp_glBufferData; +	glBufferPageCommitmentMemNV = call_user_get_proc_address(user_get_proc_address, "glBufferPageCommitmentMemNV\0"): *fp_glBufferPageCommitmentMemNV; +	glBufferStorageEXT = call_user_get_proc_address(user_get_proc_address, "glBufferStorageEXT\0"): *fp_glBufferStorageEXT; +	glBufferStorageExternalEXT = call_user_get_proc_address(user_get_proc_address, "glBufferStorageExternalEXT\0"): *fp_glBufferStorageExternalEXT; +	glBufferStorageMemEXT = call_user_get_proc_address(user_get_proc_address, "glBufferStorageMemEXT\0"): *fp_glBufferStorageMemEXT; +	glBufferSubData = call_user_get_proc_address(user_get_proc_address, "glBufferSubData\0"): *fp_glBufferSubData; +	glCheckFramebufferStatus = call_user_get_proc_address(user_get_proc_address, "glCheckFramebufferStatus\0"): *fp_glCheckFramebufferStatus; +	glClear = call_user_get_proc_address(user_get_proc_address, "glClear\0"): *fp_glClear; +	glClearBufferfi = call_user_get_proc_address(user_get_proc_address, "glClearBufferfi\0"): *fp_glClearBufferfi; +	glClearBufferfv = call_user_get_proc_address(user_get_proc_address, "glClearBufferfv\0"): *fp_glClearBufferfv; +	glClearBufferiv = call_user_get_proc_address(user_get_proc_address, "glClearBufferiv\0"): *fp_glClearBufferiv; +	glClearBufferuiv = call_user_get_proc_address(user_get_proc_address, "glClearBufferuiv\0"): *fp_glClearBufferuiv; +	glClearColor = call_user_get_proc_address(user_get_proc_address, "glClearColor\0"): *fp_glClearColor; +	glClearDepthf = call_user_get_proc_address(user_get_proc_address, "glClearDepthf\0"): *fp_glClearDepthf; +	glClearPixelLocalStorageuiEXT = call_user_get_proc_address(user_get_proc_address, "glClearPixelLocalStorageuiEXT\0"): *fp_glClearPixelLocalStorageuiEXT; +	glClearStencil = call_user_get_proc_address(user_get_proc_address, "glClearStencil\0"): *fp_glClearStencil; +	glClearTexImageEXT = call_user_get_proc_address(user_get_proc_address, "glClearTexImageEXT\0"): *fp_glClearTexImageEXT; +	glClearTexSubImageEXT = call_user_get_proc_address(user_get_proc_address, "glClearTexSubImageEXT\0"): *fp_glClearTexSubImageEXT; +	glClientWaitSync = call_user_get_proc_address(user_get_proc_address, "glClientWaitSync\0"): *fp_glClientWaitSync; +	glClientWaitSyncAPPLE = call_user_get_proc_address(user_get_proc_address, "glClientWaitSyncAPPLE\0"): *fp_glClientWaitSyncAPPLE; +	glClipControlEXT = call_user_get_proc_address(user_get_proc_address, "glClipControlEXT\0"): *fp_glClipControlEXT; +	glColorMask = call_user_get_proc_address(user_get_proc_address, "glColorMask\0"): *fp_glColorMask; +	glColorMaski = call_user_get_proc_address(user_get_proc_address, "glColorMaski\0"): *fp_glColorMaski; +	glColorMaskiEXT = call_user_get_proc_address(user_get_proc_address, "glColorMaskiEXT\0"): *fp_glColorMaskiEXT; +	glColorMaskiOES = call_user_get_proc_address(user_get_proc_address, "glColorMaskiOES\0"): *fp_glColorMaskiOES; +	glCompileShader = call_user_get_proc_address(user_get_proc_address, "glCompileShader\0"): *fp_glCompileShader; +	glCompressedTexImage2D = call_user_get_proc_address(user_get_proc_address, "glCompressedTexImage2D\0"): *fp_glCompressedTexImage2D; +	glCompressedTexImage3D = call_user_get_proc_address(user_get_proc_address, "glCompressedTexImage3D\0"): *fp_glCompressedTexImage3D; +	glCompressedTexImage3DOES = call_user_get_proc_address(user_get_proc_address, "glCompressedTexImage3DOES\0"): *fp_glCompressedTexImage3DOES; +	glCompressedTexSubImage2D = call_user_get_proc_address(user_get_proc_address, "glCompressedTexSubImage2D\0"): *fp_glCompressedTexSubImage2D; +	glCompressedTexSubImage3D = call_user_get_proc_address(user_get_proc_address, "glCompressedTexSubImage3D\0"): *fp_glCompressedTexSubImage3D; +	glCompressedTexSubImage3DOES = call_user_get_proc_address(user_get_proc_address, "glCompressedTexSubImage3DOES\0"): *fp_glCompressedTexSubImage3DOES; +	glConservativeRasterParameteriNV = call_user_get_proc_address(user_get_proc_address, "glConservativeRasterParameteriNV\0"): *fp_glConservativeRasterParameteriNV; +	glCopyBufferSubData = call_user_get_proc_address(user_get_proc_address, "glCopyBufferSubData\0"): *fp_glCopyBufferSubData; +	glCopyBufferSubDataNV = call_user_get_proc_address(user_get_proc_address, "glCopyBufferSubDataNV\0"): *fp_glCopyBufferSubDataNV; +	glCopyImageSubData = call_user_get_proc_address(user_get_proc_address, "glCopyImageSubData\0"): *fp_glCopyImageSubData; +	glCopyImageSubDataEXT = call_user_get_proc_address(user_get_proc_address, "glCopyImageSubDataEXT\0"): *fp_glCopyImageSubDataEXT; +	glCopyImageSubDataOES = call_user_get_proc_address(user_get_proc_address, "glCopyImageSubDataOES\0"): *fp_glCopyImageSubDataOES; +	glCopyPathNV = call_user_get_proc_address(user_get_proc_address, "glCopyPathNV\0"): *fp_glCopyPathNV; +	glCopyTexImage2D = call_user_get_proc_address(user_get_proc_address, "glCopyTexImage2D\0"): *fp_glCopyTexImage2D; +	glCopyTexSubImage2D = call_user_get_proc_address(user_get_proc_address, "glCopyTexSubImage2D\0"): *fp_glCopyTexSubImage2D; +	glCopyTexSubImage3D = call_user_get_proc_address(user_get_proc_address, "glCopyTexSubImage3D\0"): *fp_glCopyTexSubImage3D; +	glCopyTexSubImage3DOES = call_user_get_proc_address(user_get_proc_address, "glCopyTexSubImage3DOES\0"): *fp_glCopyTexSubImage3DOES; +	glCopyTextureLevelsAPPLE = call_user_get_proc_address(user_get_proc_address, "glCopyTextureLevelsAPPLE\0"): *fp_glCopyTextureLevelsAPPLE; +	glCoverFillPathInstancedNV = call_user_get_proc_address(user_get_proc_address, "glCoverFillPathInstancedNV\0"): *fp_glCoverFillPathInstancedNV; +	glCoverFillPathNV = call_user_get_proc_address(user_get_proc_address, "glCoverFillPathNV\0"): *fp_glCoverFillPathNV; +	glCoverStrokePathInstancedNV = call_user_get_proc_address(user_get_proc_address, "glCoverStrokePathInstancedNV\0"): *fp_glCoverStrokePathInstancedNV; +	glCoverStrokePathNV = call_user_get_proc_address(user_get_proc_address, "glCoverStrokePathNV\0"): *fp_glCoverStrokePathNV; +	glCoverageMaskNV = call_user_get_proc_address(user_get_proc_address, "glCoverageMaskNV\0"): *fp_glCoverageMaskNV; +	glCoverageModulationNV = call_user_get_proc_address(user_get_proc_address, "glCoverageModulationNV\0"): *fp_glCoverageModulationNV; +	glCoverageModulationTableNV = call_user_get_proc_address(user_get_proc_address, "glCoverageModulationTableNV\0"): *fp_glCoverageModulationTableNV; +	glCoverageOperationNV = call_user_get_proc_address(user_get_proc_address, "glCoverageOperationNV\0"): *fp_glCoverageOperationNV; +	glCreateMemoryObjectsEXT = call_user_get_proc_address(user_get_proc_address, "glCreateMemoryObjectsEXT\0"): *fp_glCreateMemoryObjectsEXT; +	glCreatePerfQueryINTEL = call_user_get_proc_address(user_get_proc_address, "glCreatePerfQueryINTEL\0"): *fp_glCreatePerfQueryINTEL; +	glCreateProgram = call_user_get_proc_address(user_get_proc_address, "glCreateProgram\0"): *fp_glCreateProgram; +	glCreateSemaphoresNV = call_user_get_proc_address(user_get_proc_address, "glCreateSemaphoresNV\0"): *fp_glCreateSemaphoresNV; +	glCreateShader = call_user_get_proc_address(user_get_proc_address, "glCreateShader\0"): *fp_glCreateShader; +	glCreateShaderProgramv = call_user_get_proc_address(user_get_proc_address, "glCreateShaderProgramv\0"): *fp_glCreateShaderProgramv; +	glCreateShaderProgramvEXT = call_user_get_proc_address(user_get_proc_address, "glCreateShaderProgramvEXT\0"): *fp_glCreateShaderProgramvEXT; +	glCullFace = call_user_get_proc_address(user_get_proc_address, "glCullFace\0"): *fp_glCullFace; +	glDebugMessageCallback = call_user_get_proc_address(user_get_proc_address, "glDebugMessageCallback\0"): *fp_glDebugMessageCallback; +	glDebugMessageCallbackKHR = call_user_get_proc_address(user_get_proc_address, "glDebugMessageCallbackKHR\0"): *fp_glDebugMessageCallbackKHR; +	glDebugMessageControl = call_user_get_proc_address(user_get_proc_address, "glDebugMessageControl\0"): *fp_glDebugMessageControl; +	glDebugMessageControlKHR = call_user_get_proc_address(user_get_proc_address, "glDebugMessageControlKHR\0"): *fp_glDebugMessageControlKHR; +	glDebugMessageInsert = call_user_get_proc_address(user_get_proc_address, "glDebugMessageInsert\0"): *fp_glDebugMessageInsert; +	glDebugMessageInsertKHR = call_user_get_proc_address(user_get_proc_address, "glDebugMessageInsertKHR\0"): *fp_glDebugMessageInsertKHR; +	glDeleteBuffers = call_user_get_proc_address(user_get_proc_address, "glDeleteBuffers\0"): *fp_glDeleteBuffers; +	glDeleteFencesNV = call_user_get_proc_address(user_get_proc_address, "glDeleteFencesNV\0"): *fp_glDeleteFencesNV; +	glDeleteFramebuffers = call_user_get_proc_address(user_get_proc_address, "glDeleteFramebuffers\0"): *fp_glDeleteFramebuffers; +	glDeleteMemoryObjectsEXT = call_user_get_proc_address(user_get_proc_address, "glDeleteMemoryObjectsEXT\0"): *fp_glDeleteMemoryObjectsEXT; +	glDeletePathsNV = call_user_get_proc_address(user_get_proc_address, "glDeletePathsNV\0"): *fp_glDeletePathsNV; +	glDeletePerfMonitorsAMD = call_user_get_proc_address(user_get_proc_address, "glDeletePerfMonitorsAMD\0"): *fp_glDeletePerfMonitorsAMD; +	glDeletePerfQueryINTEL = call_user_get_proc_address(user_get_proc_address, "glDeletePerfQueryINTEL\0"): *fp_glDeletePerfQueryINTEL; +	glDeleteProgram = call_user_get_proc_address(user_get_proc_address, "glDeleteProgram\0"): *fp_glDeleteProgram; +	glDeleteProgramPipelines = call_user_get_proc_address(user_get_proc_address, "glDeleteProgramPipelines\0"): *fp_glDeleteProgramPipelines; +	glDeleteProgramPipelinesEXT = call_user_get_proc_address(user_get_proc_address, "glDeleteProgramPipelinesEXT\0"): *fp_glDeleteProgramPipelinesEXT; +	glDeleteQueries = call_user_get_proc_address(user_get_proc_address, "glDeleteQueries\0"): *fp_glDeleteQueries; +	glDeleteQueriesEXT = call_user_get_proc_address(user_get_proc_address, "glDeleteQueriesEXT\0"): *fp_glDeleteQueriesEXT; +	glDeleteRenderbuffers = call_user_get_proc_address(user_get_proc_address, "glDeleteRenderbuffers\0"): *fp_glDeleteRenderbuffers; +	glDeleteSamplers = call_user_get_proc_address(user_get_proc_address, "glDeleteSamplers\0"): *fp_glDeleteSamplers; +	glDeleteSemaphoresEXT = call_user_get_proc_address(user_get_proc_address, "glDeleteSemaphoresEXT\0"): *fp_glDeleteSemaphoresEXT; +	glDeleteShader = call_user_get_proc_address(user_get_proc_address, "glDeleteShader\0"): *fp_glDeleteShader; +	glDeleteSync = call_user_get_proc_address(user_get_proc_address, "glDeleteSync\0"): *fp_glDeleteSync; +	glDeleteSyncAPPLE = call_user_get_proc_address(user_get_proc_address, "glDeleteSyncAPPLE\0"): *fp_glDeleteSyncAPPLE; +	glDeleteTextures = call_user_get_proc_address(user_get_proc_address, "glDeleteTextures\0"): *fp_glDeleteTextures; +	glDeleteTransformFeedbacks = call_user_get_proc_address(user_get_proc_address, "glDeleteTransformFeedbacks\0"): *fp_glDeleteTransformFeedbacks; +	glDeleteVertexArrays = call_user_get_proc_address(user_get_proc_address, "glDeleteVertexArrays\0"): *fp_glDeleteVertexArrays; +	glDeleteVertexArraysOES = call_user_get_proc_address(user_get_proc_address, "glDeleteVertexArraysOES\0"): *fp_glDeleteVertexArraysOES; +	glDepthFunc = call_user_get_proc_address(user_get_proc_address, "glDepthFunc\0"): *fp_glDepthFunc; +	glDepthMask = call_user_get_proc_address(user_get_proc_address, "glDepthMask\0"): *fp_glDepthMask; +	glDepthRangeArrayfvNV = call_user_get_proc_address(user_get_proc_address, "glDepthRangeArrayfvNV\0"): *fp_glDepthRangeArrayfvNV; +	glDepthRangeArrayfvOES = call_user_get_proc_address(user_get_proc_address, "glDepthRangeArrayfvOES\0"): *fp_glDepthRangeArrayfvOES; +	glDepthRangeIndexedfNV = call_user_get_proc_address(user_get_proc_address, "glDepthRangeIndexedfNV\0"): *fp_glDepthRangeIndexedfNV; +	glDepthRangeIndexedfOES = call_user_get_proc_address(user_get_proc_address, "glDepthRangeIndexedfOES\0"): *fp_glDepthRangeIndexedfOES; +	glDepthRangef = call_user_get_proc_address(user_get_proc_address, "glDepthRangef\0"): *fp_glDepthRangef; +	glDetachShader = call_user_get_proc_address(user_get_proc_address, "glDetachShader\0"): *fp_glDetachShader; +	glDisable = call_user_get_proc_address(user_get_proc_address, "glDisable\0"): *fp_glDisable; +	glDisableDriverControlQCOM = call_user_get_proc_address(user_get_proc_address, "glDisableDriverControlQCOM\0"): *fp_glDisableDriverControlQCOM; +	glDisableVertexAttribArray = call_user_get_proc_address(user_get_proc_address, "glDisableVertexAttribArray\0"): *fp_glDisableVertexAttribArray; +	glDisablei = call_user_get_proc_address(user_get_proc_address, "glDisablei\0"): *fp_glDisablei; +	glDisableiEXT = call_user_get_proc_address(user_get_proc_address, "glDisableiEXT\0"): *fp_glDisableiEXT; +	glDisableiNV = call_user_get_proc_address(user_get_proc_address, "glDisableiNV\0"): *fp_glDisableiNV; +	glDisableiOES = call_user_get_proc_address(user_get_proc_address, "glDisableiOES\0"): *fp_glDisableiOES; +	glDiscardFramebufferEXT = call_user_get_proc_address(user_get_proc_address, "glDiscardFramebufferEXT\0"): *fp_glDiscardFramebufferEXT; +	glDispatchCompute = call_user_get_proc_address(user_get_proc_address, "glDispatchCompute\0"): *fp_glDispatchCompute; +	glDispatchComputeIndirect = call_user_get_proc_address(user_get_proc_address, "glDispatchComputeIndirect\0"): *fp_glDispatchComputeIndirect; +	glDrawArrays = call_user_get_proc_address(user_get_proc_address, "glDrawArrays\0"): *fp_glDrawArrays; +	glDrawArraysIndirect = call_user_get_proc_address(user_get_proc_address, "glDrawArraysIndirect\0"): *fp_glDrawArraysIndirect; +	glDrawArraysInstanced = call_user_get_proc_address(user_get_proc_address, "glDrawArraysInstanced\0"): *fp_glDrawArraysInstanced; +	glDrawArraysInstancedANGLE = call_user_get_proc_address(user_get_proc_address, "glDrawArraysInstancedANGLE\0"): *fp_glDrawArraysInstancedANGLE; +	glDrawArraysInstancedBaseInstanceEXT = call_user_get_proc_address(user_get_proc_address, "glDrawArraysInstancedBaseInstanceEXT\0"): *fp_glDrawArraysInstancedBaseInstanceEXT; +	glDrawArraysInstancedEXT = call_user_get_proc_address(user_get_proc_address, "glDrawArraysInstancedEXT\0"): *fp_glDrawArraysInstancedEXT; +	glDrawArraysInstancedNV = call_user_get_proc_address(user_get_proc_address, "glDrawArraysInstancedNV\0"): *fp_glDrawArraysInstancedNV; +	glDrawBuffers = call_user_get_proc_address(user_get_proc_address, "glDrawBuffers\0"): *fp_glDrawBuffers; +	glDrawBuffersEXT = call_user_get_proc_address(user_get_proc_address, "glDrawBuffersEXT\0"): *fp_glDrawBuffersEXT; +	glDrawBuffersIndexedEXT = call_user_get_proc_address(user_get_proc_address, "glDrawBuffersIndexedEXT\0"): *fp_glDrawBuffersIndexedEXT; +	glDrawBuffersNV = call_user_get_proc_address(user_get_proc_address, "glDrawBuffersNV\0"): *fp_glDrawBuffersNV; +	glDrawElements = call_user_get_proc_address(user_get_proc_address, "glDrawElements\0"): *fp_glDrawElements; +	glDrawElementsBaseVertex = call_user_get_proc_address(user_get_proc_address, "glDrawElementsBaseVertex\0"): *fp_glDrawElementsBaseVertex; +	glDrawElementsBaseVertexEXT = call_user_get_proc_address(user_get_proc_address, "glDrawElementsBaseVertexEXT\0"): *fp_glDrawElementsBaseVertexEXT; +	glDrawElementsBaseVertexOES = call_user_get_proc_address(user_get_proc_address, "glDrawElementsBaseVertexOES\0"): *fp_glDrawElementsBaseVertexOES; +	glDrawElementsIndirect = call_user_get_proc_address(user_get_proc_address, "glDrawElementsIndirect\0"): *fp_glDrawElementsIndirect; +	glDrawElementsInstanced = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstanced\0"): *fp_glDrawElementsInstanced; +	glDrawElementsInstancedANGLE = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstancedANGLE\0"): *fp_glDrawElementsInstancedANGLE; +	glDrawElementsInstancedBaseInstanceEXT = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstancedBaseInstanceEXT\0"): *fp_glDrawElementsInstancedBaseInstanceEXT; +	glDrawElementsInstancedBaseVertex = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstancedBaseVertex\0"): *fp_glDrawElementsInstancedBaseVertex; +	glDrawElementsInstancedBaseVertexBaseInstanceEXT = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstancedBaseVertexBaseInstanceEXT\0"): *fp_glDrawElementsInstancedBaseVertexBaseInstanceEXT; +	glDrawElementsInstancedBaseVertexEXT = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstancedBaseVertexEXT\0"): *fp_glDrawElementsInstancedBaseVertexEXT; +	glDrawElementsInstancedBaseVertexOES = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstancedBaseVertexOES\0"): *fp_glDrawElementsInstancedBaseVertexOES; +	glDrawElementsInstancedEXT = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstancedEXT\0"): *fp_glDrawElementsInstancedEXT; +	glDrawElementsInstancedNV = call_user_get_proc_address(user_get_proc_address, "glDrawElementsInstancedNV\0"): *fp_glDrawElementsInstancedNV; +	glDrawMeshTasksIndirectNV = call_user_get_proc_address(user_get_proc_address, "glDrawMeshTasksIndirectNV\0"): *fp_glDrawMeshTasksIndirectNV; +	glDrawMeshTasksNV = call_user_get_proc_address(user_get_proc_address, "glDrawMeshTasksNV\0"): *fp_glDrawMeshTasksNV; +	glDrawRangeElements = call_user_get_proc_address(user_get_proc_address, "glDrawRangeElements\0"): *fp_glDrawRangeElements; +	glDrawRangeElementsBaseVertex = call_user_get_proc_address(user_get_proc_address, "glDrawRangeElementsBaseVertex\0"): *fp_glDrawRangeElementsBaseVertex; +	glDrawRangeElementsBaseVertexEXT = call_user_get_proc_address(user_get_proc_address, "glDrawRangeElementsBaseVertexEXT\0"): *fp_glDrawRangeElementsBaseVertexEXT; +	glDrawRangeElementsBaseVertexOES = call_user_get_proc_address(user_get_proc_address, "glDrawRangeElementsBaseVertexOES\0"): *fp_glDrawRangeElementsBaseVertexOES; +	glDrawTransformFeedbackEXT = call_user_get_proc_address(user_get_proc_address, "glDrawTransformFeedbackEXT\0"): *fp_glDrawTransformFeedbackEXT; +	glDrawTransformFeedbackInstancedEXT = call_user_get_proc_address(user_get_proc_address, "glDrawTransformFeedbackInstancedEXT\0"): *fp_glDrawTransformFeedbackInstancedEXT; +	glDrawVkImageNV = call_user_get_proc_address(user_get_proc_address, "glDrawVkImageNV\0"): *fp_glDrawVkImageNV; +	glEGLImageTargetRenderbufferStorageOES = call_user_get_proc_address(user_get_proc_address, "glEGLImageTargetRenderbufferStorageOES\0"): *fp_glEGLImageTargetRenderbufferStorageOES; +	glEGLImageTargetTexStorageEXT = call_user_get_proc_address(user_get_proc_address, "glEGLImageTargetTexStorageEXT\0"): *fp_glEGLImageTargetTexStorageEXT; +	glEGLImageTargetTexture2DOES = call_user_get_proc_address(user_get_proc_address, "glEGLImageTargetTexture2DOES\0"): *fp_glEGLImageTargetTexture2DOES; +	glEGLImageTargetTextureStorageEXT = call_user_get_proc_address(user_get_proc_address, "glEGLImageTargetTextureStorageEXT\0"): *fp_glEGLImageTargetTextureStorageEXT; +	glEnable = call_user_get_proc_address(user_get_proc_address, "glEnable\0"): *fp_glEnable; +	glEnableDriverControlQCOM = call_user_get_proc_address(user_get_proc_address, "glEnableDriverControlQCOM\0"): *fp_glEnableDriverControlQCOM; +	glEnableVertexAttribArray = call_user_get_proc_address(user_get_proc_address, "glEnableVertexAttribArray\0"): *fp_glEnableVertexAttribArray; +	glEnablei = call_user_get_proc_address(user_get_proc_address, "glEnablei\0"): *fp_glEnablei; +	glEnableiEXT = call_user_get_proc_address(user_get_proc_address, "glEnableiEXT\0"): *fp_glEnableiEXT; +	glEnableiNV = call_user_get_proc_address(user_get_proc_address, "glEnableiNV\0"): *fp_glEnableiNV; +	glEnableiOES = call_user_get_proc_address(user_get_proc_address, "glEnableiOES\0"): *fp_glEnableiOES; +	glEndConditionalRenderNV = call_user_get_proc_address(user_get_proc_address, "glEndConditionalRenderNV\0"): *fp_glEndConditionalRenderNV; +	glEndPerfMonitorAMD = call_user_get_proc_address(user_get_proc_address, "glEndPerfMonitorAMD\0"): *fp_glEndPerfMonitorAMD; +	glEndPerfQueryINTEL = call_user_get_proc_address(user_get_proc_address, "glEndPerfQueryINTEL\0"): *fp_glEndPerfQueryINTEL; +	glEndQuery = call_user_get_proc_address(user_get_proc_address, "glEndQuery\0"): *fp_glEndQuery; +	glEndQueryEXT = call_user_get_proc_address(user_get_proc_address, "glEndQueryEXT\0"): *fp_glEndQueryEXT; +	glEndTilingQCOM = call_user_get_proc_address(user_get_proc_address, "glEndTilingQCOM\0"): *fp_glEndTilingQCOM; +	glEndTransformFeedback = call_user_get_proc_address(user_get_proc_address, "glEndTransformFeedback\0"): *fp_glEndTransformFeedback; +	glExtGetBufferPointervQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetBufferPointervQCOM\0"): *fp_glExtGetBufferPointervQCOM; +	glExtGetBuffersQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetBuffersQCOM\0"): *fp_glExtGetBuffersQCOM; +	glExtGetFramebuffersQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetFramebuffersQCOM\0"): *fp_glExtGetFramebuffersQCOM; +	glExtGetProgramBinarySourceQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetProgramBinarySourceQCOM\0"): *fp_glExtGetProgramBinarySourceQCOM; +	glExtGetProgramsQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetProgramsQCOM\0"): *fp_glExtGetProgramsQCOM; +	glExtGetRenderbuffersQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetRenderbuffersQCOM\0"): *fp_glExtGetRenderbuffersQCOM; +	glExtGetShadersQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetShadersQCOM\0"): *fp_glExtGetShadersQCOM; +	glExtGetTexLevelParameterivQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetTexLevelParameterivQCOM\0"): *fp_glExtGetTexLevelParameterivQCOM; +	glExtGetTexSubImageQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetTexSubImageQCOM\0"): *fp_glExtGetTexSubImageQCOM; +	glExtGetTexturesQCOM = call_user_get_proc_address(user_get_proc_address, "glExtGetTexturesQCOM\0"): *fp_glExtGetTexturesQCOM; +	glExtIsProgramBinaryQCOM = call_user_get_proc_address(user_get_proc_address, "glExtIsProgramBinaryQCOM\0"): *fp_glExtIsProgramBinaryQCOM; +	glExtTexObjectStateOverrideiQCOM = call_user_get_proc_address(user_get_proc_address, "glExtTexObjectStateOverrideiQCOM\0"): *fp_glExtTexObjectStateOverrideiQCOM; +	glExtrapolateTex2DQCOM = call_user_get_proc_address(user_get_proc_address, "glExtrapolateTex2DQCOM\0"): *fp_glExtrapolateTex2DQCOM; +	glFenceSync = call_user_get_proc_address(user_get_proc_address, "glFenceSync\0"): *fp_glFenceSync; +	glFenceSyncAPPLE = call_user_get_proc_address(user_get_proc_address, "glFenceSyncAPPLE\0"): *fp_glFenceSyncAPPLE; +	glFinish = call_user_get_proc_address(user_get_proc_address, "glFinish\0"): *fp_glFinish; +	glFinishFenceNV = call_user_get_proc_address(user_get_proc_address, "glFinishFenceNV\0"): *fp_glFinishFenceNV; +	glFlush = call_user_get_proc_address(user_get_proc_address, "glFlush\0"): *fp_glFlush; +	glFlushMappedBufferRange = call_user_get_proc_address(user_get_proc_address, "glFlushMappedBufferRange\0"): *fp_glFlushMappedBufferRange; +	glFlushMappedBufferRangeEXT = call_user_get_proc_address(user_get_proc_address, "glFlushMappedBufferRangeEXT\0"): *fp_glFlushMappedBufferRangeEXT; +	glFragmentCoverageColorNV = call_user_get_proc_address(user_get_proc_address, "glFragmentCoverageColorNV\0"): *fp_glFragmentCoverageColorNV; +	glFramebufferFetchBarrierEXT = call_user_get_proc_address(user_get_proc_address, "glFramebufferFetchBarrierEXT\0"): *fp_glFramebufferFetchBarrierEXT; +	glFramebufferFetchBarrierQCOM = call_user_get_proc_address(user_get_proc_address, "glFramebufferFetchBarrierQCOM\0"): *fp_glFramebufferFetchBarrierQCOM; +	glFramebufferFoveationConfigQCOM = call_user_get_proc_address(user_get_proc_address, "glFramebufferFoveationConfigQCOM\0"): *fp_glFramebufferFoveationConfigQCOM; +	glFramebufferFoveationParametersQCOM = call_user_get_proc_address(user_get_proc_address, "glFramebufferFoveationParametersQCOM\0"): *fp_glFramebufferFoveationParametersQCOM; +	glFramebufferParameteri = call_user_get_proc_address(user_get_proc_address, "glFramebufferParameteri\0"): *fp_glFramebufferParameteri; +	glFramebufferParameteriMESA = call_user_get_proc_address(user_get_proc_address, "glFramebufferParameteriMESA\0"): *fp_glFramebufferParameteriMESA; +	glFramebufferPixelLocalStorageSizeEXT = call_user_get_proc_address(user_get_proc_address, "glFramebufferPixelLocalStorageSizeEXT\0"): *fp_glFramebufferPixelLocalStorageSizeEXT; +	glFramebufferRenderbuffer = call_user_get_proc_address(user_get_proc_address, "glFramebufferRenderbuffer\0"): *fp_glFramebufferRenderbuffer; +	glFramebufferSampleLocationsfvNV = call_user_get_proc_address(user_get_proc_address, "glFramebufferSampleLocationsfvNV\0"): *fp_glFramebufferSampleLocationsfvNV; +	glFramebufferShadingRateEXT = call_user_get_proc_address(user_get_proc_address, "glFramebufferShadingRateEXT\0"): *fp_glFramebufferShadingRateEXT; +	glFramebufferTexture = call_user_get_proc_address(user_get_proc_address, "glFramebufferTexture\0"): *fp_glFramebufferTexture; +	glFramebufferTexture2D = call_user_get_proc_address(user_get_proc_address, "glFramebufferTexture2D\0"): *fp_glFramebufferTexture2D; +	glFramebufferTexture2DDownsampleIMG = call_user_get_proc_address(user_get_proc_address, "glFramebufferTexture2DDownsampleIMG\0"): *fp_glFramebufferTexture2DDownsampleIMG; +	glFramebufferTexture2DMultisampleEXT = call_user_get_proc_address(user_get_proc_address, "glFramebufferTexture2DMultisampleEXT\0"): *fp_glFramebufferTexture2DMultisampleEXT; +	glFramebufferTexture2DMultisampleIMG = call_user_get_proc_address(user_get_proc_address, "glFramebufferTexture2DMultisampleIMG\0"): *fp_glFramebufferTexture2DMultisampleIMG; +	glFramebufferTexture3DOES = call_user_get_proc_address(user_get_proc_address, "glFramebufferTexture3DOES\0"): *fp_glFramebufferTexture3DOES; +	glFramebufferTextureEXT = call_user_get_proc_address(user_get_proc_address, "glFramebufferTextureEXT\0"): *fp_glFramebufferTextureEXT; +	glFramebufferTextureLayer = call_user_get_proc_address(user_get_proc_address, "glFramebufferTextureLayer\0"): *fp_glFramebufferTextureLayer; +	glFramebufferTextureLayerDownsampleIMG = call_user_get_proc_address(user_get_proc_address, "glFramebufferTextureLayerDownsampleIMG\0"): *fp_glFramebufferTextureLayerDownsampleIMG; +	glFramebufferTextureMultisampleMultiviewOVR = call_user_get_proc_address(user_get_proc_address, "glFramebufferTextureMultisampleMultiviewOVR\0"): *fp_glFramebufferTextureMultisampleMultiviewOVR; +	glFramebufferTextureMultiviewOVR = call_user_get_proc_address(user_get_proc_address, "glFramebufferTextureMultiviewOVR\0"): *fp_glFramebufferTextureMultiviewOVR; +	glFramebufferTextureOES = call_user_get_proc_address(user_get_proc_address, "glFramebufferTextureOES\0"): *fp_glFramebufferTextureOES; +	glFrontFace = call_user_get_proc_address(user_get_proc_address, "glFrontFace\0"): *fp_glFrontFace; +	glGenBuffers = call_user_get_proc_address(user_get_proc_address, "glGenBuffers\0"): *fp_glGenBuffers; +	glGenFencesNV = call_user_get_proc_address(user_get_proc_address, "glGenFencesNV\0"): *fp_glGenFencesNV; +	glGenFramebuffers = call_user_get_proc_address(user_get_proc_address, "glGenFramebuffers\0"): *fp_glGenFramebuffers; +	glGenPathsNV = call_user_get_proc_address(user_get_proc_address, "glGenPathsNV\0"): *fp_glGenPathsNV; +	glGenPerfMonitorsAMD = call_user_get_proc_address(user_get_proc_address, "glGenPerfMonitorsAMD\0"): *fp_glGenPerfMonitorsAMD; +	glGenProgramPipelines = call_user_get_proc_address(user_get_proc_address, "glGenProgramPipelines\0"): *fp_glGenProgramPipelines; +	glGenProgramPipelinesEXT = call_user_get_proc_address(user_get_proc_address, "glGenProgramPipelinesEXT\0"): *fp_glGenProgramPipelinesEXT; +	glGenQueries = call_user_get_proc_address(user_get_proc_address, "glGenQueries\0"): *fp_glGenQueries; +	glGenQueriesEXT = call_user_get_proc_address(user_get_proc_address, "glGenQueriesEXT\0"): *fp_glGenQueriesEXT; +	glGenRenderbuffers = call_user_get_proc_address(user_get_proc_address, "glGenRenderbuffers\0"): *fp_glGenRenderbuffers; +	glGenSamplers = call_user_get_proc_address(user_get_proc_address, "glGenSamplers\0"): *fp_glGenSamplers; +	glGenSemaphoresEXT = call_user_get_proc_address(user_get_proc_address, "glGenSemaphoresEXT\0"): *fp_glGenSemaphoresEXT; +	glGenTextures = call_user_get_proc_address(user_get_proc_address, "glGenTextures\0"): *fp_glGenTextures; +	glGenTransformFeedbacks = call_user_get_proc_address(user_get_proc_address, "glGenTransformFeedbacks\0"): *fp_glGenTransformFeedbacks; +	glGenVertexArrays = call_user_get_proc_address(user_get_proc_address, "glGenVertexArrays\0"): *fp_glGenVertexArrays; +	glGenVertexArraysOES = call_user_get_proc_address(user_get_proc_address, "glGenVertexArraysOES\0"): *fp_glGenVertexArraysOES; +	glGenerateMipmap = call_user_get_proc_address(user_get_proc_address, "glGenerateMipmap\0"): *fp_glGenerateMipmap; +	glGetActiveAttrib = call_user_get_proc_address(user_get_proc_address, "glGetActiveAttrib\0"): *fp_glGetActiveAttrib; +	glGetActiveUniform = call_user_get_proc_address(user_get_proc_address, "glGetActiveUniform\0"): *fp_glGetActiveUniform; +	glGetActiveUniformBlockName = call_user_get_proc_address(user_get_proc_address, "glGetActiveUniformBlockName\0"): *fp_glGetActiveUniformBlockName; +	glGetActiveUniformBlockiv = call_user_get_proc_address(user_get_proc_address, "glGetActiveUniformBlockiv\0"): *fp_glGetActiveUniformBlockiv; +	glGetActiveUniformsiv = call_user_get_proc_address(user_get_proc_address, "glGetActiveUniformsiv\0"): *fp_glGetActiveUniformsiv; +	glGetAttachedShaders = call_user_get_proc_address(user_get_proc_address, "glGetAttachedShaders\0"): *fp_glGetAttachedShaders; +	glGetAttribLocation = call_user_get_proc_address(user_get_proc_address, "glGetAttribLocation\0"): *fp_glGetAttribLocation; +	glGetBooleani_v = call_user_get_proc_address(user_get_proc_address, "glGetBooleani_v\0"): *fp_glGetBooleani_v; +	glGetBooleanv = call_user_get_proc_address(user_get_proc_address, "glGetBooleanv\0"): *fp_glGetBooleanv; +	glGetBufferParameteri64v = call_user_get_proc_address(user_get_proc_address, "glGetBufferParameteri64v\0"): *fp_glGetBufferParameteri64v; +	glGetBufferParameteriv = call_user_get_proc_address(user_get_proc_address, "glGetBufferParameteriv\0"): *fp_glGetBufferParameteriv; +	glGetBufferPointerv = call_user_get_proc_address(user_get_proc_address, "glGetBufferPointerv\0"): *fp_glGetBufferPointerv; +	glGetBufferPointervOES = call_user_get_proc_address(user_get_proc_address, "glGetBufferPointervOES\0"): *fp_glGetBufferPointervOES; +	glGetCoverageModulationTableNV = call_user_get_proc_address(user_get_proc_address, "glGetCoverageModulationTableNV\0"): *fp_glGetCoverageModulationTableNV; +	glGetDebugMessageLog = call_user_get_proc_address(user_get_proc_address, "glGetDebugMessageLog\0"): *fp_glGetDebugMessageLog; +	glGetDebugMessageLogKHR = call_user_get_proc_address(user_get_proc_address, "glGetDebugMessageLogKHR\0"): *fp_glGetDebugMessageLogKHR; +	glGetDriverControlStringQCOM = call_user_get_proc_address(user_get_proc_address, "glGetDriverControlStringQCOM\0"): *fp_glGetDriverControlStringQCOM; +	glGetDriverControlsQCOM = call_user_get_proc_address(user_get_proc_address, "glGetDriverControlsQCOM\0"): *fp_glGetDriverControlsQCOM; +	glGetError = call_user_get_proc_address(user_get_proc_address, "glGetError\0"): *fp_glGetError; +	glGetFenceivNV = call_user_get_proc_address(user_get_proc_address, "glGetFenceivNV\0"): *fp_glGetFenceivNV; +	glGetFirstPerfQueryIdINTEL = call_user_get_proc_address(user_get_proc_address, "glGetFirstPerfQueryIdINTEL\0"): *fp_glGetFirstPerfQueryIdINTEL; +	glGetFloati_vNV = call_user_get_proc_address(user_get_proc_address, "glGetFloati_vNV\0"): *fp_glGetFloati_vNV; +	glGetFloati_vOES = call_user_get_proc_address(user_get_proc_address, "glGetFloati_vOES\0"): *fp_glGetFloati_vOES; +	glGetFloatv = call_user_get_proc_address(user_get_proc_address, "glGetFloatv\0"): *fp_glGetFloatv; +	glGetFragDataIndexEXT = call_user_get_proc_address(user_get_proc_address, "glGetFragDataIndexEXT\0"): *fp_glGetFragDataIndexEXT; +	glGetFragDataLocation = call_user_get_proc_address(user_get_proc_address, "glGetFragDataLocation\0"): *fp_glGetFragDataLocation; +	glGetFragmentShadingRatesEXT = call_user_get_proc_address(user_get_proc_address, "glGetFragmentShadingRatesEXT\0"): *fp_glGetFragmentShadingRatesEXT; +	glGetFramebufferAttachmentParameteriv = call_user_get_proc_address(user_get_proc_address, "glGetFramebufferAttachmentParameteriv\0"): *fp_glGetFramebufferAttachmentParameteriv; +	glGetFramebufferParameteriv = call_user_get_proc_address(user_get_proc_address, "glGetFramebufferParameteriv\0"): *fp_glGetFramebufferParameteriv; +	glGetFramebufferParameterivMESA = call_user_get_proc_address(user_get_proc_address, "glGetFramebufferParameterivMESA\0"): *fp_glGetFramebufferParameterivMESA; +	glGetFramebufferPixelLocalStorageSizeEXT = call_user_get_proc_address(user_get_proc_address, "glGetFramebufferPixelLocalStorageSizeEXT\0"): *fp_glGetFramebufferPixelLocalStorageSizeEXT; +	glGetGraphicsResetStatus = call_user_get_proc_address(user_get_proc_address, "glGetGraphicsResetStatus\0"): *fp_glGetGraphicsResetStatus; +	glGetGraphicsResetStatusEXT = call_user_get_proc_address(user_get_proc_address, "glGetGraphicsResetStatusEXT\0"): *fp_glGetGraphicsResetStatusEXT; +	glGetGraphicsResetStatusKHR = call_user_get_proc_address(user_get_proc_address, "glGetGraphicsResetStatusKHR\0"): *fp_glGetGraphicsResetStatusKHR; +	glGetImageHandleNV = call_user_get_proc_address(user_get_proc_address, "glGetImageHandleNV\0"): *fp_glGetImageHandleNV; +	glGetInteger64i_v = call_user_get_proc_address(user_get_proc_address, "glGetInteger64i_v\0"): *fp_glGetInteger64i_v; +	glGetInteger64v = call_user_get_proc_address(user_get_proc_address, "glGetInteger64v\0"): *fp_glGetInteger64v; +	glGetInteger64vAPPLE = call_user_get_proc_address(user_get_proc_address, "glGetInteger64vAPPLE\0"): *fp_glGetInteger64vAPPLE; +	glGetInteger64vEXT = call_user_get_proc_address(user_get_proc_address, "glGetInteger64vEXT\0"): *fp_glGetInteger64vEXT; +	glGetIntegeri_v = call_user_get_proc_address(user_get_proc_address, "glGetIntegeri_v\0"): *fp_glGetIntegeri_v; +	glGetIntegeri_vEXT = call_user_get_proc_address(user_get_proc_address, "glGetIntegeri_vEXT\0"): *fp_glGetIntegeri_vEXT; +	glGetIntegerv = call_user_get_proc_address(user_get_proc_address, "glGetIntegerv\0"): *fp_glGetIntegerv; +	glGetInternalformatSampleivNV = call_user_get_proc_address(user_get_proc_address, "glGetInternalformatSampleivNV\0"): *fp_glGetInternalformatSampleivNV; +	glGetInternalformativ = call_user_get_proc_address(user_get_proc_address, "glGetInternalformativ\0"): *fp_glGetInternalformativ; +	glGetMemoryObjectDetachedResourcesuivNV = call_user_get_proc_address(user_get_proc_address, "glGetMemoryObjectDetachedResourcesuivNV\0"): *fp_glGetMemoryObjectDetachedResourcesuivNV; +	glGetMemoryObjectParameterivEXT = call_user_get_proc_address(user_get_proc_address, "glGetMemoryObjectParameterivEXT\0"): *fp_glGetMemoryObjectParameterivEXT; +	glGetMultisamplefv = call_user_get_proc_address(user_get_proc_address, "glGetMultisamplefv\0"): *fp_glGetMultisamplefv; +	glGetNextPerfQueryIdINTEL = call_user_get_proc_address(user_get_proc_address, "glGetNextPerfQueryIdINTEL\0"): *fp_glGetNextPerfQueryIdINTEL; +	glGetObjectLabel = call_user_get_proc_address(user_get_proc_address, "glGetObjectLabel\0"): *fp_glGetObjectLabel; +	glGetObjectLabelEXT = call_user_get_proc_address(user_get_proc_address, "glGetObjectLabelEXT\0"): *fp_glGetObjectLabelEXT; +	glGetObjectLabelKHR = call_user_get_proc_address(user_get_proc_address, "glGetObjectLabelKHR\0"): *fp_glGetObjectLabelKHR; +	glGetObjectPtrLabel = call_user_get_proc_address(user_get_proc_address, "glGetObjectPtrLabel\0"): *fp_glGetObjectPtrLabel; +	glGetObjectPtrLabelKHR = call_user_get_proc_address(user_get_proc_address, "glGetObjectPtrLabelKHR\0"): *fp_glGetObjectPtrLabelKHR; +	glGetPathCommandsNV = call_user_get_proc_address(user_get_proc_address, "glGetPathCommandsNV\0"): *fp_glGetPathCommandsNV; +	glGetPathCoordsNV = call_user_get_proc_address(user_get_proc_address, "glGetPathCoordsNV\0"): *fp_glGetPathCoordsNV; +	glGetPathDashArrayNV = call_user_get_proc_address(user_get_proc_address, "glGetPathDashArrayNV\0"): *fp_glGetPathDashArrayNV; +	glGetPathLengthNV = call_user_get_proc_address(user_get_proc_address, "glGetPathLengthNV\0"): *fp_glGetPathLengthNV; +	glGetPathMetricRangeNV = call_user_get_proc_address(user_get_proc_address, "glGetPathMetricRangeNV\0"): *fp_glGetPathMetricRangeNV; +	glGetPathMetricsNV = call_user_get_proc_address(user_get_proc_address, "glGetPathMetricsNV\0"): *fp_glGetPathMetricsNV; +	glGetPathParameterfvNV = call_user_get_proc_address(user_get_proc_address, "glGetPathParameterfvNV\0"): *fp_glGetPathParameterfvNV; +	glGetPathParameterivNV = call_user_get_proc_address(user_get_proc_address, "glGetPathParameterivNV\0"): *fp_glGetPathParameterivNV; +	glGetPathSpacingNV = call_user_get_proc_address(user_get_proc_address, "glGetPathSpacingNV\0"): *fp_glGetPathSpacingNV; +	glGetPerfCounterInfoINTEL = call_user_get_proc_address(user_get_proc_address, "glGetPerfCounterInfoINTEL\0"): *fp_glGetPerfCounterInfoINTEL; +	glGetPerfMonitorCounterDataAMD = call_user_get_proc_address(user_get_proc_address, "glGetPerfMonitorCounterDataAMD\0"): *fp_glGetPerfMonitorCounterDataAMD; +	glGetPerfMonitorCounterInfoAMD = call_user_get_proc_address(user_get_proc_address, "glGetPerfMonitorCounterInfoAMD\0"): *fp_glGetPerfMonitorCounterInfoAMD; +	glGetPerfMonitorCounterStringAMD = call_user_get_proc_address(user_get_proc_address, "glGetPerfMonitorCounterStringAMD\0"): *fp_glGetPerfMonitorCounterStringAMD; +	glGetPerfMonitorCountersAMD = call_user_get_proc_address(user_get_proc_address, "glGetPerfMonitorCountersAMD\0"): *fp_glGetPerfMonitorCountersAMD; +	glGetPerfMonitorGroupStringAMD = call_user_get_proc_address(user_get_proc_address, "glGetPerfMonitorGroupStringAMD\0"): *fp_glGetPerfMonitorGroupStringAMD; +	glGetPerfMonitorGroupsAMD = call_user_get_proc_address(user_get_proc_address, "glGetPerfMonitorGroupsAMD\0"): *fp_glGetPerfMonitorGroupsAMD; +	glGetPerfQueryDataINTEL = call_user_get_proc_address(user_get_proc_address, "glGetPerfQueryDataINTEL\0"): *fp_glGetPerfQueryDataINTEL; +	glGetPerfQueryIdByNameINTEL = call_user_get_proc_address(user_get_proc_address, "glGetPerfQueryIdByNameINTEL\0"): *fp_glGetPerfQueryIdByNameINTEL; +	glGetPerfQueryInfoINTEL = call_user_get_proc_address(user_get_proc_address, "glGetPerfQueryInfoINTEL\0"): *fp_glGetPerfQueryInfoINTEL; +	glGetPointerv = call_user_get_proc_address(user_get_proc_address, "glGetPointerv\0"): *fp_glGetPointerv; +	glGetPointervKHR = call_user_get_proc_address(user_get_proc_address, "glGetPointervKHR\0"): *fp_glGetPointervKHR; +	glGetProgramBinary = call_user_get_proc_address(user_get_proc_address, "glGetProgramBinary\0"): *fp_glGetProgramBinary; +	glGetProgramBinaryOES = call_user_get_proc_address(user_get_proc_address, "glGetProgramBinaryOES\0"): *fp_glGetProgramBinaryOES; +	glGetProgramInfoLog = call_user_get_proc_address(user_get_proc_address, "glGetProgramInfoLog\0"): *fp_glGetProgramInfoLog; +	glGetProgramInterfaceiv = call_user_get_proc_address(user_get_proc_address, "glGetProgramInterfaceiv\0"): *fp_glGetProgramInterfaceiv; +	glGetProgramPipelineInfoLog = call_user_get_proc_address(user_get_proc_address, "glGetProgramPipelineInfoLog\0"): *fp_glGetProgramPipelineInfoLog; +	glGetProgramPipelineInfoLogEXT = call_user_get_proc_address(user_get_proc_address, "glGetProgramPipelineInfoLogEXT\0"): *fp_glGetProgramPipelineInfoLogEXT; +	glGetProgramPipelineiv = call_user_get_proc_address(user_get_proc_address, "glGetProgramPipelineiv\0"): *fp_glGetProgramPipelineiv; +	glGetProgramPipelineivEXT = call_user_get_proc_address(user_get_proc_address, "glGetProgramPipelineivEXT\0"): *fp_glGetProgramPipelineivEXT; +	glGetProgramResourceIndex = call_user_get_proc_address(user_get_proc_address, "glGetProgramResourceIndex\0"): *fp_glGetProgramResourceIndex; +	glGetProgramResourceLocation = call_user_get_proc_address(user_get_proc_address, "glGetProgramResourceLocation\0"): *fp_glGetProgramResourceLocation; +	glGetProgramResourceLocationIndexEXT = call_user_get_proc_address(user_get_proc_address, "glGetProgramResourceLocationIndexEXT\0"): *fp_glGetProgramResourceLocationIndexEXT; +	glGetProgramResourceName = call_user_get_proc_address(user_get_proc_address, "glGetProgramResourceName\0"): *fp_glGetProgramResourceName; +	glGetProgramResourcefvNV = call_user_get_proc_address(user_get_proc_address, "glGetProgramResourcefvNV\0"): *fp_glGetProgramResourcefvNV; +	glGetProgramResourceiv = call_user_get_proc_address(user_get_proc_address, "glGetProgramResourceiv\0"): *fp_glGetProgramResourceiv; +	glGetProgramiv = call_user_get_proc_address(user_get_proc_address, "glGetProgramiv\0"): *fp_glGetProgramiv; +	glGetQueryObjecti64vEXT = call_user_get_proc_address(user_get_proc_address, "glGetQueryObjecti64vEXT\0"): *fp_glGetQueryObjecti64vEXT; +	glGetQueryObjectivEXT = call_user_get_proc_address(user_get_proc_address, "glGetQueryObjectivEXT\0"): *fp_glGetQueryObjectivEXT; +	glGetQueryObjectui64vEXT = call_user_get_proc_address(user_get_proc_address, "glGetQueryObjectui64vEXT\0"): *fp_glGetQueryObjectui64vEXT; +	glGetQueryObjectuiv = call_user_get_proc_address(user_get_proc_address, "glGetQueryObjectuiv\0"): *fp_glGetQueryObjectuiv; +	glGetQueryObjectuivEXT = call_user_get_proc_address(user_get_proc_address, "glGetQueryObjectuivEXT\0"): *fp_glGetQueryObjectuivEXT; +	glGetQueryiv = call_user_get_proc_address(user_get_proc_address, "glGetQueryiv\0"): *fp_glGetQueryiv; +	glGetQueryivEXT = call_user_get_proc_address(user_get_proc_address, "glGetQueryivEXT\0"): *fp_glGetQueryivEXT; +	glGetRenderbufferParameteriv = call_user_get_proc_address(user_get_proc_address, "glGetRenderbufferParameteriv\0"): *fp_glGetRenderbufferParameteriv; +	glGetSamplerParameterIiv = call_user_get_proc_address(user_get_proc_address, "glGetSamplerParameterIiv\0"): *fp_glGetSamplerParameterIiv; +	glGetSamplerParameterIivEXT = call_user_get_proc_address(user_get_proc_address, "glGetSamplerParameterIivEXT\0"): *fp_glGetSamplerParameterIivEXT; +	glGetSamplerParameterIivOES = call_user_get_proc_address(user_get_proc_address, "glGetSamplerParameterIivOES\0"): *fp_glGetSamplerParameterIivOES; +	glGetSamplerParameterIuiv = call_user_get_proc_address(user_get_proc_address, "glGetSamplerParameterIuiv\0"): *fp_glGetSamplerParameterIuiv; +	glGetSamplerParameterIuivEXT = call_user_get_proc_address(user_get_proc_address, "glGetSamplerParameterIuivEXT\0"): *fp_glGetSamplerParameterIuivEXT; +	glGetSamplerParameterIuivOES = call_user_get_proc_address(user_get_proc_address, "glGetSamplerParameterIuivOES\0"): *fp_glGetSamplerParameterIuivOES; +	glGetSamplerParameterfv = call_user_get_proc_address(user_get_proc_address, "glGetSamplerParameterfv\0"): *fp_glGetSamplerParameterfv; +	glGetSamplerParameteriv = call_user_get_proc_address(user_get_proc_address, "glGetSamplerParameteriv\0"): *fp_glGetSamplerParameteriv; +	glGetSemaphoreParameterivNV = call_user_get_proc_address(user_get_proc_address, "glGetSemaphoreParameterivNV\0"): *fp_glGetSemaphoreParameterivNV; +	glGetSemaphoreParameterui64vEXT = call_user_get_proc_address(user_get_proc_address, "glGetSemaphoreParameterui64vEXT\0"): *fp_glGetSemaphoreParameterui64vEXT; +	glGetShaderInfoLog = call_user_get_proc_address(user_get_proc_address, "glGetShaderInfoLog\0"): *fp_glGetShaderInfoLog; +	glGetShaderPrecisionFormat = call_user_get_proc_address(user_get_proc_address, "glGetShaderPrecisionFormat\0"): *fp_glGetShaderPrecisionFormat; +	glGetShaderSource = call_user_get_proc_address(user_get_proc_address, "glGetShaderSource\0"): *fp_glGetShaderSource; +	glGetShaderiv = call_user_get_proc_address(user_get_proc_address, "glGetShaderiv\0"): *fp_glGetShaderiv; +	glGetShadingRateImagePaletteNV = call_user_get_proc_address(user_get_proc_address, "glGetShadingRateImagePaletteNV\0"): *fp_glGetShadingRateImagePaletteNV; +	glGetShadingRateSampleLocationivNV = call_user_get_proc_address(user_get_proc_address, "glGetShadingRateSampleLocationivNV\0"): *fp_glGetShadingRateSampleLocationivNV; +	glGetString = call_user_get_proc_address(user_get_proc_address, "glGetString\0"): *fp_glGetString; +	glGetStringi = call_user_get_proc_address(user_get_proc_address, "glGetStringi\0"): *fp_glGetStringi; +	glGetSynciv = call_user_get_proc_address(user_get_proc_address, "glGetSynciv\0"): *fp_glGetSynciv; +	glGetSyncivAPPLE = call_user_get_proc_address(user_get_proc_address, "glGetSyncivAPPLE\0"): *fp_glGetSyncivAPPLE; +	glGetTexLevelParameterfv = call_user_get_proc_address(user_get_proc_address, "glGetTexLevelParameterfv\0"): *fp_glGetTexLevelParameterfv; +	glGetTexLevelParameteriv = call_user_get_proc_address(user_get_proc_address, "glGetTexLevelParameteriv\0"): *fp_glGetTexLevelParameteriv; +	glGetTexParameterIiv = call_user_get_proc_address(user_get_proc_address, "glGetTexParameterIiv\0"): *fp_glGetTexParameterIiv; +	glGetTexParameterIivEXT = call_user_get_proc_address(user_get_proc_address, "glGetTexParameterIivEXT\0"): *fp_glGetTexParameterIivEXT; +	glGetTexParameterIivOES = call_user_get_proc_address(user_get_proc_address, "glGetTexParameterIivOES\0"): *fp_glGetTexParameterIivOES; +	glGetTexParameterIuiv = call_user_get_proc_address(user_get_proc_address, "glGetTexParameterIuiv\0"): *fp_glGetTexParameterIuiv; +	glGetTexParameterIuivEXT = call_user_get_proc_address(user_get_proc_address, "glGetTexParameterIuivEXT\0"): *fp_glGetTexParameterIuivEXT; +	glGetTexParameterIuivOES = call_user_get_proc_address(user_get_proc_address, "glGetTexParameterIuivOES\0"): *fp_glGetTexParameterIuivOES; +	glGetTexParameterfv = call_user_get_proc_address(user_get_proc_address, "glGetTexParameterfv\0"): *fp_glGetTexParameterfv; +	glGetTexParameteriv = call_user_get_proc_address(user_get_proc_address, "glGetTexParameteriv\0"): *fp_glGetTexParameteriv; +	glGetTextureHandleIMG = call_user_get_proc_address(user_get_proc_address, "glGetTextureHandleIMG\0"): *fp_glGetTextureHandleIMG; +	glGetTextureHandleNV = call_user_get_proc_address(user_get_proc_address, "glGetTextureHandleNV\0"): *fp_glGetTextureHandleNV; +	glGetTextureSamplerHandleIMG = call_user_get_proc_address(user_get_proc_address, "glGetTextureSamplerHandleIMG\0"): *fp_glGetTextureSamplerHandleIMG; +	glGetTextureSamplerHandleNV = call_user_get_proc_address(user_get_proc_address, "glGetTextureSamplerHandleNV\0"): *fp_glGetTextureSamplerHandleNV; +	glGetTransformFeedbackVarying = call_user_get_proc_address(user_get_proc_address, "glGetTransformFeedbackVarying\0"): *fp_glGetTransformFeedbackVarying; +	glGetTranslatedShaderSourceANGLE = call_user_get_proc_address(user_get_proc_address, "glGetTranslatedShaderSourceANGLE\0"): *fp_glGetTranslatedShaderSourceANGLE; +	glGetUniformBlockIndex = call_user_get_proc_address(user_get_proc_address, "glGetUniformBlockIndex\0"): *fp_glGetUniformBlockIndex; +	glGetUniformIndices = call_user_get_proc_address(user_get_proc_address, "glGetUniformIndices\0"): *fp_glGetUniformIndices; +	glGetUniformLocation = call_user_get_proc_address(user_get_proc_address, "glGetUniformLocation\0"): *fp_glGetUniformLocation; +	glGetUniformfv = call_user_get_proc_address(user_get_proc_address, "glGetUniformfv\0"): *fp_glGetUniformfv; +	glGetUniformi64vNV = call_user_get_proc_address(user_get_proc_address, "glGetUniformi64vNV\0"): *fp_glGetUniformi64vNV; +	glGetUniformiv = call_user_get_proc_address(user_get_proc_address, "glGetUniformiv\0"): *fp_glGetUniformiv; +	glGetUniformuiv = call_user_get_proc_address(user_get_proc_address, "glGetUniformuiv\0"): *fp_glGetUniformuiv; +	glGetUnsignedBytei_vEXT = call_user_get_proc_address(user_get_proc_address, "glGetUnsignedBytei_vEXT\0"): *fp_glGetUnsignedBytei_vEXT; +	glGetUnsignedBytevEXT = call_user_get_proc_address(user_get_proc_address, "glGetUnsignedBytevEXT\0"): *fp_glGetUnsignedBytevEXT; +	glGetVertexAttribIiv = call_user_get_proc_address(user_get_proc_address, "glGetVertexAttribIiv\0"): *fp_glGetVertexAttribIiv; +	glGetVertexAttribIuiv = call_user_get_proc_address(user_get_proc_address, "glGetVertexAttribIuiv\0"): *fp_glGetVertexAttribIuiv; +	glGetVertexAttribPointerv = call_user_get_proc_address(user_get_proc_address, "glGetVertexAttribPointerv\0"): *fp_glGetVertexAttribPointerv; +	glGetVertexAttribfv = call_user_get_proc_address(user_get_proc_address, "glGetVertexAttribfv\0"): *fp_glGetVertexAttribfv; +	glGetVertexAttribiv = call_user_get_proc_address(user_get_proc_address, "glGetVertexAttribiv\0"): *fp_glGetVertexAttribiv; +	glGetVkProcAddrNV = call_user_get_proc_address(user_get_proc_address, "glGetVkProcAddrNV\0"): *fp_glGetVkProcAddrNV; +	glGetnUniformfv = call_user_get_proc_address(user_get_proc_address, "glGetnUniformfv\0"): *fp_glGetnUniformfv; +	glGetnUniformfvEXT = call_user_get_proc_address(user_get_proc_address, "glGetnUniformfvEXT\0"): *fp_glGetnUniformfvEXT; +	glGetnUniformfvKHR = call_user_get_proc_address(user_get_proc_address, "glGetnUniformfvKHR\0"): *fp_glGetnUniformfvKHR; +	glGetnUniformiv = call_user_get_proc_address(user_get_proc_address, "glGetnUniformiv\0"): *fp_glGetnUniformiv; +	glGetnUniformivEXT = call_user_get_proc_address(user_get_proc_address, "glGetnUniformivEXT\0"): *fp_glGetnUniformivEXT; +	glGetnUniformivKHR = call_user_get_proc_address(user_get_proc_address, "glGetnUniformivKHR\0"): *fp_glGetnUniformivKHR; +	glGetnUniformuiv = call_user_get_proc_address(user_get_proc_address, "glGetnUniformuiv\0"): *fp_glGetnUniformuiv; +	glGetnUniformuivKHR = call_user_get_proc_address(user_get_proc_address, "glGetnUniformuivKHR\0"): *fp_glGetnUniformuivKHR; +	glHint = call_user_get_proc_address(user_get_proc_address, "glHint\0"): *fp_glHint; +	glImportMemoryFdEXT = call_user_get_proc_address(user_get_proc_address, "glImportMemoryFdEXT\0"): *fp_glImportMemoryFdEXT; +	glImportMemoryWin32HandleEXT = call_user_get_proc_address(user_get_proc_address, "glImportMemoryWin32HandleEXT\0"): *fp_glImportMemoryWin32HandleEXT; +	glImportMemoryWin32NameEXT = call_user_get_proc_address(user_get_proc_address, "glImportMemoryWin32NameEXT\0"): *fp_glImportMemoryWin32NameEXT; +	glImportSemaphoreFdEXT = call_user_get_proc_address(user_get_proc_address, "glImportSemaphoreFdEXT\0"): *fp_glImportSemaphoreFdEXT; +	glImportSemaphoreWin32HandleEXT = call_user_get_proc_address(user_get_proc_address, "glImportSemaphoreWin32HandleEXT\0"): *fp_glImportSemaphoreWin32HandleEXT; +	glImportSemaphoreWin32NameEXT = call_user_get_proc_address(user_get_proc_address, "glImportSemaphoreWin32NameEXT\0"): *fp_glImportSemaphoreWin32NameEXT; +	glInsertEventMarkerEXT = call_user_get_proc_address(user_get_proc_address, "glInsertEventMarkerEXT\0"): *fp_glInsertEventMarkerEXT; +	glInterpolatePathsNV = call_user_get_proc_address(user_get_proc_address, "glInterpolatePathsNV\0"): *fp_glInterpolatePathsNV; +	glInvalidateFramebuffer = call_user_get_proc_address(user_get_proc_address, "glInvalidateFramebuffer\0"): *fp_glInvalidateFramebuffer; +	glInvalidateSubFramebuffer = call_user_get_proc_address(user_get_proc_address, "glInvalidateSubFramebuffer\0"): *fp_glInvalidateSubFramebuffer; +	glIsBuffer = call_user_get_proc_address(user_get_proc_address, "glIsBuffer\0"): *fp_glIsBuffer; +	glIsEnabled = call_user_get_proc_address(user_get_proc_address, "glIsEnabled\0"): *fp_glIsEnabled; +	glIsEnabledi = call_user_get_proc_address(user_get_proc_address, "glIsEnabledi\0"): *fp_glIsEnabledi; +	glIsEnablediEXT = call_user_get_proc_address(user_get_proc_address, "glIsEnablediEXT\0"): *fp_glIsEnablediEXT; +	glIsEnablediNV = call_user_get_proc_address(user_get_proc_address, "glIsEnablediNV\0"): *fp_glIsEnablediNV; +	glIsEnablediOES = call_user_get_proc_address(user_get_proc_address, "glIsEnablediOES\0"): *fp_glIsEnablediOES; +	glIsFenceNV = call_user_get_proc_address(user_get_proc_address, "glIsFenceNV\0"): *fp_glIsFenceNV; +	glIsFramebuffer = call_user_get_proc_address(user_get_proc_address, "glIsFramebuffer\0"): *fp_glIsFramebuffer; +	glIsImageHandleResidentNV = call_user_get_proc_address(user_get_proc_address, "glIsImageHandleResidentNV\0"): *fp_glIsImageHandleResidentNV; +	glIsMemoryObjectEXT = call_user_get_proc_address(user_get_proc_address, "glIsMemoryObjectEXT\0"): *fp_glIsMemoryObjectEXT; +	glIsPathNV = call_user_get_proc_address(user_get_proc_address, "glIsPathNV\0"): *fp_glIsPathNV; +	glIsPointInFillPathNV = call_user_get_proc_address(user_get_proc_address, "glIsPointInFillPathNV\0"): *fp_glIsPointInFillPathNV; +	glIsPointInStrokePathNV = call_user_get_proc_address(user_get_proc_address, "glIsPointInStrokePathNV\0"): *fp_glIsPointInStrokePathNV; +	glIsProgram = call_user_get_proc_address(user_get_proc_address, "glIsProgram\0"): *fp_glIsProgram; +	glIsProgramPipeline = call_user_get_proc_address(user_get_proc_address, "glIsProgramPipeline\0"): *fp_glIsProgramPipeline; +	glIsProgramPipelineEXT = call_user_get_proc_address(user_get_proc_address, "glIsProgramPipelineEXT\0"): *fp_glIsProgramPipelineEXT; +	glIsQuery = call_user_get_proc_address(user_get_proc_address, "glIsQuery\0"): *fp_glIsQuery; +	glIsQueryEXT = call_user_get_proc_address(user_get_proc_address, "glIsQueryEXT\0"): *fp_glIsQueryEXT; +	glIsRenderbuffer = call_user_get_proc_address(user_get_proc_address, "glIsRenderbuffer\0"): *fp_glIsRenderbuffer; +	glIsSampler = call_user_get_proc_address(user_get_proc_address, "glIsSampler\0"): *fp_glIsSampler; +	glIsSemaphoreEXT = call_user_get_proc_address(user_get_proc_address, "glIsSemaphoreEXT\0"): *fp_glIsSemaphoreEXT; +	glIsShader = call_user_get_proc_address(user_get_proc_address, "glIsShader\0"): *fp_glIsShader; +	glIsSync = call_user_get_proc_address(user_get_proc_address, "glIsSync\0"): *fp_glIsSync; +	glIsSyncAPPLE = call_user_get_proc_address(user_get_proc_address, "glIsSyncAPPLE\0"): *fp_glIsSyncAPPLE; +	glIsTexture = call_user_get_proc_address(user_get_proc_address, "glIsTexture\0"): *fp_glIsTexture; +	glIsTextureHandleResidentNV = call_user_get_proc_address(user_get_proc_address, "glIsTextureHandleResidentNV\0"): *fp_glIsTextureHandleResidentNV; +	glIsTransformFeedback = call_user_get_proc_address(user_get_proc_address, "glIsTransformFeedback\0"): *fp_glIsTransformFeedback; +	glIsVertexArray = call_user_get_proc_address(user_get_proc_address, "glIsVertexArray\0"): *fp_glIsVertexArray; +	glIsVertexArrayOES = call_user_get_proc_address(user_get_proc_address, "glIsVertexArrayOES\0"): *fp_glIsVertexArrayOES; +	glLabelObjectEXT = call_user_get_proc_address(user_get_proc_address, "glLabelObjectEXT\0"): *fp_glLabelObjectEXT; +	glLineWidth = call_user_get_proc_address(user_get_proc_address, "glLineWidth\0"): *fp_glLineWidth; +	glLinkProgram = call_user_get_proc_address(user_get_proc_address, "glLinkProgram\0"): *fp_glLinkProgram; +	glMakeImageHandleNonResidentNV = call_user_get_proc_address(user_get_proc_address, "glMakeImageHandleNonResidentNV\0"): *fp_glMakeImageHandleNonResidentNV; +	glMakeImageHandleResidentNV = call_user_get_proc_address(user_get_proc_address, "glMakeImageHandleResidentNV\0"): *fp_glMakeImageHandleResidentNV; +	glMakeTextureHandleNonResidentNV = call_user_get_proc_address(user_get_proc_address, "glMakeTextureHandleNonResidentNV\0"): *fp_glMakeTextureHandleNonResidentNV; +	glMakeTextureHandleResidentNV = call_user_get_proc_address(user_get_proc_address, "glMakeTextureHandleResidentNV\0"): *fp_glMakeTextureHandleResidentNV; +	glMapBufferOES = call_user_get_proc_address(user_get_proc_address, "glMapBufferOES\0"): *fp_glMapBufferOES; +	glMapBufferRange = call_user_get_proc_address(user_get_proc_address, "glMapBufferRange\0"): *fp_glMapBufferRange; +	glMapBufferRangeEXT = call_user_get_proc_address(user_get_proc_address, "glMapBufferRangeEXT\0"): *fp_glMapBufferRangeEXT; +	glMatrixFrustumEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixFrustumEXT\0"): *fp_glMatrixFrustumEXT; +	glMatrixLoad3x2fNV = call_user_get_proc_address(user_get_proc_address, "glMatrixLoad3x2fNV\0"): *fp_glMatrixLoad3x2fNV; +	glMatrixLoad3x3fNV = call_user_get_proc_address(user_get_proc_address, "glMatrixLoad3x3fNV\0"): *fp_glMatrixLoad3x3fNV; +	glMatrixLoadIdentityEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixLoadIdentityEXT\0"): *fp_glMatrixLoadIdentityEXT; +	glMatrixLoadTranspose3x3fNV = call_user_get_proc_address(user_get_proc_address, "glMatrixLoadTranspose3x3fNV\0"): *fp_glMatrixLoadTranspose3x3fNV; +	glMatrixLoadTransposedEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixLoadTransposedEXT\0"): *fp_glMatrixLoadTransposedEXT; +	glMatrixLoadTransposefEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixLoadTransposefEXT\0"): *fp_glMatrixLoadTransposefEXT; +	glMatrixLoaddEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixLoaddEXT\0"): *fp_glMatrixLoaddEXT; +	glMatrixLoadfEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixLoadfEXT\0"): *fp_glMatrixLoadfEXT; +	glMatrixMult3x2fNV = call_user_get_proc_address(user_get_proc_address, "glMatrixMult3x2fNV\0"): *fp_glMatrixMult3x2fNV; +	glMatrixMult3x3fNV = call_user_get_proc_address(user_get_proc_address, "glMatrixMult3x3fNV\0"): *fp_glMatrixMult3x3fNV; +	glMatrixMultTranspose3x3fNV = call_user_get_proc_address(user_get_proc_address, "glMatrixMultTranspose3x3fNV\0"): *fp_glMatrixMultTranspose3x3fNV; +	glMatrixMultTransposedEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixMultTransposedEXT\0"): *fp_glMatrixMultTransposedEXT; +	glMatrixMultTransposefEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixMultTransposefEXT\0"): *fp_glMatrixMultTransposefEXT; +	glMatrixMultdEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixMultdEXT\0"): *fp_glMatrixMultdEXT; +	glMatrixMultfEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixMultfEXT\0"): *fp_glMatrixMultfEXT; +	glMatrixOrthoEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixOrthoEXT\0"): *fp_glMatrixOrthoEXT; +	glMatrixPopEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixPopEXT\0"): *fp_glMatrixPopEXT; +	glMatrixPushEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixPushEXT\0"): *fp_glMatrixPushEXT; +	glMatrixRotatedEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixRotatedEXT\0"): *fp_glMatrixRotatedEXT; +	glMatrixRotatefEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixRotatefEXT\0"): *fp_glMatrixRotatefEXT; +	glMatrixScaledEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixScaledEXT\0"): *fp_glMatrixScaledEXT; +	glMatrixScalefEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixScalefEXT\0"): *fp_glMatrixScalefEXT; +	glMatrixTranslatedEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixTranslatedEXT\0"): *fp_glMatrixTranslatedEXT; +	glMatrixTranslatefEXT = call_user_get_proc_address(user_get_proc_address, "glMatrixTranslatefEXT\0"): *fp_glMatrixTranslatefEXT; +	glMaxShaderCompilerThreadsKHR = call_user_get_proc_address(user_get_proc_address, "glMaxShaderCompilerThreadsKHR\0"): *fp_glMaxShaderCompilerThreadsKHR; +	glMemoryBarrier = call_user_get_proc_address(user_get_proc_address, "glMemoryBarrier\0"): *fp_glMemoryBarrier; +	glMemoryBarrierByRegion = call_user_get_proc_address(user_get_proc_address, "glMemoryBarrierByRegion\0"): *fp_glMemoryBarrierByRegion; +	glMemoryObjectParameterivEXT = call_user_get_proc_address(user_get_proc_address, "glMemoryObjectParameterivEXT\0"): *fp_glMemoryObjectParameterivEXT; +	glMinSampleShading = call_user_get_proc_address(user_get_proc_address, "glMinSampleShading\0"): *fp_glMinSampleShading; +	glMinSampleShadingOES = call_user_get_proc_address(user_get_proc_address, "glMinSampleShadingOES\0"): *fp_glMinSampleShadingOES; +	glMultiDrawArraysEXT = call_user_get_proc_address(user_get_proc_address, "glMultiDrawArraysEXT\0"): *fp_glMultiDrawArraysEXT; +	glMultiDrawArraysIndirectEXT = call_user_get_proc_address(user_get_proc_address, "glMultiDrawArraysIndirectEXT\0"): *fp_glMultiDrawArraysIndirectEXT; +	glMultiDrawElementsBaseVertexEXT = call_user_get_proc_address(user_get_proc_address, "glMultiDrawElementsBaseVertexEXT\0"): *fp_glMultiDrawElementsBaseVertexEXT; +	glMultiDrawElementsEXT = call_user_get_proc_address(user_get_proc_address, "glMultiDrawElementsEXT\0"): *fp_glMultiDrawElementsEXT; +	glMultiDrawElementsIndirectEXT = call_user_get_proc_address(user_get_proc_address, "glMultiDrawElementsIndirectEXT\0"): *fp_glMultiDrawElementsIndirectEXT; +	glMultiDrawMeshTasksIndirectCountNV = call_user_get_proc_address(user_get_proc_address, "glMultiDrawMeshTasksIndirectCountNV\0"): *fp_glMultiDrawMeshTasksIndirectCountNV; +	glMultiDrawMeshTasksIndirectNV = call_user_get_proc_address(user_get_proc_address, "glMultiDrawMeshTasksIndirectNV\0"): *fp_glMultiDrawMeshTasksIndirectNV; +	glNamedBufferAttachMemoryNV = call_user_get_proc_address(user_get_proc_address, "glNamedBufferAttachMemoryNV\0"): *fp_glNamedBufferAttachMemoryNV; +	glNamedBufferPageCommitmentMemNV = call_user_get_proc_address(user_get_proc_address, "glNamedBufferPageCommitmentMemNV\0"): *fp_glNamedBufferPageCommitmentMemNV; +	glNamedBufferStorageExternalEXT = call_user_get_proc_address(user_get_proc_address, "glNamedBufferStorageExternalEXT\0"): *fp_glNamedBufferStorageExternalEXT; +	glNamedBufferStorageMemEXT = call_user_get_proc_address(user_get_proc_address, "glNamedBufferStorageMemEXT\0"): *fp_glNamedBufferStorageMemEXT; +	glNamedFramebufferSampleLocationsfvNV = call_user_get_proc_address(user_get_proc_address, "glNamedFramebufferSampleLocationsfvNV\0"): *fp_glNamedFramebufferSampleLocationsfvNV; +	glNamedRenderbufferStorageMultisampleAdvancedAMD = call_user_get_proc_address(user_get_proc_address, "glNamedRenderbufferStorageMultisampleAdvancedAMD\0"): *fp_glNamedRenderbufferStorageMultisampleAdvancedAMD; +	glObjectLabel = call_user_get_proc_address(user_get_proc_address, "glObjectLabel\0"): *fp_glObjectLabel; +	glObjectLabelKHR = call_user_get_proc_address(user_get_proc_address, "glObjectLabelKHR\0"): *fp_glObjectLabelKHR; +	glObjectPtrLabel = call_user_get_proc_address(user_get_proc_address, "glObjectPtrLabel\0"): *fp_glObjectPtrLabel; +	glObjectPtrLabelKHR = call_user_get_proc_address(user_get_proc_address, "glObjectPtrLabelKHR\0"): *fp_glObjectPtrLabelKHR; +	glPatchParameteri = call_user_get_proc_address(user_get_proc_address, "glPatchParameteri\0"): *fp_glPatchParameteri; +	glPatchParameteriEXT = call_user_get_proc_address(user_get_proc_address, "glPatchParameteriEXT\0"): *fp_glPatchParameteriEXT; +	glPatchParameteriOES = call_user_get_proc_address(user_get_proc_address, "glPatchParameteriOES\0"): *fp_glPatchParameteriOES; +	glPathCommandsNV = call_user_get_proc_address(user_get_proc_address, "glPathCommandsNV\0"): *fp_glPathCommandsNV; +	glPathCoordsNV = call_user_get_proc_address(user_get_proc_address, "glPathCoordsNV\0"): *fp_glPathCoordsNV; +	glPathCoverDepthFuncNV = call_user_get_proc_address(user_get_proc_address, "glPathCoverDepthFuncNV\0"): *fp_glPathCoverDepthFuncNV; +	glPathDashArrayNV = call_user_get_proc_address(user_get_proc_address, "glPathDashArrayNV\0"): *fp_glPathDashArrayNV; +	glPathGlyphIndexArrayNV = call_user_get_proc_address(user_get_proc_address, "glPathGlyphIndexArrayNV\0"): *fp_glPathGlyphIndexArrayNV; +	glPathGlyphIndexRangeNV = call_user_get_proc_address(user_get_proc_address, "glPathGlyphIndexRangeNV\0"): *fp_glPathGlyphIndexRangeNV; +	glPathGlyphRangeNV = call_user_get_proc_address(user_get_proc_address, "glPathGlyphRangeNV\0"): *fp_glPathGlyphRangeNV; +	glPathGlyphsNV = call_user_get_proc_address(user_get_proc_address, "glPathGlyphsNV\0"): *fp_glPathGlyphsNV; +	glPathMemoryGlyphIndexArrayNV = call_user_get_proc_address(user_get_proc_address, "glPathMemoryGlyphIndexArrayNV\0"): *fp_glPathMemoryGlyphIndexArrayNV; +	glPathParameterfNV = call_user_get_proc_address(user_get_proc_address, "glPathParameterfNV\0"): *fp_glPathParameterfNV; +	glPathParameterfvNV = call_user_get_proc_address(user_get_proc_address, "glPathParameterfvNV\0"): *fp_glPathParameterfvNV; +	glPathParameteriNV = call_user_get_proc_address(user_get_proc_address, "glPathParameteriNV\0"): *fp_glPathParameteriNV; +	glPathParameterivNV = call_user_get_proc_address(user_get_proc_address, "glPathParameterivNV\0"): *fp_glPathParameterivNV; +	glPathStencilDepthOffsetNV = call_user_get_proc_address(user_get_proc_address, "glPathStencilDepthOffsetNV\0"): *fp_glPathStencilDepthOffsetNV; +	glPathStencilFuncNV = call_user_get_proc_address(user_get_proc_address, "glPathStencilFuncNV\0"): *fp_glPathStencilFuncNV; +	glPathStringNV = call_user_get_proc_address(user_get_proc_address, "glPathStringNV\0"): *fp_glPathStringNV; +	glPathSubCommandsNV = call_user_get_proc_address(user_get_proc_address, "glPathSubCommandsNV\0"): *fp_glPathSubCommandsNV; +	glPathSubCoordsNV = call_user_get_proc_address(user_get_proc_address, "glPathSubCoordsNV\0"): *fp_glPathSubCoordsNV; +	glPauseTransformFeedback = call_user_get_proc_address(user_get_proc_address, "glPauseTransformFeedback\0"): *fp_glPauseTransformFeedback; +	glPixelStorei = call_user_get_proc_address(user_get_proc_address, "glPixelStorei\0"): *fp_glPixelStorei; +	glPointAlongPathNV = call_user_get_proc_address(user_get_proc_address, "glPointAlongPathNV\0"): *fp_glPointAlongPathNV; +	glPolygonModeNV = call_user_get_proc_address(user_get_proc_address, "glPolygonModeNV\0"): *fp_glPolygonModeNV; +	glPolygonOffset = call_user_get_proc_address(user_get_proc_address, "glPolygonOffset\0"): *fp_glPolygonOffset; +	glPolygonOffsetClampEXT = call_user_get_proc_address(user_get_proc_address, "glPolygonOffsetClampEXT\0"): *fp_glPolygonOffsetClampEXT; +	glPopDebugGroup = call_user_get_proc_address(user_get_proc_address, "glPopDebugGroup\0"): *fp_glPopDebugGroup; +	glPopDebugGroupKHR = call_user_get_proc_address(user_get_proc_address, "glPopDebugGroupKHR\0"): *fp_glPopDebugGroupKHR; +	glPopGroupMarkerEXT = call_user_get_proc_address(user_get_proc_address, "glPopGroupMarkerEXT\0"): *fp_glPopGroupMarkerEXT; +	glPrimitiveBoundingBox = call_user_get_proc_address(user_get_proc_address, "glPrimitiveBoundingBox\0"): *fp_glPrimitiveBoundingBox; +	glPrimitiveBoundingBoxEXT = call_user_get_proc_address(user_get_proc_address, "glPrimitiveBoundingBoxEXT\0"): *fp_glPrimitiveBoundingBoxEXT; +	glPrimitiveBoundingBoxOES = call_user_get_proc_address(user_get_proc_address, "glPrimitiveBoundingBoxOES\0"): *fp_glPrimitiveBoundingBoxOES; +	glProgramBinary = call_user_get_proc_address(user_get_proc_address, "glProgramBinary\0"): *fp_glProgramBinary; +	glProgramBinaryOES = call_user_get_proc_address(user_get_proc_address, "glProgramBinaryOES\0"): *fp_glProgramBinaryOES; +	glProgramParameteri = call_user_get_proc_address(user_get_proc_address, "glProgramParameteri\0"): *fp_glProgramParameteri; +	glProgramParameteriEXT = call_user_get_proc_address(user_get_proc_address, "glProgramParameteriEXT\0"): *fp_glProgramParameteriEXT; +	glProgramPathFragmentInputGenNV = call_user_get_proc_address(user_get_proc_address, "glProgramPathFragmentInputGenNV\0"): *fp_glProgramPathFragmentInputGenNV; +	glProgramUniform1f = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1f\0"): *fp_glProgramUniform1f; +	glProgramUniform1fEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1fEXT\0"): *fp_glProgramUniform1fEXT; +	glProgramUniform1fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1fv\0"): *fp_glProgramUniform1fv; +	glProgramUniform1fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1fvEXT\0"): *fp_glProgramUniform1fvEXT; +	glProgramUniform1i = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1i\0"): *fp_glProgramUniform1i; +	glProgramUniform1i64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1i64NV\0"): *fp_glProgramUniform1i64NV; +	glProgramUniform1i64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1i64vNV\0"): *fp_glProgramUniform1i64vNV; +	glProgramUniform1iEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1iEXT\0"): *fp_glProgramUniform1iEXT; +	glProgramUniform1iv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1iv\0"): *fp_glProgramUniform1iv; +	glProgramUniform1ivEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1ivEXT\0"): *fp_glProgramUniform1ivEXT; +	glProgramUniform1ui = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1ui\0"): *fp_glProgramUniform1ui; +	glProgramUniform1ui64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1ui64NV\0"): *fp_glProgramUniform1ui64NV; +	glProgramUniform1ui64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1ui64vNV\0"): *fp_glProgramUniform1ui64vNV; +	glProgramUniform1uiEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1uiEXT\0"): *fp_glProgramUniform1uiEXT; +	glProgramUniform1uiv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1uiv\0"): *fp_glProgramUniform1uiv; +	glProgramUniform1uivEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform1uivEXT\0"): *fp_glProgramUniform1uivEXT; +	glProgramUniform2f = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2f\0"): *fp_glProgramUniform2f; +	glProgramUniform2fEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2fEXT\0"): *fp_glProgramUniform2fEXT; +	glProgramUniform2fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2fv\0"): *fp_glProgramUniform2fv; +	glProgramUniform2fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2fvEXT\0"): *fp_glProgramUniform2fvEXT; +	glProgramUniform2i = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2i\0"): *fp_glProgramUniform2i; +	glProgramUniform2i64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2i64NV\0"): *fp_glProgramUniform2i64NV; +	glProgramUniform2i64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2i64vNV\0"): *fp_glProgramUniform2i64vNV; +	glProgramUniform2iEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2iEXT\0"): *fp_glProgramUniform2iEXT; +	glProgramUniform2iv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2iv\0"): *fp_glProgramUniform2iv; +	glProgramUniform2ivEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2ivEXT\0"): *fp_glProgramUniform2ivEXT; +	glProgramUniform2ui = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2ui\0"): *fp_glProgramUniform2ui; +	glProgramUniform2ui64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2ui64NV\0"): *fp_glProgramUniform2ui64NV; +	glProgramUniform2ui64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2ui64vNV\0"): *fp_glProgramUniform2ui64vNV; +	glProgramUniform2uiEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2uiEXT\0"): *fp_glProgramUniform2uiEXT; +	glProgramUniform2uiv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2uiv\0"): *fp_glProgramUniform2uiv; +	glProgramUniform2uivEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform2uivEXT\0"): *fp_glProgramUniform2uivEXT; +	glProgramUniform3f = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3f\0"): *fp_glProgramUniform3f; +	glProgramUniform3fEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3fEXT\0"): *fp_glProgramUniform3fEXT; +	glProgramUniform3fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3fv\0"): *fp_glProgramUniform3fv; +	glProgramUniform3fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3fvEXT\0"): *fp_glProgramUniform3fvEXT; +	glProgramUniform3i = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3i\0"): *fp_glProgramUniform3i; +	glProgramUniform3i64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3i64NV\0"): *fp_glProgramUniform3i64NV; +	glProgramUniform3i64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3i64vNV\0"): *fp_glProgramUniform3i64vNV; +	glProgramUniform3iEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3iEXT\0"): *fp_glProgramUniform3iEXT; +	glProgramUniform3iv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3iv\0"): *fp_glProgramUniform3iv; +	glProgramUniform3ivEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3ivEXT\0"): *fp_glProgramUniform3ivEXT; +	glProgramUniform3ui = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3ui\0"): *fp_glProgramUniform3ui; +	glProgramUniform3ui64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3ui64NV\0"): *fp_glProgramUniform3ui64NV; +	glProgramUniform3ui64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3ui64vNV\0"): *fp_glProgramUniform3ui64vNV; +	glProgramUniform3uiEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3uiEXT\0"): *fp_glProgramUniform3uiEXT; +	glProgramUniform3uiv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3uiv\0"): *fp_glProgramUniform3uiv; +	glProgramUniform3uivEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform3uivEXT\0"): *fp_glProgramUniform3uivEXT; +	glProgramUniform4f = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4f\0"): *fp_glProgramUniform4f; +	glProgramUniform4fEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4fEXT\0"): *fp_glProgramUniform4fEXT; +	glProgramUniform4fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4fv\0"): *fp_glProgramUniform4fv; +	glProgramUniform4fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4fvEXT\0"): *fp_glProgramUniform4fvEXT; +	glProgramUniform4i = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4i\0"): *fp_glProgramUniform4i; +	glProgramUniform4i64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4i64NV\0"): *fp_glProgramUniform4i64NV; +	glProgramUniform4i64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4i64vNV\0"): *fp_glProgramUniform4i64vNV; +	glProgramUniform4iEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4iEXT\0"): *fp_glProgramUniform4iEXT; +	glProgramUniform4iv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4iv\0"): *fp_glProgramUniform4iv; +	glProgramUniform4ivEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4ivEXT\0"): *fp_glProgramUniform4ivEXT; +	glProgramUniform4ui = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4ui\0"): *fp_glProgramUniform4ui; +	glProgramUniform4ui64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4ui64NV\0"): *fp_glProgramUniform4ui64NV; +	glProgramUniform4ui64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4ui64vNV\0"): *fp_glProgramUniform4ui64vNV; +	glProgramUniform4uiEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4uiEXT\0"): *fp_glProgramUniform4uiEXT; +	glProgramUniform4uiv = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4uiv\0"): *fp_glProgramUniform4uiv; +	glProgramUniform4uivEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniform4uivEXT\0"): *fp_glProgramUniform4uivEXT; +	glProgramUniformHandleui64IMG = call_user_get_proc_address(user_get_proc_address, "glProgramUniformHandleui64IMG\0"): *fp_glProgramUniformHandleui64IMG; +	glProgramUniformHandleui64NV = call_user_get_proc_address(user_get_proc_address, "glProgramUniformHandleui64NV\0"): *fp_glProgramUniformHandleui64NV; +	glProgramUniformHandleui64vIMG = call_user_get_proc_address(user_get_proc_address, "glProgramUniformHandleui64vIMG\0"): *fp_glProgramUniformHandleui64vIMG; +	glProgramUniformHandleui64vNV = call_user_get_proc_address(user_get_proc_address, "glProgramUniformHandleui64vNV\0"): *fp_glProgramUniformHandleui64vNV; +	glProgramUniformMatrix2fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix2fv\0"): *fp_glProgramUniformMatrix2fv; +	glProgramUniformMatrix2fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix2fvEXT\0"): *fp_glProgramUniformMatrix2fvEXT; +	glProgramUniformMatrix2x3fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix2x3fv\0"): *fp_glProgramUniformMatrix2x3fv; +	glProgramUniformMatrix2x3fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix2x3fvEXT\0"): *fp_glProgramUniformMatrix2x3fvEXT; +	glProgramUniformMatrix2x4fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix2x4fv\0"): *fp_glProgramUniformMatrix2x4fv; +	glProgramUniformMatrix2x4fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix2x4fvEXT\0"): *fp_glProgramUniformMatrix2x4fvEXT; +	glProgramUniformMatrix3fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix3fv\0"): *fp_glProgramUniformMatrix3fv; +	glProgramUniformMatrix3fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix3fvEXT\0"): *fp_glProgramUniformMatrix3fvEXT; +	glProgramUniformMatrix3x2fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix3x2fv\0"): *fp_glProgramUniformMatrix3x2fv; +	glProgramUniformMatrix3x2fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix3x2fvEXT\0"): *fp_glProgramUniformMatrix3x2fvEXT; +	glProgramUniformMatrix3x4fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix3x4fv\0"): *fp_glProgramUniformMatrix3x4fv; +	glProgramUniformMatrix3x4fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix3x4fvEXT\0"): *fp_glProgramUniformMatrix3x4fvEXT; +	glProgramUniformMatrix4fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix4fv\0"): *fp_glProgramUniformMatrix4fv; +	glProgramUniformMatrix4fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix4fvEXT\0"): *fp_glProgramUniformMatrix4fvEXT; +	glProgramUniformMatrix4x2fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix4x2fv\0"): *fp_glProgramUniformMatrix4x2fv; +	glProgramUniformMatrix4x2fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix4x2fvEXT\0"): *fp_glProgramUniformMatrix4x2fvEXT; +	glProgramUniformMatrix4x3fv = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix4x3fv\0"): *fp_glProgramUniformMatrix4x3fv; +	glProgramUniformMatrix4x3fvEXT = call_user_get_proc_address(user_get_proc_address, "glProgramUniformMatrix4x3fvEXT\0"): *fp_glProgramUniformMatrix4x3fvEXT; +	glPushDebugGroup = call_user_get_proc_address(user_get_proc_address, "glPushDebugGroup\0"): *fp_glPushDebugGroup; +	glPushDebugGroupKHR = call_user_get_proc_address(user_get_proc_address, "glPushDebugGroupKHR\0"): *fp_glPushDebugGroupKHR; +	glPushGroupMarkerEXT = call_user_get_proc_address(user_get_proc_address, "glPushGroupMarkerEXT\0"): *fp_glPushGroupMarkerEXT; +	glQueryCounterEXT = call_user_get_proc_address(user_get_proc_address, "glQueryCounterEXT\0"): *fp_glQueryCounterEXT; +	glRasterSamplesEXT = call_user_get_proc_address(user_get_proc_address, "glRasterSamplesEXT\0"): *fp_glRasterSamplesEXT; +	glReadBuffer = call_user_get_proc_address(user_get_proc_address, "glReadBuffer\0"): *fp_glReadBuffer; +	glReadBufferIndexedEXT = call_user_get_proc_address(user_get_proc_address, "glReadBufferIndexedEXT\0"): *fp_glReadBufferIndexedEXT; +	glReadBufferNV = call_user_get_proc_address(user_get_proc_address, "glReadBufferNV\0"): *fp_glReadBufferNV; +	glReadPixels = call_user_get_proc_address(user_get_proc_address, "glReadPixels\0"): *fp_glReadPixels; +	glReadnPixels = call_user_get_proc_address(user_get_proc_address, "glReadnPixels\0"): *fp_glReadnPixels; +	glReadnPixelsEXT = call_user_get_proc_address(user_get_proc_address, "glReadnPixelsEXT\0"): *fp_glReadnPixelsEXT; +	glReadnPixelsKHR = call_user_get_proc_address(user_get_proc_address, "glReadnPixelsKHR\0"): *fp_glReadnPixelsKHR; +	glReleaseKeyedMutexWin32EXT = call_user_get_proc_address(user_get_proc_address, "glReleaseKeyedMutexWin32EXT\0"): *fp_glReleaseKeyedMutexWin32EXT; +	glReleaseShaderCompiler = call_user_get_proc_address(user_get_proc_address, "glReleaseShaderCompiler\0"): *fp_glReleaseShaderCompiler; +	glRenderbufferStorage = call_user_get_proc_address(user_get_proc_address, "glRenderbufferStorage\0"): *fp_glRenderbufferStorage; +	glRenderbufferStorageMultisample = call_user_get_proc_address(user_get_proc_address, "glRenderbufferStorageMultisample\0"): *fp_glRenderbufferStorageMultisample; +	glRenderbufferStorageMultisampleANGLE = call_user_get_proc_address(user_get_proc_address, "glRenderbufferStorageMultisampleANGLE\0"): *fp_glRenderbufferStorageMultisampleANGLE; +	glRenderbufferStorageMultisampleAPPLE = call_user_get_proc_address(user_get_proc_address, "glRenderbufferStorageMultisampleAPPLE\0"): *fp_glRenderbufferStorageMultisampleAPPLE; +	glRenderbufferStorageMultisampleAdvancedAMD = call_user_get_proc_address(user_get_proc_address, "glRenderbufferStorageMultisampleAdvancedAMD\0"): *fp_glRenderbufferStorageMultisampleAdvancedAMD; +	glRenderbufferStorageMultisampleEXT = call_user_get_proc_address(user_get_proc_address, "glRenderbufferStorageMultisampleEXT\0"): *fp_glRenderbufferStorageMultisampleEXT; +	glRenderbufferStorageMultisampleIMG = call_user_get_proc_address(user_get_proc_address, "glRenderbufferStorageMultisampleIMG\0"): *fp_glRenderbufferStorageMultisampleIMG; +	glRenderbufferStorageMultisampleNV = call_user_get_proc_address(user_get_proc_address, "glRenderbufferStorageMultisampleNV\0"): *fp_glRenderbufferStorageMultisampleNV; +	glResetMemoryObjectParameterNV = call_user_get_proc_address(user_get_proc_address, "glResetMemoryObjectParameterNV\0"): *fp_glResetMemoryObjectParameterNV; +	glResolveDepthValuesNV = call_user_get_proc_address(user_get_proc_address, "glResolveDepthValuesNV\0"): *fp_glResolveDepthValuesNV; +	glResolveMultisampleFramebufferAPPLE = call_user_get_proc_address(user_get_proc_address, "glResolveMultisampleFramebufferAPPLE\0"): *fp_glResolveMultisampleFramebufferAPPLE; +	glResumeTransformFeedback = call_user_get_proc_address(user_get_proc_address, "glResumeTransformFeedback\0"): *fp_glResumeTransformFeedback; +	glSampleCoverage = call_user_get_proc_address(user_get_proc_address, "glSampleCoverage\0"): *fp_glSampleCoverage; +	glSampleMaski = call_user_get_proc_address(user_get_proc_address, "glSampleMaski\0"): *fp_glSampleMaski; +	glSamplerParameterIiv = call_user_get_proc_address(user_get_proc_address, "glSamplerParameterIiv\0"): *fp_glSamplerParameterIiv; +	glSamplerParameterIivEXT = call_user_get_proc_address(user_get_proc_address, "glSamplerParameterIivEXT\0"): *fp_glSamplerParameterIivEXT; +	glSamplerParameterIivOES = call_user_get_proc_address(user_get_proc_address, "glSamplerParameterIivOES\0"): *fp_glSamplerParameterIivOES; +	glSamplerParameterIuiv = call_user_get_proc_address(user_get_proc_address, "glSamplerParameterIuiv\0"): *fp_glSamplerParameterIuiv; +	glSamplerParameterIuivEXT = call_user_get_proc_address(user_get_proc_address, "glSamplerParameterIuivEXT\0"): *fp_glSamplerParameterIuivEXT; +	glSamplerParameterIuivOES = call_user_get_proc_address(user_get_proc_address, "glSamplerParameterIuivOES\0"): *fp_glSamplerParameterIuivOES; +	glSamplerParameterf = call_user_get_proc_address(user_get_proc_address, "glSamplerParameterf\0"): *fp_glSamplerParameterf; +	glSamplerParameterfv = call_user_get_proc_address(user_get_proc_address, "glSamplerParameterfv\0"): *fp_glSamplerParameterfv; +	glSamplerParameteri = call_user_get_proc_address(user_get_proc_address, "glSamplerParameteri\0"): *fp_glSamplerParameteri; +	glSamplerParameteriv = call_user_get_proc_address(user_get_proc_address, "glSamplerParameteriv\0"): *fp_glSamplerParameteriv; +	glScissor = call_user_get_proc_address(user_get_proc_address, "glScissor\0"): *fp_glScissor; +	glScissorArrayvNV = call_user_get_proc_address(user_get_proc_address, "glScissorArrayvNV\0"): *fp_glScissorArrayvNV; +	glScissorArrayvOES = call_user_get_proc_address(user_get_proc_address, "glScissorArrayvOES\0"): *fp_glScissorArrayvOES; +	glScissorExclusiveArrayvNV = call_user_get_proc_address(user_get_proc_address, "glScissorExclusiveArrayvNV\0"): *fp_glScissorExclusiveArrayvNV; +	glScissorExclusiveNV = call_user_get_proc_address(user_get_proc_address, "glScissorExclusiveNV\0"): *fp_glScissorExclusiveNV; +	glScissorIndexedNV = call_user_get_proc_address(user_get_proc_address, "glScissorIndexedNV\0"): *fp_glScissorIndexedNV; +	glScissorIndexedOES = call_user_get_proc_address(user_get_proc_address, "glScissorIndexedOES\0"): *fp_glScissorIndexedOES; +	glScissorIndexedvNV = call_user_get_proc_address(user_get_proc_address, "glScissorIndexedvNV\0"): *fp_glScissorIndexedvNV; +	glScissorIndexedvOES = call_user_get_proc_address(user_get_proc_address, "glScissorIndexedvOES\0"): *fp_glScissorIndexedvOES; +	glSelectPerfMonitorCountersAMD = call_user_get_proc_address(user_get_proc_address, "glSelectPerfMonitorCountersAMD\0"): *fp_glSelectPerfMonitorCountersAMD; +	glSemaphoreParameterivNV = call_user_get_proc_address(user_get_proc_address, "glSemaphoreParameterivNV\0"): *fp_glSemaphoreParameterivNV; +	glSemaphoreParameterui64vEXT = call_user_get_proc_address(user_get_proc_address, "glSemaphoreParameterui64vEXT\0"): *fp_glSemaphoreParameterui64vEXT; +	glSetFenceNV = call_user_get_proc_address(user_get_proc_address, "glSetFenceNV\0"): *fp_glSetFenceNV; +	glShaderBinary = call_user_get_proc_address(user_get_proc_address, "glShaderBinary\0"): *fp_glShaderBinary; +	glShaderSource = call_user_get_proc_address(user_get_proc_address, "glShaderSource\0"): *fp_glShaderSource; +	glShadingRateCombinerOpsEXT = call_user_get_proc_address(user_get_proc_address, "glShadingRateCombinerOpsEXT\0"): *fp_glShadingRateCombinerOpsEXT; +	glShadingRateEXT = call_user_get_proc_address(user_get_proc_address, "glShadingRateEXT\0"): *fp_glShadingRateEXT; +	glShadingRateImageBarrierNV = call_user_get_proc_address(user_get_proc_address, "glShadingRateImageBarrierNV\0"): *fp_glShadingRateImageBarrierNV; +	glShadingRateImagePaletteNV = call_user_get_proc_address(user_get_proc_address, "glShadingRateImagePaletteNV\0"): *fp_glShadingRateImagePaletteNV; +	glShadingRateQCOM = call_user_get_proc_address(user_get_proc_address, "glShadingRateQCOM\0"): *fp_glShadingRateQCOM; +	glShadingRateSampleOrderCustomNV = call_user_get_proc_address(user_get_proc_address, "glShadingRateSampleOrderCustomNV\0"): *fp_glShadingRateSampleOrderCustomNV; +	glShadingRateSampleOrderNV = call_user_get_proc_address(user_get_proc_address, "glShadingRateSampleOrderNV\0"): *fp_glShadingRateSampleOrderNV; +	glSignalSemaphoreEXT = call_user_get_proc_address(user_get_proc_address, "glSignalSemaphoreEXT\0"): *fp_glSignalSemaphoreEXT; +	glSignalVkFenceNV = call_user_get_proc_address(user_get_proc_address, "glSignalVkFenceNV\0"): *fp_glSignalVkFenceNV; +	glSignalVkSemaphoreNV = call_user_get_proc_address(user_get_proc_address, "glSignalVkSemaphoreNV\0"): *fp_glSignalVkSemaphoreNV; +	glStartTilingQCOM = call_user_get_proc_address(user_get_proc_address, "glStartTilingQCOM\0"): *fp_glStartTilingQCOM; +	glStencilFillPathInstancedNV = call_user_get_proc_address(user_get_proc_address, "glStencilFillPathInstancedNV\0"): *fp_glStencilFillPathInstancedNV; +	glStencilFillPathNV = call_user_get_proc_address(user_get_proc_address, "glStencilFillPathNV\0"): *fp_glStencilFillPathNV; +	glStencilFunc = call_user_get_proc_address(user_get_proc_address, "glStencilFunc\0"): *fp_glStencilFunc; +	glStencilFuncSeparate = call_user_get_proc_address(user_get_proc_address, "glStencilFuncSeparate\0"): *fp_glStencilFuncSeparate; +	glStencilMask = call_user_get_proc_address(user_get_proc_address, "glStencilMask\0"): *fp_glStencilMask; +	glStencilMaskSeparate = call_user_get_proc_address(user_get_proc_address, "glStencilMaskSeparate\0"): *fp_glStencilMaskSeparate; +	glStencilOp = call_user_get_proc_address(user_get_proc_address, "glStencilOp\0"): *fp_glStencilOp; +	glStencilOpSeparate = call_user_get_proc_address(user_get_proc_address, "glStencilOpSeparate\0"): *fp_glStencilOpSeparate; +	glStencilStrokePathInstancedNV = call_user_get_proc_address(user_get_proc_address, "glStencilStrokePathInstancedNV\0"): *fp_glStencilStrokePathInstancedNV; +	glStencilStrokePathNV = call_user_get_proc_address(user_get_proc_address, "glStencilStrokePathNV\0"): *fp_glStencilStrokePathNV; +	glStencilThenCoverFillPathInstancedNV = call_user_get_proc_address(user_get_proc_address, "glStencilThenCoverFillPathInstancedNV\0"): *fp_glStencilThenCoverFillPathInstancedNV; +	glStencilThenCoverFillPathNV = call_user_get_proc_address(user_get_proc_address, "glStencilThenCoverFillPathNV\0"): *fp_glStencilThenCoverFillPathNV; +	glStencilThenCoverStrokePathInstancedNV = call_user_get_proc_address(user_get_proc_address, "glStencilThenCoverStrokePathInstancedNV\0"): *fp_glStencilThenCoverStrokePathInstancedNV; +	glStencilThenCoverStrokePathNV = call_user_get_proc_address(user_get_proc_address, "glStencilThenCoverStrokePathNV\0"): *fp_glStencilThenCoverStrokePathNV; +	glSubpixelPrecisionBiasNV = call_user_get_proc_address(user_get_proc_address, "glSubpixelPrecisionBiasNV\0"): *fp_glSubpixelPrecisionBiasNV; +	glTestFenceNV = call_user_get_proc_address(user_get_proc_address, "glTestFenceNV\0"): *fp_glTestFenceNV; +	glTexAttachMemoryNV = call_user_get_proc_address(user_get_proc_address, "glTexAttachMemoryNV\0"): *fp_glTexAttachMemoryNV; +	glTexBuffer = call_user_get_proc_address(user_get_proc_address, "glTexBuffer\0"): *fp_glTexBuffer; +	glTexBufferEXT = call_user_get_proc_address(user_get_proc_address, "glTexBufferEXT\0"): *fp_glTexBufferEXT; +	glTexBufferOES = call_user_get_proc_address(user_get_proc_address, "glTexBufferOES\0"): *fp_glTexBufferOES; +	glTexBufferRange = call_user_get_proc_address(user_get_proc_address, "glTexBufferRange\0"): *fp_glTexBufferRange; +	glTexBufferRangeEXT = call_user_get_proc_address(user_get_proc_address, "glTexBufferRangeEXT\0"): *fp_glTexBufferRangeEXT; +	glTexBufferRangeOES = call_user_get_proc_address(user_get_proc_address, "glTexBufferRangeOES\0"): *fp_glTexBufferRangeOES; +	glTexEstimateMotionQCOM = call_user_get_proc_address(user_get_proc_address, "glTexEstimateMotionQCOM\0"): *fp_glTexEstimateMotionQCOM; +	glTexEstimateMotionRegionsQCOM = call_user_get_proc_address(user_get_proc_address, "glTexEstimateMotionRegionsQCOM\0"): *fp_glTexEstimateMotionRegionsQCOM; +	glTexImage2D = call_user_get_proc_address(user_get_proc_address, "glTexImage2D\0"): *fp_glTexImage2D; +	glTexImage3D = call_user_get_proc_address(user_get_proc_address, "glTexImage3D\0"): *fp_glTexImage3D; +	glTexImage3DOES = call_user_get_proc_address(user_get_proc_address, "glTexImage3DOES\0"): *fp_glTexImage3DOES; +	glTexPageCommitmentEXT = call_user_get_proc_address(user_get_proc_address, "glTexPageCommitmentEXT\0"): *fp_glTexPageCommitmentEXT; +	glTexPageCommitmentMemNV = call_user_get_proc_address(user_get_proc_address, "glTexPageCommitmentMemNV\0"): *fp_glTexPageCommitmentMemNV; +	glTexParameterIiv = call_user_get_proc_address(user_get_proc_address, "glTexParameterIiv\0"): *fp_glTexParameterIiv; +	glTexParameterIivEXT = call_user_get_proc_address(user_get_proc_address, "glTexParameterIivEXT\0"): *fp_glTexParameterIivEXT; +	glTexParameterIivOES = call_user_get_proc_address(user_get_proc_address, "glTexParameterIivOES\0"): *fp_glTexParameterIivOES; +	glTexParameterIuiv = call_user_get_proc_address(user_get_proc_address, "glTexParameterIuiv\0"): *fp_glTexParameterIuiv; +	glTexParameterIuivEXT = call_user_get_proc_address(user_get_proc_address, "glTexParameterIuivEXT\0"): *fp_glTexParameterIuivEXT; +	glTexParameterIuivOES = call_user_get_proc_address(user_get_proc_address, "glTexParameterIuivOES\0"): *fp_glTexParameterIuivOES; +	glTexParameterf = call_user_get_proc_address(user_get_proc_address, "glTexParameterf\0"): *fp_glTexParameterf; +	glTexParameterfv = call_user_get_proc_address(user_get_proc_address, "glTexParameterfv\0"): *fp_glTexParameterfv; +	glTexParameteri = call_user_get_proc_address(user_get_proc_address, "glTexParameteri\0"): *fp_glTexParameteri; +	glTexParameteriv = call_user_get_proc_address(user_get_proc_address, "glTexParameteriv\0"): *fp_glTexParameteriv; +	glTexStorage1DEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorage1DEXT\0"): *fp_glTexStorage1DEXT; +	glTexStorage2D = call_user_get_proc_address(user_get_proc_address, "glTexStorage2D\0"): *fp_glTexStorage2D; +	glTexStorage2DEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorage2DEXT\0"): *fp_glTexStorage2DEXT; +	glTexStorage2DMultisample = call_user_get_proc_address(user_get_proc_address, "glTexStorage2DMultisample\0"): *fp_glTexStorage2DMultisample; +	glTexStorage3D = call_user_get_proc_address(user_get_proc_address, "glTexStorage3D\0"): *fp_glTexStorage3D; +	glTexStorage3DEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorage3DEXT\0"): *fp_glTexStorage3DEXT; +	glTexStorage3DMultisample = call_user_get_proc_address(user_get_proc_address, "glTexStorage3DMultisample\0"): *fp_glTexStorage3DMultisample; +	glTexStorage3DMultisampleOES = call_user_get_proc_address(user_get_proc_address, "glTexStorage3DMultisampleOES\0"): *fp_glTexStorage3DMultisampleOES; +	glTexStorageAttribs2DEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorageAttribs2DEXT\0"): *fp_glTexStorageAttribs2DEXT; +	glTexStorageAttribs3DEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorageAttribs3DEXT\0"): *fp_glTexStorageAttribs3DEXT; +	glTexStorageMem2DEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorageMem2DEXT\0"): *fp_glTexStorageMem2DEXT; +	glTexStorageMem2DMultisampleEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorageMem2DMultisampleEXT\0"): *fp_glTexStorageMem2DMultisampleEXT; +	glTexStorageMem3DEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorageMem3DEXT\0"): *fp_glTexStorageMem3DEXT; +	glTexStorageMem3DMultisampleEXT = call_user_get_proc_address(user_get_proc_address, "glTexStorageMem3DMultisampleEXT\0"): *fp_glTexStorageMem3DMultisampleEXT; +	glTexSubImage2D = call_user_get_proc_address(user_get_proc_address, "glTexSubImage2D\0"): *fp_glTexSubImage2D; +	glTexSubImage3D = call_user_get_proc_address(user_get_proc_address, "glTexSubImage3D\0"): *fp_glTexSubImage3D; +	glTexSubImage3DOES = call_user_get_proc_address(user_get_proc_address, "glTexSubImage3DOES\0"): *fp_glTexSubImage3DOES; +	glTextureAttachMemoryNV = call_user_get_proc_address(user_get_proc_address, "glTextureAttachMemoryNV\0"): *fp_glTextureAttachMemoryNV; +	glTextureFoveationParametersQCOM = call_user_get_proc_address(user_get_proc_address, "glTextureFoveationParametersQCOM\0"): *fp_glTextureFoveationParametersQCOM; +	glTexturePageCommitmentMemNV = call_user_get_proc_address(user_get_proc_address, "glTexturePageCommitmentMemNV\0"): *fp_glTexturePageCommitmentMemNV; +	glTextureStorage1DEXT = call_user_get_proc_address(user_get_proc_address, "glTextureStorage1DEXT\0"): *fp_glTextureStorage1DEXT; +	glTextureStorage2DEXT = call_user_get_proc_address(user_get_proc_address, "glTextureStorage2DEXT\0"): *fp_glTextureStorage2DEXT; +	glTextureStorage3DEXT = call_user_get_proc_address(user_get_proc_address, "glTextureStorage3DEXT\0"): *fp_glTextureStorage3DEXT; +	glTextureStorageMem2DEXT = call_user_get_proc_address(user_get_proc_address, "glTextureStorageMem2DEXT\0"): *fp_glTextureStorageMem2DEXT; +	glTextureStorageMem2DMultisampleEXT = call_user_get_proc_address(user_get_proc_address, "glTextureStorageMem2DMultisampleEXT\0"): *fp_glTextureStorageMem2DMultisampleEXT; +	glTextureStorageMem3DEXT = call_user_get_proc_address(user_get_proc_address, "glTextureStorageMem3DEXT\0"): *fp_glTextureStorageMem3DEXT; +	glTextureStorageMem3DMultisampleEXT = call_user_get_proc_address(user_get_proc_address, "glTextureStorageMem3DMultisampleEXT\0"): *fp_glTextureStorageMem3DMultisampleEXT; +	glTextureViewEXT = call_user_get_proc_address(user_get_proc_address, "glTextureViewEXT\0"): *fp_glTextureViewEXT; +	glTextureViewOES = call_user_get_proc_address(user_get_proc_address, "glTextureViewOES\0"): *fp_glTextureViewOES; +	glTransformFeedbackVaryings = call_user_get_proc_address(user_get_proc_address, "glTransformFeedbackVaryings\0"): *fp_glTransformFeedbackVaryings; +	glTransformPathNV = call_user_get_proc_address(user_get_proc_address, "glTransformPathNV\0"): *fp_glTransformPathNV; +	glUniform1f = call_user_get_proc_address(user_get_proc_address, "glUniform1f\0"): *fp_glUniform1f; +	glUniform1fv = call_user_get_proc_address(user_get_proc_address, "glUniform1fv\0"): *fp_glUniform1fv; +	glUniform1i = call_user_get_proc_address(user_get_proc_address, "glUniform1i\0"): *fp_glUniform1i; +	glUniform1i64NV = call_user_get_proc_address(user_get_proc_address, "glUniform1i64NV\0"): *fp_glUniform1i64NV; +	glUniform1i64vNV = call_user_get_proc_address(user_get_proc_address, "glUniform1i64vNV\0"): *fp_glUniform1i64vNV; +	glUniform1iv = call_user_get_proc_address(user_get_proc_address, "glUniform1iv\0"): *fp_glUniform1iv; +	glUniform1ui = call_user_get_proc_address(user_get_proc_address, "glUniform1ui\0"): *fp_glUniform1ui; +	glUniform1ui64NV = call_user_get_proc_address(user_get_proc_address, "glUniform1ui64NV\0"): *fp_glUniform1ui64NV; +	glUniform1ui64vNV = call_user_get_proc_address(user_get_proc_address, "glUniform1ui64vNV\0"): *fp_glUniform1ui64vNV; +	glUniform1uiv = call_user_get_proc_address(user_get_proc_address, "glUniform1uiv\0"): *fp_glUniform1uiv; +	glUniform2f = call_user_get_proc_address(user_get_proc_address, "glUniform2f\0"): *fp_glUniform2f; +	glUniform2fv = call_user_get_proc_address(user_get_proc_address, "glUniform2fv\0"): *fp_glUniform2fv; +	glUniform2i = call_user_get_proc_address(user_get_proc_address, "glUniform2i\0"): *fp_glUniform2i; +	glUniform2i64NV = call_user_get_proc_address(user_get_proc_address, "glUniform2i64NV\0"): *fp_glUniform2i64NV; +	glUniform2i64vNV = call_user_get_proc_address(user_get_proc_address, "glUniform2i64vNV\0"): *fp_glUniform2i64vNV; +	glUniform2iv = call_user_get_proc_address(user_get_proc_address, "glUniform2iv\0"): *fp_glUniform2iv; +	glUniform2ui = call_user_get_proc_address(user_get_proc_address, "glUniform2ui\0"): *fp_glUniform2ui; +	glUniform2ui64NV = call_user_get_proc_address(user_get_proc_address, "glUniform2ui64NV\0"): *fp_glUniform2ui64NV; +	glUniform2ui64vNV = call_user_get_proc_address(user_get_proc_address, "glUniform2ui64vNV\0"): *fp_glUniform2ui64vNV; +	glUniform2uiv = call_user_get_proc_address(user_get_proc_address, "glUniform2uiv\0"): *fp_glUniform2uiv; +	glUniform3f = call_user_get_proc_address(user_get_proc_address, "glUniform3f\0"): *fp_glUniform3f; +	glUniform3fv = call_user_get_proc_address(user_get_proc_address, "glUniform3fv\0"): *fp_glUniform3fv; +	glUniform3i = call_user_get_proc_address(user_get_proc_address, "glUniform3i\0"): *fp_glUniform3i; +	glUniform3i64NV = call_user_get_proc_address(user_get_proc_address, "glUniform3i64NV\0"): *fp_glUniform3i64NV; +	glUniform3i64vNV = call_user_get_proc_address(user_get_proc_address, "glUniform3i64vNV\0"): *fp_glUniform3i64vNV; +	glUniform3iv = call_user_get_proc_address(user_get_proc_address, "glUniform3iv\0"): *fp_glUniform3iv; +	glUniform3ui = call_user_get_proc_address(user_get_proc_address, "glUniform3ui\0"): *fp_glUniform3ui; +	glUniform3ui64NV = call_user_get_proc_address(user_get_proc_address, "glUniform3ui64NV\0"): *fp_glUniform3ui64NV; +	glUniform3ui64vNV = call_user_get_proc_address(user_get_proc_address, "glUniform3ui64vNV\0"): *fp_glUniform3ui64vNV; +	glUniform3uiv = call_user_get_proc_address(user_get_proc_address, "glUniform3uiv\0"): *fp_glUniform3uiv; +	glUniform4f = call_user_get_proc_address(user_get_proc_address, "glUniform4f\0"): *fp_glUniform4f; +	glUniform4fv = call_user_get_proc_address(user_get_proc_address, "glUniform4fv\0"): *fp_glUniform4fv; +	glUniform4i = call_user_get_proc_address(user_get_proc_address, "glUniform4i\0"): *fp_glUniform4i; +	glUniform4i64NV = call_user_get_proc_address(user_get_proc_address, "glUniform4i64NV\0"): *fp_glUniform4i64NV; +	glUniform4i64vNV = call_user_get_proc_address(user_get_proc_address, "glUniform4i64vNV\0"): *fp_glUniform4i64vNV; +	glUniform4iv = call_user_get_proc_address(user_get_proc_address, "glUniform4iv\0"): *fp_glUniform4iv; +	glUniform4ui = call_user_get_proc_address(user_get_proc_address, "glUniform4ui\0"): *fp_glUniform4ui; +	glUniform4ui64NV = call_user_get_proc_address(user_get_proc_address, "glUniform4ui64NV\0"): *fp_glUniform4ui64NV; +	glUniform4ui64vNV = call_user_get_proc_address(user_get_proc_address, "glUniform4ui64vNV\0"): *fp_glUniform4ui64vNV; +	glUniform4uiv = call_user_get_proc_address(user_get_proc_address, "glUniform4uiv\0"): *fp_glUniform4uiv; +	glUniformBlockBinding = call_user_get_proc_address(user_get_proc_address, "glUniformBlockBinding\0"): *fp_glUniformBlockBinding; +	glUniformHandleui64IMG = call_user_get_proc_address(user_get_proc_address, "glUniformHandleui64IMG\0"): *fp_glUniformHandleui64IMG; +	glUniformHandleui64NV = call_user_get_proc_address(user_get_proc_address, "glUniformHandleui64NV\0"): *fp_glUniformHandleui64NV; +	glUniformHandleui64vIMG = call_user_get_proc_address(user_get_proc_address, "glUniformHandleui64vIMG\0"): *fp_glUniformHandleui64vIMG; +	glUniformHandleui64vNV = call_user_get_proc_address(user_get_proc_address, "glUniformHandleui64vNV\0"): *fp_glUniformHandleui64vNV; +	glUniformMatrix2fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix2fv\0"): *fp_glUniformMatrix2fv; +	glUniformMatrix2x3fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix2x3fv\0"): *fp_glUniformMatrix2x3fv; +	glUniformMatrix2x3fvNV = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix2x3fvNV\0"): *fp_glUniformMatrix2x3fvNV; +	glUniformMatrix2x4fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix2x4fv\0"): *fp_glUniformMatrix2x4fv; +	glUniformMatrix2x4fvNV = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix2x4fvNV\0"): *fp_glUniformMatrix2x4fvNV; +	glUniformMatrix3fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix3fv\0"): *fp_glUniformMatrix3fv; +	glUniformMatrix3x2fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix3x2fv\0"): *fp_glUniformMatrix3x2fv; +	glUniformMatrix3x2fvNV = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix3x2fvNV\0"): *fp_glUniformMatrix3x2fvNV; +	glUniformMatrix3x4fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix3x4fv\0"): *fp_glUniformMatrix3x4fv; +	glUniformMatrix3x4fvNV = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix3x4fvNV\0"): *fp_glUniformMatrix3x4fvNV; +	glUniformMatrix4fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix4fv\0"): *fp_glUniformMatrix4fv; +	glUniformMatrix4x2fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix4x2fv\0"): *fp_glUniformMatrix4x2fv; +	glUniformMatrix4x2fvNV = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix4x2fvNV\0"): *fp_glUniformMatrix4x2fvNV; +	glUniformMatrix4x3fv = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix4x3fv\0"): *fp_glUniformMatrix4x3fv; +	glUniformMatrix4x3fvNV = call_user_get_proc_address(user_get_proc_address, "glUniformMatrix4x3fvNV\0"): *fp_glUniformMatrix4x3fvNV; +	glUnmapBuffer = call_user_get_proc_address(user_get_proc_address, "glUnmapBuffer\0"): *fp_glUnmapBuffer; +	glUnmapBufferOES = call_user_get_proc_address(user_get_proc_address, "glUnmapBufferOES\0"): *fp_glUnmapBufferOES; +	glUseProgram = call_user_get_proc_address(user_get_proc_address, "glUseProgram\0"): *fp_glUseProgram; +	glUseProgramStages = call_user_get_proc_address(user_get_proc_address, "glUseProgramStages\0"): *fp_glUseProgramStages; +	glUseProgramStagesEXT = call_user_get_proc_address(user_get_proc_address, "glUseProgramStagesEXT\0"): *fp_glUseProgramStagesEXT; +	glValidateProgram = call_user_get_proc_address(user_get_proc_address, "glValidateProgram\0"): *fp_glValidateProgram; +	glValidateProgramPipeline = call_user_get_proc_address(user_get_proc_address, "glValidateProgramPipeline\0"): *fp_glValidateProgramPipeline; +	glValidateProgramPipelineEXT = call_user_get_proc_address(user_get_proc_address, "glValidateProgramPipelineEXT\0"): *fp_glValidateProgramPipelineEXT; +	glVertexAttrib1f = call_user_get_proc_address(user_get_proc_address, "glVertexAttrib1f\0"): *fp_glVertexAttrib1f; +	glVertexAttrib1fv = call_user_get_proc_address(user_get_proc_address, "glVertexAttrib1fv\0"): *fp_glVertexAttrib1fv; +	glVertexAttrib2f = call_user_get_proc_address(user_get_proc_address, "glVertexAttrib2f\0"): *fp_glVertexAttrib2f; +	glVertexAttrib2fv = call_user_get_proc_address(user_get_proc_address, "glVertexAttrib2fv\0"): *fp_glVertexAttrib2fv; +	glVertexAttrib3f = call_user_get_proc_address(user_get_proc_address, "glVertexAttrib3f\0"): *fp_glVertexAttrib3f; +	glVertexAttrib3fv = call_user_get_proc_address(user_get_proc_address, "glVertexAttrib3fv\0"): *fp_glVertexAttrib3fv; +	glVertexAttrib4f = call_user_get_proc_address(user_get_proc_address, "glVertexAttrib4f\0"): *fp_glVertexAttrib4f; +	glVertexAttrib4fv = call_user_get_proc_address(user_get_proc_address, "glVertexAttrib4fv\0"): *fp_glVertexAttrib4fv; +	glVertexAttribBinding = call_user_get_proc_address(user_get_proc_address, "glVertexAttribBinding\0"): *fp_glVertexAttribBinding; +	glVertexAttribDivisor = call_user_get_proc_address(user_get_proc_address, "glVertexAttribDivisor\0"): *fp_glVertexAttribDivisor; +	glVertexAttribDivisorANGLE = call_user_get_proc_address(user_get_proc_address, "glVertexAttribDivisorANGLE\0"): *fp_glVertexAttribDivisorANGLE; +	glVertexAttribDivisorEXT = call_user_get_proc_address(user_get_proc_address, "glVertexAttribDivisorEXT\0"): *fp_glVertexAttribDivisorEXT; +	glVertexAttribDivisorNV = call_user_get_proc_address(user_get_proc_address, "glVertexAttribDivisorNV\0"): *fp_glVertexAttribDivisorNV; +	glVertexAttribFormat = call_user_get_proc_address(user_get_proc_address, "glVertexAttribFormat\0"): *fp_glVertexAttribFormat; +	glVertexAttribI4i = call_user_get_proc_address(user_get_proc_address, "glVertexAttribI4i\0"): *fp_glVertexAttribI4i; +	glVertexAttribI4iv = call_user_get_proc_address(user_get_proc_address, "glVertexAttribI4iv\0"): *fp_glVertexAttribI4iv; +	glVertexAttribI4ui = call_user_get_proc_address(user_get_proc_address, "glVertexAttribI4ui\0"): *fp_glVertexAttribI4ui; +	glVertexAttribI4uiv = call_user_get_proc_address(user_get_proc_address, "glVertexAttribI4uiv\0"): *fp_glVertexAttribI4uiv; +	glVertexAttribIFormat = call_user_get_proc_address(user_get_proc_address, "glVertexAttribIFormat\0"): *fp_glVertexAttribIFormat; +	glVertexAttribIPointer = call_user_get_proc_address(user_get_proc_address, "glVertexAttribIPointer\0"): *fp_glVertexAttribIPointer; +	glVertexAttribPointer = call_user_get_proc_address(user_get_proc_address, "glVertexAttribPointer\0"): *fp_glVertexAttribPointer; +	glVertexBindingDivisor = call_user_get_proc_address(user_get_proc_address, "glVertexBindingDivisor\0"): *fp_glVertexBindingDivisor; +	glViewport = call_user_get_proc_address(user_get_proc_address, "glViewport\0"): *fp_glViewport; +	glViewportArrayvNV = call_user_get_proc_address(user_get_proc_address, "glViewportArrayvNV\0"): *fp_glViewportArrayvNV; +	glViewportArrayvOES = call_user_get_proc_address(user_get_proc_address, "glViewportArrayvOES\0"): *fp_glViewportArrayvOES; +	glViewportIndexedfNV = call_user_get_proc_address(user_get_proc_address, "glViewportIndexedfNV\0"): *fp_glViewportIndexedfNV; +	glViewportIndexedfOES = call_user_get_proc_address(user_get_proc_address, "glViewportIndexedfOES\0"): *fp_glViewportIndexedfOES; +	glViewportIndexedfvNV = call_user_get_proc_address(user_get_proc_address, "glViewportIndexedfvNV\0"): *fp_glViewportIndexedfvNV; +	glViewportIndexedfvOES = call_user_get_proc_address(user_get_proc_address, "glViewportIndexedfvOES\0"): *fp_glViewportIndexedfvOES; +	glViewportPositionWScaleNV = call_user_get_proc_address(user_get_proc_address, "glViewportPositionWScaleNV\0"): *fp_glViewportPositionWScaleNV; +	glViewportSwizzleNV = call_user_get_proc_address(user_get_proc_address, "glViewportSwizzleNV\0"): *fp_glViewportSwizzleNV; +	glWaitSemaphoreEXT = call_user_get_proc_address(user_get_proc_address, "glWaitSemaphoreEXT\0"): *fp_glWaitSemaphoreEXT; +	glWaitSync = call_user_get_proc_address(user_get_proc_address, "glWaitSync\0"): *fp_glWaitSync; +	glWaitSyncAPPLE = call_user_get_proc_address(user_get_proc_address, "glWaitSyncAPPLE\0"): *fp_glWaitSyncAPPLE; +	glWaitVkSemaphoreNV = call_user_get_proc_address(user_get_proc_address, "glWaitVkSemaphoreNV\0"): *fp_glWaitVkSemaphoreNV; +	glWeightPathsNV = call_user_get_proc_address(user_get_proc_address, "glWeightPathsNV\0"): *fp_glWeightPathsNV; +	glWindowRectanglesEXT = call_user_get_proc_address(user_get_proc_address, "glWindowRectanglesEXT\0"): *fp_glWindowRectanglesEXT; +}; diff --git a/glm/LICENSE b/glm/LICENSE new file mode 100644 index 0000000..69b6947 --- /dev/null +++ b/glm/LICENSE @@ -0,0 +1,8 @@ +Copyright (c) 2022 Vlad-Stefan Harbuz <vlad@vladh.net> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +The software is provided "as is" and the author disclaims all warranties +with regard to this software. diff --git a/glm/affine.ha b/glm/affine.ha new file mode 100644 index 0000000..e36cdd9 --- /dev/null +++ b/glm/affine.ha @@ -0,0 +1,80 @@ +use math; + +export fn translation_make(v: *v3) m4 = { +	const mat = m4_new_ident(); +	v3_copy_to(v, m4_col(&mat, 3): *v3); +	return mat; +}; + +export fn translate(m: *m4, v: *v3) void = { +	const mat = translation_make(v); +	const orig = *m; +	m4_mul_to(&mat, &orig, m); +}; + +export fn rotation_make(angle: f32, axis: *v3) m4 = { +	const r = m4_new_ident(); +	const c = math::cosf64(angle): f32; + +	let axisn = v3_new_zero(); +	let v = v3_new_zero(); +	let vs = v3_new_zero(); + +	v3_normalize_to(axis, &axisn); +	v3_scale_to(&axisn, 1.0 - c, &v); +	v3_scale_to(&axisn, math::sinf64(angle): f32, &vs); + +	v3_scale_to(&axisn, v[0], m4_col(&r, 0): *v3); +	v3_scale_to(&axisn, v[1], m4_col(&r, 1): *v3); +	v3_scale_to(&axisn, v[2], m4_col(&r, 2): *v3); + +	r[0][0] += c; +	r[1][0] -= vs[2]; +	r[2][0] += vs[1]; + +	r[0][1] += vs[2]; +	r[1][1] += c; +	r[2][1] -= vs[0]; + +	r[0][2] -= vs[1]; +	r[1][2] += vs[0]; +	r[2][2] += c; + +	return r; +}; + +export fn rotate(m: *m4, angle: f32, axis: *v3) void = { +	const rot = rotation_make(angle, axis); +	const orig = *m; +	m4_mul_to(&rot, &orig, m); +}; + +export fn rotate_at(m: *m4, pivot: *v3, angle: f32, axis: *v3) void = { +	const pivot_inv = v3_new_fill(0.0); +	v3_negate_to(pivot, &pivot_inv); +	translate(m, &pivot_inv); +	rotate(m, angle, axis); +	translate(m, pivot); +}; + +export fn scale_make(v: *v3) m4 = { +	let res = m4_new_ident(); +	res[0][0] = v[0]; +	res[1][1] = v[1]; +	res[2][2] = v[2]; +	return res; +}; + +export fn scale(m: *m4, v: *v3) void = { +	const mat = scale_make(v); +	const orig = *m; +	m4_mul_to(&mat, &orig, m); +}; + +export fn affine_mul_v3(a: *m4, b: *v3) v3 = { +	return v3_new( +		a[0][0] * b[0] + a[1][0] * b[1] + a[2][0] * b[2] + a[3][0], +		a[0][1] * b[0] + a[1][1] * b[1] + a[2][1] * b[2] + a[3][1], +		a[0][2] * b[0] + a[1][2] * b[1] + a[2][2] * b[2] + a[3][2], +	); +}; diff --git a/glm/camera.ha b/glm/camera.ha new file mode 100644 index 0000000..b648232 --- /dev/null +++ b/glm/camera.ha @@ -0,0 +1,71 @@ +use math; + +export fn ortho( +	m: *m4, +	left: f32, +	right: f32, +	bottom: f32, +	top: f32, +	znear: f32, +	zfar: f32, +) void = { +	m4_set_zero(m); + +	const rl = 1.0 / (right - left); +	const tb = 1.0 / (top - bottom); +	const nf = -1.0 / (zfar - znear); + +	m[0][0] = 2.0 * rl; +	m[1][1] = 2.0 * tb; +	m[2][2] = 2.0 * nf; +	m[3][0] =-(right + left) * rl; +	m[3][1] =-(top + bottom) * tb; +	m[3][2] = (zfar + znear) * nf; +	m[3][3] = 1.0; +}; + +export fn lookat(eye: *v3, center: *v3, up: *v3) m4 = { +	const f = v3_sub(center, eye); +	v3_normalize(&f); +	const s = v3_crossn(&f, up); +	const u = v3_cross(&s, &f); + +	const res = m4_new(1.0); +	res[0][0] = s[0]; +	res[0][1] = u[0]; +	res[0][2] = -f[0]; +	res[1][0] = s[1]; +	res[1][1] = u[1]; +	res[1][2] = -f[1]; +	res[2][0] = s[2]; +	res[2][1] = u[2]; +	res[2][2] = -f[2]; +	res[3][0] = -v3_dot(&s, eye); +	res[3][1] = -v3_dot(&u, eye); +	res[3][2] = v3_dot(&f, eye); +	res[0][3] = 0.0; +	res[1][3] = 0.0; +	res[2][3] = 0.0; +	res[3][3] = 1.0; +	return res; +}; + + +export fn perspective( +	m: *m4, +	fovy_in_deg: f32, +	aspect_ratio: f32, +	znear: f32, +	zfar: f32 +) void = { +	m4_set_zero(m); + +	const f = 1.0 / math::tanf64(fovy_in_deg * 0.5): f32; +	const f1 = 1.0 / (znear - zfar); + +	m[0][0] = f / aspect_ratio; +	m[1][1] = f; +	m[2][2] = (znear + zfar) * f1; +	m[2][3] = -1.0; +	m[3][2] = 2.0 * znear * zfar * f1; +}; diff --git a/glm/m4.ha b/glm/m4.ha new file mode 100644 index 0000000..6b283e2 --- /dev/null +++ b/glm/m4.ha @@ -0,0 +1,105 @@ +use fmt; +use rt; + +export def M4_IDENT: m4 = [ +	[1.0, 0.0, 0.0, 0.0], +	[0.0, 1.0, 0.0, 0.0], +	[0.0, 0.0, 1.0, 0.0], +	[0.0, 0.0, 0.0, 1.0], +]; + +export def M4_ZERO: m4 = [ +	[0.0, 0.0, 0.0, 0.0], +	[0.0, 0.0, 0.0, 0.0], +	[0.0, 0.0, 0.0, 0.0], +	[0.0, 0.0, 0.0, 0.0], +]; + +export fn m4_new(diag: f32) m4 = { +	return [ +		[diag, 0.0, 0.0, 0.0], +		[0.0, diag, 0.0, 0.0], +		[0.0, 0.0, diag, 0.0], +		[0.0, 0.0, 0.0, diag], +	]; +}; + +export fn m4_new_ident() m4 = { +	return m4_new(1.0); +}; + +export fn m4_new_zero() m4 = { +	return m4_new(0.0); +}; + +export fn m4_valptr(m: *m4) *const f32 = { +	return &m[0][0]; +}; + +export fn m4_print(m: *m4) void = { +	fmt::printfln("[ {}, {}, {}, {}, ", m[0][0], m[1][0], m[2][0], m[3][0])!; +	fmt::printfln("  {}, {}, {}, {}, ", m[0][1], m[1][1], m[2][1], m[3][1])!; +	fmt::printfln("  {}, {}, {}, {}, ", m[0][2], m[1][2], m[2][2], m[3][2])!; +	fmt::printfln("  {}, {}, {}, {} ]", m[0][3], m[1][3], m[2][3], m[3][3])!; +}; + +export fn m4_set_ident(m: *m4) *m4 = { +	m4_set_zero(m); +	m[0][0] = 1.0; +	m[1][1] = 1.0; +	m[2][2] = 1.0; +	m[3][3] = 1.0; +	return m; +}; + +export fn m4_set_zero(m: *m4) *m4 = { +	rt::memset(m, 0, 4 * 4 * 4); +	return m; +}; + +export fn m4_col(m: *m4, col: int) *v4 = { +	return (&m[col]: *[4]f32): *v4; +}; + +export fn m4_mul_to(a: *m4, b: *m4, dest: *m4) void = { +	const a = *a; +	const b = *b; +	dest[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + +		a[2][0] * b[0][2] + a[3][0] * b[0][3]; +	dest[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + +		a[2][1] * b[0][2] + a[3][1] * b[0][3]; +	dest[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + +		a[2][2] * b[0][2] + a[3][2] * b[0][3]; +	dest[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + +		a[2][3] * b[0][2] + a[3][3] * b[0][3]; +	dest[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + +		a[2][0] * b[1][2] + a[3][0] * b[1][3]; +	dest[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + +		a[2][1] * b[1][2] + a[3][1] * b[1][3]; +	dest[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + +		a[2][2] * b[1][2] + a[3][2] * b[1][3]; +	dest[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + +		a[2][3] * b[1][2] + a[3][3] * b[1][3]; +	dest[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + +		a[2][0] * b[2][2] + a[3][0] * b[2][3]; +	dest[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + +		a[2][1] * b[2][2] + a[3][1] * b[2][3]; +	dest[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + +		a[2][2] * b[2][2] + a[3][2] * b[2][3]; +	dest[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + +		a[2][3] * b[2][2] + a[3][3] * b[2][3]; +	dest[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + +		a[2][0] * b[3][2] + a[3][0] * b[3][3]; +	dest[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + +		a[2][1] * b[3][2] + a[3][1] * b[3][3]; +	dest[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + +		a[2][2] * b[3][2] + a[3][2] * b[3][3]; +	dest[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + +		a[2][3] * b[3][2] + a[3][3] * b[3][3]; +}; + +export fn m4_mul(a: *m4, b: *m4) m4 = { +	let res = m4_new_zero(); +	m4_mul_to(a, b, &res); +	return res; +}; diff --git a/glm/types.ha b/glm/types.ha new file mode 100644 index 0000000..3b14a67 --- /dev/null +++ b/glm/types.ha @@ -0,0 +1,7 @@ +export type m2 = [2][2]f32; +export type m3 = [3][3]f32; +export type m4 = [4][4]f32; +export type v2 = [2]f32; +export type v3 = [3]f32; +export type v4 = [4]f32; +export type quat = [4]f32; diff --git a/glm/util.ha b/glm/util.ha new file mode 100644 index 0000000..02e4afc --- /dev/null +++ b/glm/util.ha @@ -0,0 +1,9 @@ +use math; + +export fn rad(deg: f32) f32 = { +	return deg * math::PI: f32 / 180.0; +}; + +export fn deg(rad: f32) f32 = { +	return rad * 180.0 / math::PI: f32; +}; diff --git a/glm/v2.ha b/glm/v2.ha new file mode 100644 index 0000000..d8b5d51 --- /dev/null +++ b/glm/v2.ha @@ -0,0 +1,10 @@ +export def V2_ZERO: v2 = [0.0, 0.0]; +export def V2_ONE: v2 = [1.0, 1.0]; + +export fn v2_new(x: f32, y: f32) v2 = { +	return [x, y]; +}; + +export fn v2_new_fill(x: f32) v2 = { +	return [x, x]; +}; diff --git a/glm/v3.ha b/glm/v3.ha new file mode 100644 index 0000000..e7f1a8e --- /dev/null +++ b/glm/v3.ha @@ -0,0 +1,127 @@ +use fmt; +use math; + +export def V3_ZERO: v3 = [0.0, 0.0, 0.0]; +export def V3_ONE: v3 = [1.0, 1.0, 1.0]; + +export fn v3_new(x: f32, y: f32, z: f32) v3 = { +	return [x, y, z]; +}; + +export fn v3_new_fill(x: f32) v3 = { +	return [x, x, x]; +}; + +export fn v3_new_zero() v3 = { +	return [0.0, 0.0, 0.0]; +}; + +export fn v3_copy(v: *v3) v3 = { +	return [v[0], v[1], v[2]]; +}; + +export fn v3_copy_to(v: *v3, dest: *v3) void = { +	dest[0] = v[0]; +	dest[1] = v[1]; +	dest[2] = v[2]; +}; + +export fn v3_valptr(v: *v3) *const f32 = { +	return &v[0]; +}; + +export fn v3_print(v: *v3) void = { +	fmt::printfln("[ {}, {}, {} ]", v[0], v[1], v[2])!; +}; + +export fn v3_negate(v: *v3) void = { +	v[0] *= -1.0; +	v[1] *= -1.0; +	v[2] *= -1.0; +}; + +export fn v3_negate_to(v: *v3, dest: *v3) void = { +	dest[0] = v[0] * -1.0; +	dest[1] = v[1] * -1.0; +	dest[2] = v[2] * -1.0; +}; + +export fn v3_add(a: *v3, b: *v3) v3 = { +	return [ +		a[0] + b[0], +		a[1] + b[1], +		a[2] + b[2], +	]; +}; + +export fn v3_sub(a: *v3, b: *v3) v3 = { +	return [ +		a[0] - b[0], +		a[1] - b[1], +		a[2] - b[2], +	]; +}; + +export fn v3_normalize(v: *v3) void = { +	const norm = v3_norm(v); + +	if (norm == 0.0) { +		v[0] = 0.0; +		v[1] = 0.0; +		v[2] = 0.0; +		return; +	}; + +	v3_scale(v, 1.0 / norm); +}; + +export fn v3_normalize_to(v: *v3, dest: *v3) void = { +	const norm = v3_norm(v); + +	if (norm == 0.0) { +		dest[0] = 0.0; +		dest[1] = 0.0; +		dest[2] = 0.0; +		return; +	}; + +	v3_scale_to(v, 1.0 / norm, dest); +}; + +export fn v3_dot(a: *v3, b: *v3) f32 = { +	return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +}; + +export fn v3_norm2(v: *v3) f32 = { +	return v3_dot(v, v); +}; + +export fn v3_norm(v: *v3) f32 = { +	return math::sqrtf64(v3_norm2(v)): f32; +}; + +export fn v3_scale(v: *v3, s: f32) void = { +	v[0] = v[0] * s; +	v[1] = v[1] * s; +	v[2] = v[2] * s; +}; + +export fn v3_scale_to(v: *v3, s: f32, dest: *v3) void = { +	dest[0] = v[0] * s; +	dest[1] = v[1] * s; +	dest[2] = v[2] * s; +}; + +export fn v3_cross(a: *v3, b: *v3) v3 = { +	return [ +		a[1] * b[2] - a[2] * b[1], +		a[2] * b[0] - a[0] * b[2], +		a[0] * b[1] - a[1] * b[0], +	]; +}; + +export fn v3_crossn(a: *v3, b: *v3) v3 = { +	let res = v3_cross(a, b); +	v3_normalize(&res); +	return res; +}; diff --git a/glm/v4.ha b/glm/v4.ha new file mode 100644 index 0000000..659be04 --- /dev/null +++ b/glm/v4.ha @@ -0,0 +1,105 @@ +use fmt; +use math; + +export fn v4_new(x: f32, y: f32, z: f32, w: f32) v4 = { +	return [x, y, z, w]; +}; + +export fn v4_new_fill(x: f32) v4 = { +	return [x, x, x, x]; +}; + +export fn v4_new_zero() v4 = { +	return [0.0, 0.0, 0.0, 0.0]; +}; + +export fn v4_copy(v: *v4) v4 = { +	return [v[0], v[1], v[2], v[3]]; +}; + +export fn v4_copy_to(v: *v4, dest: *v4) void = { +	dest[0] = v[0]; +	dest[1] = v[1]; +	dest[2] = v[2]; +	dest[3] = v[3]; +}; + +export fn v4_valptr(v: *v4) *const f32 = { +	return &v[0]; +}; + +export fn v4_print(v: v4) void = { +	fmt::printfln("[ {}, {}, {}, {} ]", v[0], v[1], v[2], v[3])!; +}; + +export fn v4_negate(v: *v4) void = { +	v[0] *= -1.0; +	v[1] *= -1.0; +	v[2] *= -1.0; +	v[3] *= -1.0; +}; + +export fn v4_negate_to(v: *v4, dest: *v4) void = { +	dest[0] = v[0] * -1.0; +	dest[1] = v[1] * -1.0; +	dest[2] = v[2] * -1.0; +	dest[3] = v[3] * -1.0; +}; + +export fn v4_add(a: *v4, b: *v4) v4 = { +	return [ +		a[0] + b[0], +		a[1] + b[1], +		a[2] + b[2], +		a[3] + b[3], +	]; +}; + +export fn v4_sub(a: *v4, b: *v4) v4 = { +	return [ +		a[0] - b[0], +		a[1] - b[1], +		a[2] - b[2], +		a[3] - b[3], +	]; +}; + +export fn v4_normalize(v: *v4) void = { +	const norm = v4_norm(v); + +	if (norm == 0.0) { +		v[0] = 0.0; +		v[1] = 0.0; +		v[2] = 0.0; +		v[3] = 0.0; +		return; +	}; + +	v4_scale(v, 1.0 / norm); +}; + +export fn v4_dot(a: *v4, b: *v4) f32 = { +	return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; +}; + +export fn v4_norm2(v: *v4) f32 = { +	return v4_dot(v, v); +}; + +export fn v4_norm(v: *v4) f32 = { +	return math::sqrtf64(v4_norm2(v)): f32; +}; + +export fn v4_scale(v: *v4, s: f32) void = { +	v[0] = v[0] * s; +	v[1] = v[1] * s; +	v[2] = v[2] * s; +	v[3] = v[3] * s; +}; + +export fn v4_scale_to(v: *v4, s: f32, dest: *v4) void = { +	dest[0] = v[0] * s; +	dest[1] = v[1] * s; +	dest[2] = v[2] * s; +	dest[3] = v[3] * s; +}; diff --git a/glw/debug.ha b/glw/debug.ha new file mode 100644 index 0000000..2ffe3c4 --- /dev/null +++ b/glw/debug.ha @@ -0,0 +1,34 @@ +use strings; +use types::c; +use trace; + +use gl::*; + +fn debug_callback( +	source: gl_enum, +	type_: gl_enum, +	id: uint, +	severity: gl_enum, +	length: i32, +	message: nullable *const c::char, +	user_data: nullable *opaque, +) void = { +	// (2024 note): I'm painfully aware of the data race present here: +	// The GL driver can call this from another thread, and the stdlib has +	// some non-thread-safe stuff in it that we use, in particular strconv. +	// I've seen it happen at times, but it's pretty rare. +	const message = (message: *const [*]u8)[..length]; +	const message = strings::fromutf8(message)!; +	const message = strings::trimsuffix(message, "\n"); +	trace::debug(&trace::root, "gl: {}", message); +}; + +export fn init_debug_logging() void = { +	let ctxflags = 0i32; +	glGetIntegerv(GL_CONTEXT_FLAGS, &ctxflags); + +	if (ctxflags & GL_CONTEXT_FLAG_DEBUG_BIT: i32 != 0) { +		trace::info(&trace::root, "opengl debugging is enabled"); +		glDebugMessageCallback(&debug_callback, null); +	}; +}; diff --git a/glw/glw.ha b/glw/glw.ha new file mode 100644 index 0000000..a3a2b65 --- /dev/null +++ b/glw/glw.ha @@ -0,0 +1,91 @@ +use strings; +use trace; +use types::c; + +use gl::*; + +export fn get_string(name: gl_enum) str = { +	match (glGetString(name)) { +	case null => +		return ""; +	case let s: *const u8 => +		return c::tostr(s: *const c::char)!; +	}; +}; + +export fn buffer_data( +	target: gl_enum, +	data: []opaque, +	itemsz: size, +	usage: gl_enum, +) void = { +	glBufferData( +		target, +		(len(data) * itemsz): uintptr, +		data: nullable *[*]u8: nullable *opaque, +		usage, +	); +}; + +export fn compile_shader_src(type_: gl_enum, src: str) uint = { +	const shader = glCreateShader(type_); +	glShaderSource( +		shader, 1, +		&(strings::toutf8(src): *[*]i8: nullable *const i8), +		&(len(src): i32), +	); +	glCompileShader(shader); + +	let status = 0i32; +	glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + +	if (status == 0) { +		let log_len = 0i32; +		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len); + +		const log_buf = alloc([0u8...], log_len: size); +		glGetShaderInfoLog( +			shader, log_len, +			null, log_buf: *[*]i8: *i8, +		); + +		const log = strings::fromutf8(log_buf)!; + +		const type_str = switch (type_) { +		case GL_VERTEX_SHADER => yield "vertex"; +		case GL_FRAGMENT_SHADER => yield "fragment"; +		case GL_GEOMETRY_SHADER => yield "geometry"; +		case => yield "(unknown)"; +		}; + +		trace::error(&trace::root, +			"{} shader compilation failed:\n{}", +			type_str, log): void; +	}; + +	return shader; +}; + +export fn link_program(program: uint) void = { +	glLinkProgram(program); + +	let status = 0i32; +	glGetProgramiv(program, GL_LINK_STATUS, &status); + +	if (status == 0) { +		let log_len = 0i32; +		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len); + +		const log_buf = alloc([0u8...], log_len: size); +		glGetProgramInfoLog( +			program, log_len, +			null, log_buf: *[*]i8: *i8, +		); + +		const log = strings::fromutf8(log_buf)!; + +		trace::error(&trace::root, +			"program linking failed:\n{}", +			log): void; +	}; +}; diff --git a/htab/+test.ha b/htab/+test.ha new file mode 100644 index 0000000..518e97d --- /dev/null +++ b/htab/+test.ha @@ -0,0 +1,61 @@ +use fmt; +use hash; +use hash::fnv; +use math::random; + +fn test_eq(ctx: *opaque, entry: *opaque) bool = +	*(ctx: *u64) == *(entry: *u64); + +fn test_fnvhash(x: u64) u64 = { +	let h = fnv::fnv64a(); +	hash::write(&h, &x: *[8]u8); +	return fnv::sum64(&h); +}; + +fn test_garbagehash(x: u64) u64 = +	0x0123456789abcdef; + +fn test_table(sz: size, hash_fn: *fn(x: u64) u64, rng: *random::random) void = { +	fmt::printf("{} ", sz)!; +	static let array: [1024]bool = [false...]; +	for (let i = 0z; i < len(array); i += 1) { +		array[i] = false; +	}; +	let tab = new(0, sz); +	defer finish(&tab); + +	for (let i = 0; i < 100000; i += 1) { +		const x = random::u64n(rng, len(array): u64); +		const hash = hash_fn(x); +		match (get(&tab, hash, &test_eq, &x, sz)) { +		case let entry: *opaque => +			assert(array[x: size]); +			assert(*(entry: *u64) == x); +			del(&tab, entry, sz); +			array[x: size] = false; +		case null => +			assert(!array[x: size]); +			const entry = add(&tab, hash, sz); +			array[x: size] = true; +			*(entry: *u64) = x; +		}; +	}; + +	for (let x = 0u64; x < len(array): u64; x += 1) { +		const hash = hash_fn(x); +		get(&tab, hash, &test_eq, &x, sz); +	}; + +	fmt::println()!; +}; + +@test fn table() void = { +	let rng = random::init(42); + +	fmt::println("fnvhash:")!; +	for (let i = 8z; i < 128; i += 8) +		test_table(i, &test_fnvhash, &rng); +	fmt::println("garbagehash:")!; +	for (let i = 8z; i < 128; i += 8) +		test_table(i, &test_garbagehash, &rng); +}; diff --git a/htab/README b/htab/README new file mode 100644 index 0000000..cd296b2 --- /dev/null +++ b/htab/README @@ -0,0 +1,8 @@ +Generic open addressing hash table. + +The table-related functions in this module expect a sz argument specifying the +table's element size. This value must remain consistent across all function +calls referencing the table. + +The hash value 0 is reserved as a sentinel value for use by the hash table +implementation, and must not be used. diff --git a/htab/table.ha b/htab/table.ha new file mode 100644 index 0000000..b90b0aa --- /dev/null +++ b/htab/table.ha @@ -0,0 +1,254 @@ +use fmt; +use math; +use rt; + +fn cap2nslots(cap: size) size = { +	const nslots_ = cap << 1; +	let nslots = 1z; +	for (nslots < nslots_) { +		nslots <<= 1; +	}; +	return nslots; +}; + +fn nslots2cap(nslots: size) size = { +	return nslots >> 1; +}; + +fn dbg(fmt: str, args: fmt::field...) void = { +	fmt::errorfln(fmt, args...)!; +}; + +// temporary hack before inlining works. +def DBG = false; + +export type table = struct { +	table: *[*]u64, +	nslots: size, // must be a power of 2. +	nleft: size, +}; + +// The interface of user-specified equality comparison functions. +export type eq_fn = fn(ctx: *opaque, elem: *opaque) bool; + +export const empty: [1]u64 = [0]; + +// An empty hash table. +def EMPTY = table { +	table = &empty, +	nslots = 1, +	nleft = 0, +}; + +// Returns a new hash table preallocated with the specified capacity. +// +// If cap is 0, no memory is allocated, and the result is equivalent +// to [[EMPTY]]. +export fn new(cap: size, sz: size) table = { +	if (cap == 0) { +		return EMPTY; +	}; + +	const nslots = cap2nslots(cap); + +	// TODO: need to check for overflow here +	// TODO: should probably deal with alignment > 8 bytes +	const allocsz = nslots * size(u64) + nslots * sz; +	const ptr = rt::malloc(allocsz): *opaque; + +	let tab = table { +		table = ptr: *[*]u64, +		nslots = nslots, +		... +	}; +	clear(&tab, sz); +	return tab; +}; + +// Clears the table without deallocating it. +// +// Calling this function causes all previously obtained element pointers and +// iterators belonging to the table to become invalid. +export fn clear(tab: *table, sz: size) void = { +	for (let i = 0z; i < tab.nslots; i += 1) { +		tab.table[i] = 0; +	}; +	tab.nleft = nslots2cap(tab.nslots); +}; + +// Clears and deallocates the table. +// +// The table is left in a valid, empty state. +// +// Calling this function causes all previously obtained element pointers and +// iterators belonging to the table to become invalid. +export fn finish(tab: *table) void = { +	if (tab.nslots != 1) { +		free(tab.table); +	}; +	*tab = EMPTY; +}; + +// Returns the number of elements in the table. +export fn count(tab: *table) size = { +	return nslots2cap(tab.nslots) - tab.nleft; +}; + +fn at(tab: *table, i: size, sz: size) *opaque = { +	const elems: *opaque = &tab.table[tab.nslots]; +	return (elems: uintptr + i * sz): *opaque; +}; + +// Resizes the table to the specified capacity. +// +// The capacity specifies the maximum number of elements storable without +// growing the table. The resulting memory allocation will be larger. +// +// If the number of elements in the table exceeds the capacity, +// the program aborts. +// +// Calling this function causes all previously obtained element pointers and +// iterators belonging to the table to become invalid. +export fn resize(tab: *table, newcap: size, sz: size) void = { +	if (cap2nslots(newcap) == tab.nslots) { +		return; +	}; +	assert(count(tab) <= newcap, +		"table won't fit into requested capacity"); +	if (DBG) dbg("resize {} {{", newcap); +	let newtab = new(newcap, sz); +	for (let i = 0z; i < tab.nslots; i += 1) { +		if (tab.table[i] == 0) { +			continue; +		}; +		const entry = add(&newtab, tab.table[i], sz); +		rt::memcpy(entry, at(tab, i, sz), sz); +	}; +	finish(tab); +	*tab = newtab; +	if (DBG) dbg("}} resize {}", newcap); +}; + +// Finds an element with the specified hash in the table. +// +// If no element is found, null is returned. +// +// hash must not equal 0. +// +// If eq is non-null, it is called on each element matching the hash until it +// returns true. If it is null, an arbitrary matching element is returned. +// +// ctx specifies the value of the ctx argument passed to eq. +export fn get(tab: *table, hash: u64, eq: *eq_fn, ctx: *opaque, sz: size) +		nullable *opaque = { +	if (DBG) dbg("get {}", hash); +	let i = hash: size & tab.nslots - 1; +	for (let inc = 0z; true; inc = 1) { +		i = i + inc & tab.nslots - 1; +		if (DBG) dbg("[{}] -> {}", i, tab.table[i]); +		if (tab.table[i] == 0) { +			break; +		}; +		if (tab.table[i] != hash) { +			continue; +		}; +		const elem = at(tab, i, sz); +		if (!eq(ctx, elem)) { +			continue; +		}; +		return elem; +	}; +	return null; +}; + +// Adds an element with the specified hash to the table and returns a pointer +// to it. +// +// The element is left uninitialized. +// +// hash must not equal 0. +// +// Calling this function causes all previously obtained element pointers and +// iterators belonging to the table to become invalid. +// +// Unless the table is known not to already contain an identical element, users +// should first use [[get]] to check for that possibility. +export fn add(tab: *table, hash: u64, sz: size) *opaque = { +	if (DBG) dbg("add {}", hash); + +	if (tab.nleft == 0) { +		resize(tab, nslots2cap(tab.nslots) + 1, sz); +	}; +	tab.nleft -= 1; + +	let i = hash: size & tab.nslots - 1; +	for (let inc = 0z; true; inc = 1) { +		i = i + inc & tab.nslots - 1; +		if (DBG) dbg("[{}] -> {}", i, tab.table[i]); +		if (tab.table[i] != 0) { +			continue; +		}; +		if (DBG) dbg("[{}] <- {}", i, hash); +		tab.table[i] = hash; +		return at(tab, i, sz); +	}; +}; + +// Removes the specified element from the table. +// +// Calling this function causes all previously obtained element pointers and +// iterators belonging to the table to become invalid. +export fn del(tab: *table, elem: *opaque, sz: size) void = { +	tab.nleft += 1; + +	let i = (elem: uintptr - at(tab, 0, sz): uintptr): size / sz; +	if (DBG) dbg("del {}", i); +	if (DBG) dbg("[{}] <- {}", i, 0); +	tab.table[i] = 0; + +	for (let j = i; true) { +		j = j + 1 & tab.nslots - 1; +		if (DBG) dbg("[{}] -> {}", j, tab.table[j]); +		if (tab.table[j] == 0) { +			break; +		}; +		const k = tab.table[j]: size & tab.nslots - 1; +		if (if (i < j) i < k && k <= j else i < k || k <= j) { +			continue; +		}; +		if (DBG) dbg("[{}] <- {}", i, tab.table[j]); +		tab.table[i] = tab.table[j]; +		rt::memcpy(at(tab, i, sz), at(tab, j, sz), sz); +		if (DBG) dbg("[{}] <- {}", j, 0); +		tab.table[j] = 0; +		i = j; +	}; +}; + +export type iterator = struct { +	table: *table, +	i: size, +}; + +// Returns a new iterator for the table. +// +// The order of iteration is unspecified. +export fn iter(tab: *table) iterator = { +	return iterator { +		table = tab, +		i = 0, +	}; +}; + +// Returns a pointer to the next element from the iterator, or null if iteration +// has completed. +export fn next(it: *iterator, sz: size) nullable *opaque = { +	for (it.i < it.table.nslots) { +		const i = it.i; +		it.i += 1; +		if (it.table.table[i] != 0) { +			return at(it.table, i, sz); +		}; +	}; +	return null; +}; @@ -0,0 +1,258 @@ +use gl::*; +use glm; +use math; +use strconv; +use strings; +use trace; +use types; + +let TEXTURE_GUI_ICONS = 0u; + +def HUD_WIDTH = 182.0f32; +def HUD_HEALTH_YOFFSET = 39.0f32; + +fn hud_load() void = { +	TEXTURE_GUI_ICONS = texture_upload( +		textures_find("minecraft:gui/icons") as *Texture, +		&trace::root); +}; + +const LAYER_HUD = Layer { +	blocks_input = &layer_hud_blocks_input, +	input = &layer_hud_input, +	is_opaque = &layer_hud_is_opaque, +	render = &layer_hud_render, +}; + +fn layer_hud_blocks_input() bool = { +	return false; +}; + +fn layer_hud_input(event: InputEvent) bool = { +	return false; +}; + +fn layer_hud_is_opaque() bool = { +	return false; +}; + +fn layer_hud_render() void = { +	if (CLIENT_STATE != ClientState::GAME) { +		return; +	}; + +	let (width, height) = drawable_size(); +	let gui_width = width / gui_scale(); +	let gui_height = height / gui_scale(); + +	const trans = gui_proj(); + +	// crosshair + +	if (GAMEMODE != Gamemode::SPECTATOR) { +		glEnable(GL_BLEND); +		glBlendEquation(GL_FUNC_ADD); +		glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); + +		render_rect_textured(trans, +			((gui_width - 15) / 2): f32, ((gui_height - 15) / 2): f32, +			15.0, 15.0, +			[255...], +			0.0, 0.0, 15.0, 15.0, +			TEXTURE_GUI_ICONS, 256, 256); +	}; + +	glEnable(GL_BLEND); +	glBlendEquation(GL_FUNC_ADD); +	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +	const left = gui_width: f32 * 0.5 - HUD_WIDTH * 0.5; +	const right = gui_width: f32 * 0.5 + HUD_WIDTH * 0.5; + +	const survival = GAMEMODE == Gamemode::SURVIVAL +		|| GAMEMODE == Gamemode::ADVENTURE; + +	// xp bar + +	if (survival) { +		const progress = 0.0f32; // TODO +		const progress = math::ceilf64(progress * HUD_WIDTH): f32; +		const y = gui_height: f32 - 29.0; +		const height = 5.0f32; +		render_rect_textured(trans, left, y, HUD_WIDTH, height, +			[255...], +			0.0, 64.0, HUD_WIDTH, height, +			TEXTURE_GUI_ICONS, 256, 256); + +		render_rect_textured(trans, left, y, progress, height, +			[255...], +			0.0, 69.0, progress, height, +			TEXTURE_GUI_ICONS, 256, 256); + +		const level = 0u32; // TODO +		if (level != 0) { +			// XXX: let's not take risks here with the static +			// alloc... +			const text = strings::dup(strconv::u32tos(level)); +			defer free(text); +			const font = fonts_find("minecraft:default") as *Font; +			const metrics = font_measure(font, text); +			// TODO: harec weirdness... +			let x = (gui_width: f32 - metrics.width) * 0.5; +			const y = gui_height: f32 - 35.0; +			// TODO: this is how minecraft does it; however it looks +			// ugly with high-res fonts (unifont included!). should +			// probably take font resolution into account, or use a +			// shader thing or something. +			const text_trans = glm::translation_make(&[x - 1.0, y, 0.0]); +			const text_trans = glm::m4_mul(trans, &text_trans); +			render_text(text, font, &text_trans, [0...]); +			const text_trans = glm::translation_make(&[x + 1.0, y, 0.0]); +			const text_trans = glm::m4_mul(trans, &text_trans); +			render_text(text, font, &text_trans, [0...]); +			const text_trans = glm::translation_make(&[x, y - 1.0, 0.0]); +			const text_trans = glm::m4_mul(trans, &text_trans); +			render_text(text, font, &text_trans, [0...]); +			const text_trans = glm::translation_make(&[x, y + 1.0, 0.0]); +			const text_trans = glm::m4_mul(trans, &text_trans); +			render_text(text, font, &text_trans, [0...]); +			const text_trans = glm::translation_make(&[x, y, 0.0]); +			const text_trans = glm::m4_mul(trans, &text_trans); +			render_text(text, font, &text_trans, [128, 255, 32, 255]); +		}; +	}; + +	// icon bars left + +	const x = left; +	let y = gui_height: f32 - HUD_HEALTH_YOFFSET; + +	if (survival) { +		// XXX: absorption really screwed over any attempt at simplicity +		// here... + +		const health = math::ceilf64(PLAYER_HEALTH): f32; +		const health = if (health > 0.0) health else 0.0f32; +		const health = health: u32; +		const max_health = 20u32; // TODO +		const max_health = if (health > max_health) +			health else max_health; +		const nhearts = (max_health >> 1) + (max_health & 1); +		const nhealth_rows = (nhearts + 9) / 10; + +		const extra_health = math::ceilf64(0.0f32): f32; // TODO +		const extra_health = extra_health: u32; +		const nextra_hearts = (extra_health >> 1) + (extra_health & 1); +		const nextra_health_rows = (nextra_hearts + 9) / 10; + +		const nrows = nhealth_rows + nextra_health_rows;  +		const row_height = if (nrows <= 9) 12 - nrows else 3u32; +		const row_height = row_height: f32; + +		hud_render_icon_bar(trans, +			extra_health, 0, +			x, y - nhealth_rows: f32 * row_height, 8.0, -row_height, +			16.0, 0.0, 160.0, 0.0, 169.0, 0.0); +		hud_render_icon_bar(trans, +			health, max_health, +			x, y, 8.0, -row_height, +			16.0, 0.0, 52.0, 0.0, 61.0, 0.0); +		y -= 10.0 + (nrows - 1): f32 * row_height; +	}; + +	const armor = 0u32; // TODO +	const max_armor = 20u32; // TODO +	if (survival && armor != 0) { +		y -= hud_render_simple_icon_bar(trans, +			armor, max_armor, x, y, 8.0, +			16.0, 9.0, 34.0, 9.0, 25.0, 9.0); +	}; + +	// icon bars right + +	const x = right - 9.0; +	let y = gui_height: f32 - HUD_HEALTH_YOFFSET; + +	if (false) { // TODO +		const vehicle_health = 20u32; // TODO +		const max_vehicle_health = 20u32; // TODO +		y -= hud_render_simple_icon_bar(trans, +			vehicle_health, max_vehicle_health, x, y, -8.0, +			52.0, 9.0, 88.0, 9.0, 97.0, 9.0); +	}; + +	if (survival) { +		const food = PLAYER_FOOD: u32; +		const max_food = 20u32; // TODO +		y -= hud_render_simple_icon_bar(trans, +			food, max_food, x, y, -8.0, +			16.0, 27.0, 52.0, 27.0, 61.0, 27.0); +	}; + +	const air = 300u32; // TODO +	const max_air = 300u32; // TODO +	if (survival && air != max_air) { // TODO: always show when underwater +		const air_rem = (air * 10 + max_air - 1) % max_air; +		const air_bubbles = (air * 10 + max_air - 1) / max_air; +		const air_bubbles = if (air_rem < 20) +			air_bubbles * 2 - 1 else air_bubbles * 2; +		y -= hud_render_simple_icon_bar(trans, +			air_bubbles, 20, x, y, -8.0, +			70.0, 18.0, 16.0, 18.0, 25.0, 18.0); +	}; +}; + +fn hud_render_simple_icon_bar( +	trans: *glm::m4, +	amount: u32, max: u32, +	x: f32, y: f32, xstep: f32, +	ubg: f32, vbg: f32, +	ufull: f32, vfull: f32, +	uhalf: f32, vhalf: f32, +) f32 = { +	const max = if (amount > max) amount else max; +	const nicons = (max >> 1) + (max & 1); +	const nrows = (nicons + 9) / 10; +	const row_height = if (nrows <= 9) 12 - nrows else 3u32; +	const row_height = row_height: f32; +	hud_render_icon_bar(trans, amount, max, +		x, y, xstep, -row_height, +		ubg, vbg, ufull, vfull, uhalf, vhalf); +	return 10.0 + row_height * (nrows - 1): f32; +}; + +fn hud_render_icon_bar( +	trans: *glm::m4, +	amount: u32, max: u32, +	x: f32, y: f32, xstep: f32, ystep: f32, +	ubg: f32, vbg: f32, +	ufull: f32, vfull: f32, +	uhalf: f32, vhalf: f32, +) void = { +	const max = if (amount > max) amount else max; +	const nicons = (max >> 1) + (max & 1); + +	for (let i = nicons; i > 0) { +		i -= 1; + +		const x_ = x + (i % 10): f32 * xstep; +		const y_ = y + (i / 10): f32 * ystep; + +		render_rect_textured(trans, x_, y_, 9.0, 9.0, +			[255...], +			ubg, vbg, 9.0, 9.0, +			TEXTURE_GUI_ICONS, 256, 256); + +		if (i * 2 >= amount) { +			continue; +		}; + +		let (ufg, vfg) = if (i * 2 + 1 == amount) +			(uhalf, vhalf) else (ufull, vfull); + +		render_rect_textured(trans, x_, y_, 9.0, 9.0, +			[255...], +			ufg, vfg, 9.0, 9.0, +			TEXTURE_GUI_ICONS, 256, 256); +	}; +}; diff --git a/ident.ha b/ident.ha new file mode 100644 index 0000000..446fbad --- /dev/null +++ b/ident.ha @@ -0,0 +1,19 @@ +use strings; + +def DEFAULT_NS = "minecraft"; + +fn ident_split(ident: str) (str, str) = { +	assert(strings::contains(ident, ":")); +	return strings::cut(ident, ":"); +}; + +fn ident_make(ns: str, name: str) str = +	strings::concat(ns, ":", name); + +fn ident_qual(ident: str) str = { +	if (strings::contains(ident, ":")) { +		return strings::dup(ident); +	} else { +		return ident_make(DEFAULT_NS, ident); +	}; +}; diff --git a/idreg.ha b/idreg.ha new file mode 100644 index 0000000..1cdd74a --- /dev/null +++ b/idreg.ha @@ -0,0 +1,72 @@ +use hash::fnv; +use htab; +use strings; +use types; + +type IdRegistry = struct { +	idtoname: []str, +	nametoid: htab::table, // u32 +}; + +def HTAB_EMPTY = htab::table { +	// XXX: harec limitation... +	table = &htab::empty, +	nslots = 1, +	... +}; + +def IDREG_EMPTY = IdRegistry { +	nametoid = HTAB_EMPTY, +	... +}; + +fn newidreg() IdRegistry = +	IdRegistry { +		idtoname = [], +		nametoid = htab::new(0, size(u32)), +	}; + +fn idreg_count(reg: *IdRegistry) u32 = +	len(reg.idtoname): u32; + +fn idreg_exists(reg: *IdRegistry, id: u32) bool = +	id < len(reg.idtoname); + +fn idreg_getname(reg: *IdRegistry, id: u32) str = +	reg.idtoname[id]; + +fn idreg_eqfunc(ctx: *opaque, entry: *opaque) bool = { +	const ctx = ctx: *(*IdRegistry, str); +	return ctx.1 == ctx.0.idtoname[*(entry: *u32)]; +}; + +fn idreg_lookup(reg: *IdRegistry, name: str) (u32 | void) = { +	const hash = fnv::string64(name); +	match (htab::get(®.nametoid, hash, +		&idreg_eqfunc, &(reg, name), size(u32))) { +	case let entry: *opaque => +		return *(entry: *u32); +	case null => void; +	}; +}; + +fn idreg_register(reg: *IdRegistry, name: str) u32 = { +	assert(idreg_lookup(reg, name) is void, "already registered"); +	assert(len(reg.idtoname) < types::U32_MAX, "registry full"); + +	const id = len(reg.idtoname): u32; +	append(reg.idtoname, strings::dup(name)); + +	const hash = fnv::string64(name); +	const entry = htab::add(®.nametoid, hash, size(u32)); +	*(entry: *u32) = id; + +	return id; +}; + +fn idreg_clear(reg: *IdRegistry) void = { +	strings::freeall(reg.idtoname); +	htab::finish(®.nametoid); +	reg.idtoname = []; +	reg.nametoid = htab::new(0, size(u32)); +}; diff --git a/image/README b/image/README new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/image/README diff --git a/image/png/COPYING b/image/png/COPYING new file mode 100644 index 0000000..c257317 --- /dev/null +++ b/image/png/COPYING @@ -0,0 +1,367 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" +    means each individual or legal entity that creates, contributes to +    the creation of, or owns Covered Software. + +1.2. "Contributor Version" +    means the combination of the Contributions of others (if any) used +    by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" +    means Covered Software of a particular Contributor. + +1.4. "Covered Software" +    means Source Code Form to which the initial Contributor has attached +    the notice in Exhibit A, the Executable Form of such Source Code +    Form, and Modifications of such Source Code Form, in each case +    including portions thereof. + +1.5. "Incompatible With Secondary Licenses" +    means + +    (a) that the initial Contributor has attached the notice described +        in Exhibit B to the Covered Software; or + +    (b) that the Covered Software was made available under the terms of +        version 1.1 or earlier of the License, but not also under the +        terms of a Secondary License. + +1.6. "Executable Form" +    means any form of the work other than Source Code Form. + +1.7. "Larger Work" +    means a work that combines Covered Software with other material, in  +    a separate file or files, that is not Covered Software. + +1.8. "License" +    means this document. + +1.9. "Licensable" +    means having the right to grant, to the maximum extent possible, +    whether at the time of the initial grant or subsequently, any and +    all of the rights conveyed by this License. + +1.10. "Modifications" +    means any of the following: + +    (a) any file in Source Code Form that results from an addition to, +        deletion from, or modification of the contents of Covered +        Software; or + +    (b) any new file in Source Code Form that contains any Covered +        Software. + +1.11. "Patent Claims" of a Contributor +    means any patent claim(s), including without limitation, method, +    process, and apparatus claims, in any patent Licensable by such +    Contributor that would be infringed, but for the grant of the +    License, by the making, using, selling, offering for sale, having +    made, import, or transfer of either its Contributions or its +    Contributor Version. + +1.12. "Secondary License" +    means either the GNU General Public License, Version 2.0, the GNU +    Lesser General Public License, Version 2.1, the GNU Affero General +    Public License, Version 3.0, or any later versions of those +    licenses. + +1.13. "Source Code Form" +    means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") +    means an individual or a legal entity exercising rights under this +    License. For legal entities, "You" includes any entity that +    controls, is controlled by, or is under common control with You. For +    purposes of this definition, "control" means (a) the power, direct +    or indirect, to cause the direction or management of such entity, +    whether by contract or otherwise, or (b) ownership of more than +    fifty percent (50%) of the outstanding shares or beneficial +    ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) +    Licensable by such Contributor to use, reproduce, make available, +    modify, display, perform, distribute, and otherwise exploit its +    Contributions, either on an unmodified basis, with Modifications, or +    as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer +    for sale, have made, import, and otherwise transfer either its +    Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; +    or + +(b) for infringements caused by: (i) Your and any other third party's +    modifications of Covered Software, or (ii) the combination of its +    Contributions with other software (except as part of its Contributor +    Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of +    its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code +    Form, as described in Section 3.1, and You must inform recipients of +    the Executable Form how they can obtain a copy of such Source Code +    Form by reasonable means in a timely manner, at a charge no more +    than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this +    License, or sublicense it under different terms, provided that the +    license for the Executable Form does not attempt to limit or alter +    the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +*                                                                      * +*  6. Disclaimer of Warranty                                           * +*  -------------------------                                           * +*                                                                      * +*  Covered Software is provided under this License on an "as is"       * +*  basis, without warranty of any kind, either expressed, implied, or  * +*  statutory, including, without limitation, warranties that the       * +*  Covered Software is free of defects, merchantable, fit for a        * +*  particular purpose or non-infringing. The entire risk as to the     * +*  quality and performance of the Covered Software is with You.        * +*  Should any Covered Software prove defective in any respect, You     * +*  (not any Contributor) assume the cost of any necessary servicing,   * +*  repair, or correction. This disclaimer of warranty constitutes an   * +*  essential part of this License. No use of any Covered Software is   * +*  authorized under this License except under this disclaimer.         * +*                                                                      * +************************************************************************ + +************************************************************************ +*                                                                      * +*  7. Limitation of Liability                                          * +*  --------------------------                                          * +*                                                                      * +*  Under no circumstances and under no legal theory, whether tort      * +*  (including negligence), contract, or otherwise, shall any           * +*  Contributor, or anyone who distributes Covered Software as          * +*  permitted above, be liable to You for any direct, indirect,         * +*  special, incidental, or consequential damages of any character      * +*  including, without limitation, damages for lost profits, loss of    * +*  goodwill, work stoppage, computer failure or malfunction, or any    * +*  and all other commercial damages or losses, even if such party      * +*  shall have been informed of the possibility of such damages. This   * +*  limitation of liability shall not apply to liability for death or   * +*  personal injury resulting from such party's negligence to the       * +*  extent applicable law prohibits such limitation. Some               * +*  jurisdictions do not allow the exclusion or limitation of           * +*  incidental or consequential damages, so this exclusion and          * +*  limitation may not apply to You.                                    * +*                                                                      * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + +  This Source Code Form is subject to the terms of the Mozilla Public +  License, v. 2.0. If a copy of the MPL was not distributed with this +  file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. diff --git a/image/png/README b/image/png/README new file mode 100644 index 0000000..c39aaa4 --- /dev/null +++ b/image/png/README @@ -0,0 +1,8 @@ +This module provides support for decoding PNG images per the PNG specification +version 1.2: + +http://www.libpng.org/pub/png/spec/1.2/ + +To read an image all at once, see [[load]]. The PNG image data is returned +unmodified; the user is responsible for converting to the pixel format of their +choice. To read an image incrementally, see [[newreader]]. diff --git a/image/png/decoder.ha b/image/png/decoder.ha new file mode 100644 index 0000000..4516bb7 --- /dev/null +++ b/image/png/decoder.ha @@ -0,0 +1,171 @@ +use bufio; +use bytes; +use compress::zlib; +use io; + +export type decoder = struct { +	vtable: io::stream, +	src: io::handle, +	inflate: zlib::reader, +	ihdr: *ihdr, +	filter: (filter | void), +	bpp: size, // bytes per pixel, rounded up +	buffered: size, +	cr: []u8, +	pr: []u8, +}; + +// Returns a new image decoder, from which raw pixel data may be read via +// [[io::read]]. The input should be a compressed IDAT data stream, normally +// obtained via an [[idat_reader]]. +// +// The user must provide a pixel buffer of suitable size to store two scanlines +// for image filtering, or larger for interlaced images; see [[decoder_bufsiz]] +// to determine the appropriate length. +// +// The header is borrowed from the input and should remain valid until the +// decoder is no longer in use. +// +// The user must call [[io::close]] afterwards to free resources allocated for +// the decompressor. The call never returns an error. +export fn newdecoder( +	src: io::handle, +	ihdr: *ihdr, +	buf: []u8, +) (decoder | error) = { +	assert(len(buf) == decoder_bufsiz(ihdr), +		"Incorrect buffer length provided for PNG decoder"); +	bytes::zero(buf); +	return decoder { +		vtable = &decoder_vtable, +		src = src, +		inflate = zlib::decompress(src)?, +		ihdr = ihdr, +		filter = void, +		bpp = bytesperpixel(ihdr), +		buffered = 0, +		cr = buf[..len(buf) / 2], +		pr = buf[len(buf) / 2..], +	}; +}; + +const decoder_vtable: io::vtable = io::vtable { +	reader = &decoder_read, +	closer = &decoder_close, +	... +}; + +fn decoder_read(st: *io::stream, buf: []u8) (size | io::EOF | io::error) = { +	let dec = st: *decoder; +	assert(dec.vtable == &decoder_vtable); + +	if (dec.buffered != 0) { +		return decoder_copy(dec, buf); +	}; + +	if (dec.filter is void) { +		const ft = match (bufio::read_byte(&dec.inflate)?) { +		case io::EOF => +			if (!(io::read(dec.src, &[0u8])? is io::EOF)) { +				// Extra data following zlib stream +				return wraperror(invalid); +			}; +			return io::EOF; +		case let b: u8 => +			yield b: filter; +		}; +		if (ft > filter::PAETH) { +			return wraperror(unsupported); +		}; +		dec.filter = ft; +	}; + +	if (dec.ihdr.interlace == interlace::ADAM7) { +		abort(); // TODO +	}; + +	// Read one scanline +	match (io::readall(&dec.inflate, dec.cr)) { +	case io::EOF => +		return wraperror(invalid); +	case let err: io::error => +		if (err is io::underread) { +			return wraperror(invalid); +		}; +		return err; +	case size => void; +	}; + +	applyfilter(dec); +	dec.buffered = len(dec.cr); +	return decoder_copy(dec, buf); +}; + +fn decoder_close(st: *io::stream) (void | io::error) = { +	let dec = st: *decoder; +	assert(dec.vtable == &decoder_vtable); +	io::close(&dec.inflate)?; +}; + +// Returns the size of a buffer suitable to store decoder state for this image. +// The computed size is twice the length of a scanline in bytes, unless the +// image is interlaced, in which case the buffer size is the full length +// necessary to store the complete image. +export fn decoder_bufsiz(ihdr: *ihdr) size = { +	let sampledepth = ihdr.bitdepth: uint; +	const samples: uint = switch (ihdr.colortype) { +	case colortype::GRAYSCALE => +		yield 1; +	case colortype::RGB => +		yield 3; +	case colortype::PLTE => +		yield 1; +	case colortype::GRAYALPHA => +		yield 2; +	case colortype::RGBA => +		yield 4; +	}; +	const width = ihdr.width: uint, height = ihdr.height: uint; + +	let scanline = width * samples * sampledepth; // in bits +	if (scanline % 8 != 0) { +		// Pad to nearest byte +		scanline += 8 - (scanline % 8); +	}; + +	if (ihdr.interlace == interlace::ADAM7) { +		return scanline * height; +	}; + +	return (scanline / 8) * 2; // Two scanlines +}; + +fn bytesperpixel(ihdr: *ihdr) size = { +	let sampledepth = ihdr.bitdepth: uint; +	const samples: uint = switch (ihdr.colortype) { +	case colortype::GRAYSCALE => +		yield 1; +	case colortype::RGB => +		yield 3; +	case colortype::PLTE => +		yield 1; +	case colortype::GRAYALPHA => +		yield 2; +	case colortype::RGBA => +		yield 4; +	}; +	return (sampledepth * samples + 7) / 8; +}; + +// Copies pending pixel data into a user buffer. +fn decoder_copy(dec: *decoder, buf: []u8) size = { +	let max = dec.buffered; +	if (len(buf) < max) { +		max = len(buf); +	}; +	assert(max > 0); +	buf[..max] = dec.cr[..max]; +	dec.cr[..len(dec.cr)-max] = dec.cr[max..]; +	dec.buffered -= max; +	return max; +}; diff --git a/image/png/errors.ha b/image/png/errors.ha new file mode 100644 index 0000000..8f41ddb --- /dev/null +++ b/image/png/errors.ha @@ -0,0 +1,35 @@ +use errors; +use io; + +// Invalid PNG data was encountered. +export type invalid = !void; + +// PNG data using unsupported features was encountered. +export type unsupported = !void; + +// All errors which could be returned from this module. +export type error = !(io::error | invalid | unsupported); + +// Returns a human-friendly error string. +export fn strerror(err: error) const str = { +	match (err) { +	case let err: io::error => +		return io::strerror(err); +	case invalid => +		return "Invalid PNG format"; +	case unsupported => +		return "Provided PNG file requires unsupported features"; +	}; +}; + +fn wraperror(err: (invalid | unsupported)) errors::opaque_ = { +	static assert(size((invalid | unsupported)) <= size(errors::opaque_data)); +	let wrapped = errors::opaque_ { strerror = &opaque_strerror, ... }; +	let ptr = &wrapped.data: *error; +	*ptr = err; +	return wrapped; +}; + +fn opaque_strerror(err: *errors::opaque_data) const str = { +	return strerror(*(err: *(invalid | unsupported))); +}; diff --git a/image/png/filter.ha b/image/png/filter.ha new file mode 100644 index 0000000..5ae54e9 --- /dev/null +++ b/image/png/filter.ha @@ -0,0 +1,75 @@ +use bytes; +use io; +use memio; + +// Filter modes supported by PNG files. +export type filter = enum u8 { +	NONE = 0, +	SUB = 1, +	UP = 2, +	AVERAGE = 3, +	PAETH = 4, +}; + +fn applyfilter(dec: *decoder) void = { +	const mode = dec.filter as filter; +	const bpp = dec.bpp; +	switch (mode) { +	case filter::NONE => +		yield; // no-op +	case filter::SUB => +		for (let i = bpp; i < len(dec.cr); i += 1) { +			dec.cr[i] += dec.cr[i - bpp]; +		}; +	case filter::UP => +		for (let i = 0z; i < len(dec.cr); i += 1) { +			dec.cr[i] += dec.pr[i]; +		}; +	case filter::AVERAGE => +		for (let i = 0z; i < bpp; i += 1) { +			dec.cr[i] += dec.pr[i] / 2; +		}; +		for (let i = bpp; i < len(dec.cr); i += 1) { +			dec.cr[i] += ((dec.cr[i - bpp]: int + dec.pr[i]: int) / 2): u8; +		}; +	case filter::PAETH => +		applypaeth(dec); +	}; +	dec.filter = void; +	dec.pr[..] = dec.cr[..]; +}; + +@test fn filter_none() void = { +	const src = memio::fixed(no_filtering); +	const image = load(&src)!; +	defer image_finish(&image); +	assert(bytes::equal(image.pixels, no_filtering_data)); +}; + +@test fn filter_sub() void = { +	const src = memio::fixed(filter_sub_png); +	const image = load(&src)!; +	defer image_finish(&image); +	assert(bytes::equal(image.pixels, filter_sub_data)); +}; + +@test fn filter_up() void = { +	const src = memio::fixed(filter_up_png); +	const image = load(&src)!; +	defer image_finish(&image); +	assert(bytes::equal(image.pixels, filter_up_data)); +}; + +@test fn filter_average() void = { +	const src = memio::fixed(filter_avg_png); +	const image = load(&src)!; +	defer image_finish(&image); +	assert(bytes::equal(image.pixels, filter_avg_data)); +}; + +@test fn filter_peath() void = { +	const src = memio::fixed(filter_peath_png); +	const image = load(&src)!; +	defer image_finish(&image); +	assert(bytes::equal(image.pixels, filter_peath_data)); +}; diff --git a/image/png/idat.ha b/image/png/idat.ha new file mode 100644 index 0000000..dd2e749 --- /dev/null +++ b/image/png/idat.ha @@ -0,0 +1,82 @@ +use bufio; +use bytes; +use io; +use memio; + +export type idat_reader = struct { +	vtable: io::stream, +	src: *reader, +}; + +// Returns a new IDAT reader, which reads consecutive IDAT chunks from a +// [[reader]] and outputs their raw (compressed) contents as a continuous data +// stream. Instead of reading from this directly, users are advised to construct +// a [[decoder]] with [[newdecoder]], and use that to read the uncompressed +// pixel data. +// +// This stream does not need to be closed. +export fn new_idat_reader(src: *reader) idat_reader = { +	assert(chunk_type(src) == IDAT, +		"Attempted to create IDAT reader for non-IDAT chunk"); +	return idat_reader { +		vtable = &idat_reader_vtable, +		src = src, +	}; +}; + +const idat_reader_vtable: io::vtable = io::vtable { +	reader = &idat_read, +	... +}; + +fn idat_read( +	st: *io::stream, +	buf: []u8, +) (size | io::EOF | io::error) = { +	let st = st: *idat_reader; + +	assert(st.vtable == &idat_reader_vtable); + +	for (true) match (io::read(st.src, buf)?) { +	case io::EOF => +		match (nextchunk(st.src)) { +		case let err: (invalid | unsupported) => +			return wraperror(err); +		case let err: io::error => +			return err; +		case io::EOF => +			return io::EOF; +		case let ctype: u32 => +			if (ctype != IDAT) { +				return io::EOF; +			}; +		}; +	case let z: size => +		return z; +	}; +}; + +@test fn idat_reader() void = { +	const src = memio::fixed(no_filtering); +	const read = newreader(&src) as reader; +	assert(nextchunk(&read) as u32 == IHDR); +	const ihdr = ihdr_read(&read)!; + +	let pixbuf: []u8 = alloc([0...], decoder_bufsiz(&ihdr)); +	defer free(pixbuf); + +	for (true) { +		const ctype = nextchunk(&read) as u32; +		if (ctype == IDAT) { +			break; +		}; +		io::copy(io::empty, &read)!; +	}; + +	let idat = new_idat_reader(&read); +	let dec = newdecoder(&idat, &ihdr, pixbuf)!; +	defer io::close(&dec)!; +	const pixels = io::drain(&dec)!; +	defer free(pixels); +	assert(bytes::equal(pixels, no_filtering_data)); +}; diff --git a/image/png/iend.ha b/image/png/iend.ha new file mode 100644 index 0000000..97651a3 --- /dev/null +++ b/image/png/iend.ha @@ -0,0 +1,27 @@ +use bufio; +use io; +use memio; + +// Reads an IEND chunk from a [[reader]]. This function simply performs a sanity +// check and verifies the chunk checksum. +export fn iend_read(src: *reader) (void | error) = { +	assert(chunk_type(src) == IEND, +		"Attempted to call iend_read on non-IEND chunk"); +	io::copy(io::empty, src)?; +}; + +@test fn iend_reader() void = { +	const src = memio::fixed(simple_png); +	const read = newreader(&src) as reader; +	assert(nextchunk(&read) as u32 == IHDR); +	io::copy(io::empty, &read)!; + +	for (true) { +		if (nextchunk(&read) as u32 == IEND) { +			break; +		}; +		io::copy(io::empty, &read)!; +	}; + +	iend_read(&read)!; +}; diff --git a/image/png/ihdr.ha b/image/png/ihdr.ha new file mode 100644 index 0000000..bbb8e3e --- /dev/null +++ b/image/png/ihdr.ha @@ -0,0 +1,114 @@ +use endian; +use io; +use memio; + +// A PNG IHDR chunk. +export type ihdr = struct { +	width: u32, +	height: u32, +	bitdepth: u8, +	colortype: colortype, +	compression: compression, +	filter_mode: filter_mode, +	interlace: interlace, +}; + +// Pixel formats supported by PNG files. +export type colortype = enum u8 { +	GRAYSCALE = 0, +	RGB = 2, +	PLTE = 3, +	GRAYALPHA = 4, +	RGBA = 6, +}; + +// Compression types supported by PNG files. +export type compression = enum u8 { +	DEFLATE = 0, +}; + +export type filter_mode = enum u8 { +	ADAPTIVE = 0, +}; + +// Interlace types supported by PNG files. +export type interlace = enum u8 { +	NONE = 0, +	ADAM7 = 1, +}; + +// Reads an [[ihdr]] from a [[reader]]. +export fn ihdr_read(src: *reader) (ihdr | error) = { +	assert(chunk_type(src) == IHDR, +		"Attempted to call ihdr_read on non-IHDR chunk"); +	let buf: [13]u8 = [0...]; +	match (io::readall(src, buf)?) { +	case io::EOF => +		return invalid; +	case size => +		yield; +	}; +	// Read checksum +	if (!(io::read(src, &[0u8])? is io::EOF)) { +		return invalid; +	}; +	const hdr = ihdr { +		width = endian::begetu32(buf[..4]), +		height = endian::begetu32(buf[4..8]), +		bitdepth = buf[8], +		colortype = buf[9]: colortype, +		compression = buf[10]: compression, +		filter_mode = buf[11]: filter_mode, +		interlace = buf[12]: interlace, +	}; +	if ((hdr.width | hdr.height) & 0x80000000 > 0) { +		return invalid; +	}; +	switch (hdr.colortype) { +	case colortype::GRAYSCALE => +		if (hdr.bitdepth != 1 && hdr.bitdepth != 2 && hdr.bitdepth != 4 +				&& hdr.bitdepth != 8 && hdr.bitdepth != 16) { +			return invalid; +		}; +	case colortype::RGB => +		if (hdr.bitdepth != 8 && hdr.bitdepth != 16) { +			return invalid; +		}; +	case colortype::PLTE => +		if (hdr.bitdepth != 1 && hdr.bitdepth != 2 +				&& hdr.bitdepth != 4 && hdr.bitdepth != 8) { +			return invalid; +		}; +	case colortype::GRAYALPHA => +		if (hdr.bitdepth != 8 && hdr.bitdepth != 16) { +			return invalid; +		}; +	case colortype::RGBA => +		if (hdr.bitdepth != 8 && hdr.bitdepth != 16) { +			return invalid; +		}; +	case => +		return invalid; +	}; +	if (hdr.compression != compression::DEFLATE) { +		return unsupported; +	}; +	if (hdr.filter_mode != filter_mode::ADAPTIVE) { +		return unsupported; +	}; +	if (hdr.interlace > interlace::ADAM7) { +		return unsupported; +	}; +	return hdr; +}; + +@test fn ihdr_reader() void = { +	const src = memio::fixed(simple_png); +	const read = newreader(&src) as reader; +	assert(nextchunk(&read) as u32 == IHDR); +	const ihdr = ihdr_read(&read)!; +	assert(ihdr.width == 4 && ihdr.height == 4); +	assert(ihdr.colortype == colortype::RGB); +	assert(ihdr.filter_mode == filter_mode::ADAPTIVE); +	assert(ihdr.interlace == interlace::NONE); +}; diff --git a/image/png/load.ha b/image/png/load.ha new file mode 100644 index 0000000..d3578f8 --- /dev/null +++ b/image/png/load.ha @@ -0,0 +1,88 @@ +use errors; +use io; +use memio; + +// A decoded PNG image. +export type image = struct { +	// Image header +	ihdr: ihdr, +	// RGBA palette data (if present, otherwise an empty slice) +	palette: []u32, +	// Raw pixel data +	pixels: []u8, +}; + +// Reads a PNG image from an [[io::handle]], returning the decoded header, +// palette (if present), and raw pixel data. The caller must pass the return +// value to [[image_finish]] to discard resources associated with the image. +export fn load(in: io::handle) (image | error) = { +	let success = false; + +	const reader = newreader(in)?; + +	match (nextchunk(&reader)?) { +	case io::EOF => +		return invalid; +	case let ctype: u32 => +		if (ctype != IHDR) { +			return invalid; +		}; +	}; +	const ihdr = ihdr_read(&reader)?; +	let pixels: ([]u8 | void) = void; +	defer if (!success && pixels is []u8) free(pixels as []u8); +	let palette: []u32 = []; +	defer if (!success) free(palette); + +	for (true) match (nextchunk(&reader)?) { +	case io::EOF => +		return invalid; +	case let ctype: u32 => +		switch (ctype) { +		case IHDR => +			return invalid; +		case PLTE => +			if (len(palette) != 0) { +				return invalid; +			}; +			let plte = new_plte_reader(&reader)?; +			palette = alloc([0...], plte_ncolors(&plte)); +			plte_read(&plte, palette)?; +		case IDAT => +			if (pixels is []u8) { +				return invalid; +			}; +			let pixbuf: []u8 = alloc([0...], decoder_bufsiz(&ihdr)); +			defer free(pixbuf); +			let idat = new_idat_reader(&reader); +			let dec = newdecoder(&idat, &ihdr, pixbuf)?; +			defer io::close(&dec)!; +			pixels = io::drain(&dec)?; +		case IEND => +			iend_read(&reader)?; +			break; +		case => +			if (is_critical(ctype)) { +				return unsupported; +			}; +			io::copy(io::empty, &reader)?; +		}; +	}; + +	if (pixels is void) { +		return invalid; +	}; + +	success = true; +	return image { +		ihdr = ihdr, +		palette = palette, +		pixels = pixels as []u8, +	}; +}; + +// Frees resources associated with an [[image]]. +export fn image_finish(img: *image) void = { +	free(img.palette); +	free(img.pixels); +}; diff --git a/image/png/paeth.ha b/image/png/paeth.ha new file mode 100644 index 0000000..4abc373 --- /dev/null +++ b/image/png/paeth.ha @@ -0,0 +1,30 @@ +// Based on Go's implementation; BSD license +use math; + +fn applypaeth(dec: *decoder) void = { +	const bpp = dec.bpp; +	let a = 0i32, b = 0i32, c = 0i32, pa = 0i32, pb = 0i32, pc = 0i32; +	for (let i = 0z; i < bpp; i += 1) { +		a = 0; +		c = 0; +		for (let j = i; j < len(dec.cr); j += bpp) { +			b = dec.pr[j]: i32; +			pa = b - c; +			pb = a - c; +			pc = math::absi32(pa + pb): i32; +			pa = math::absi32(pa): i32; +			pb = math::absi32(pb): i32; +			if (pa <= pb && pa <= pc) { +				void; // no-op +			} else if (pb <= pc) { +				a = b; +			} else { +				a = c; +			}; +			a += dec.cr[j]: i32; +			a &= 0xff; +			dec.cr[j] = a: u8; +			c = b; +		}; +	}; +}; diff --git a/image/png/plte.ha b/image/png/plte.ha new file mode 100644 index 0000000..a19a263 --- /dev/null +++ b/image/png/plte.ha @@ -0,0 +1,95 @@ +use io; +use memio; + +export type plte_reader = struct { +	src: *reader, +}; + +// Returns a new PLTE reader for a [[chunk_reader]]. +export fn new_plte_reader(src: *reader) (plte_reader | invalid) = { +	assert(chunk_type(src) == PLTE, +		"Attempted to create PLTE reader for non-PLTE chunk"); +	const length = chunk_length(src); +	if (length % 3 != 0) { +		return invalid; +	}; +	const ncolor = length / 3; +	if (ncolor < 1 && ncolor > 256) { +		return invalid; +	}; +	return plte_reader { +		src = src, +	}; +}; + +// Returns the number of colors defined by this palette. The return value will +// be between 1 and 256 (inclusive), so should the caller wish to statically +// allocate a suitable buffer, [256]u32 will suffice for all cases. +export fn plte_ncolors(pr: *plte_reader) size = { +	return chunk_length(pr.src) / 3; +}; + +// Reads the palette from a PLTE chunk. The caller must provide a buffer equal +// in length to the return value of [[plte_ncolors]], which will be filled with +// RGB colors, such that the most significant byte is red and the least +// significant byte is unused (set to 0xFF). Returns the number of colors in the +// palette. +export fn plte_read(pr: *plte_reader, buf: []u32) (size | error) = { +	const ncolor = plte_ncolors(pr); +	assert(len(buf) == ncolor, "Invalid buffer size for plte_read"); + +	static let rbuf: [3 * 256]u8 = [0...]; +	for (let i = 0z; i < ncolor) { +		let n = (ncolor - i) * 3; +		if (n > len(rbuf)) { +			n = len(rbuf); +		}; +		match (io::readall(pr.src, rbuf[..n])?) { +		case io::EOF => +			return invalid; +		case size => +			yield; +		}; +		for (let q = 0z; q < n / 3; q += 1) { +			const r = rbuf[q * 3 + 0]: u32; +			const g = rbuf[q * 3 + 1]: u32; +			const b = rbuf[q * 3 + 2]: u32; +			buf[i + q] = (r << 24) | (g << 16) | (b << 8) | 0xFF; +		}; +		i += n / 3; +	}; +	// required so that the checksum gets read +	assert(io::read(pr.src, rbuf[..1])? is io::EOF); +	return ncolor; +}; + +@test fn plte_reader() void = { +	const src = memio::fixed(palette_sample); +	const read = newreader(&src) as reader; +	assert(nextchunk(&read) as u32 == IHDR); +	io::copy(io::empty, &read)!; + +	for (true) { +		const ctype = nextchunk(&read) as u32; +		if (ctype == PLTE) { +			break; +		}; +		io::copy(io::empty, &read)!; +	}; + +	const plte = new_plte_reader(&read)!; + +	let buf: []u32 = alloc([0...], plte_ncolors(&plte)); +	defer free(buf); +	plte_read(&plte, buf)!; + +	const expected: [_]u32 = [ +		0x2200FFFF, 0x00FFFFFF, 0x8800FFFF, 0x22FF00FF, 0x0099FFFF, +		0xFF6600FF, 0xDD00FFFF, 0x77FF00FF, 0xFF0000FF, 0x00FF99FF, +		0xDDFF00FF, 0xFF00BBFF, 0xFFBB00FF, 0x0044FFFF, 0x00FF44FF, +	]; +	assert(len(expected) == len(buf)); +	for (let i = 0z; i < len(expected); i += 1) { +		assert(buf[i] == expected[i]); +	}; +}; diff --git a/image/png/reader.ha b/image/png/reader.ha new file mode 100644 index 0000000..148a11f --- /dev/null +++ b/image/png/reader.ha @@ -0,0 +1,175 @@ +use bytes; +use endian; +use hash::crc32; +use hash; +use io; +use memio; + +export type reader = struct { +	vtable: io::stream, +	src: io::handle, +	status: reader_status, +	length: size, +	ctype: u32, +	crc: crc32::state, +}; + +export type reader_status = enum u8 { +	// cursor is at the start of a chunk header (or at EOF) +	NEXT, +	// cursor is at the end of a chunk header +	HEADER_READ, +	// cursor is within chunk data +	READING, +}; + +// Creates a new PNG decoder. Reads and verifies the PNG magic before returning +// the reader object. Call [[nextchunk]] to read the next chunk from the input. +export fn newreader(src: io::handle) (reader | error) = { +	let buf: [MAGIC_LEN]u8 = [0...]; +	match (io::readall(src, buf[..])?) { +	case io::EOF => +		return invalid; +	case size => +		yield; +	}; +	if (!bytes::equal(buf, magic)) { +		return invalid; +	}; +	return reader { +		vtable = &reader_vtable, +		src = src, +		status = reader_status::NEXT, +		length = 0, +		ctype = 0, +		crc = crc32::crc32(&crc32::ieee_table), +	}; +}; + +@test fn newreader() void = { +	const src = memio::fixed([]); +	assert(newreader(&src) as error is invalid); + +	const src = memio::fixed(magic); +	assert(newreader(&src) is reader); +}; + +// Starts decoding a new chunk from the reader, returning its type. The contents +// of the chunk can be read by calling [[io::read]] on the reader until it +// returns [[io::EOF]]. +// +// However, in an ideal scenario, the caller will not read directly from the +// chunk, but instead will select a chunk-type-aware decoder based on the +// returned chunk type, and use that to read the chunk's contents. +// +// Calling this function repeatedly will return the current chunk type with no +// side effects until [[io::read]] is called on the reader, after which the +// user must read the contents of the chunk until [[io::EOF]] is returned before +// calling nextchunk again. If the checksum fails verification, [[invalid]] is +// returned from [[io::read]]. +export fn nextchunk(src: *reader) (u32 | io::EOF | error) = { +	assert(src.status != reader_status::READING, +		"Must finish previous chunk before calling nextchunk again"); + +	if (src.status == reader_status::NEXT) { +		let buf: [8]u8 = [0...]; +		match (io::readall(src.src, buf[..])?) { +		case io::EOF => +			return io::EOF; +		case size => +			yield; +		}; +		src.status = reader_status::HEADER_READ; +		src.length = endian::begetu32(buf[..4]); +		src.ctype = endian::begetu32(buf[4..]); +		src.crc = crc32::crc32(&crc32::ieee_table); +		hash::write(&src.crc, buf[4..]); +	}; + +	return src.ctype; +}; + +const reader_vtable: io::vtable = io::vtable { +	reader = &read, +	... +}; + +// Returns the type of the chunk being read. +export fn chunk_type(src: *reader) u32 = { +	assert(src.status != reader_status::NEXT, +		"Must call nextchunk before calling chunk_type"); +	return src.ctype; +}; + +// Returns the remaining length of the chunk being read in bytes, not including +// the header or checksum (that is, it returns the length of the chunk data). +export fn chunk_length(src: *reader) size = { +	assert(src.status != reader_status::NEXT, +		"Must call nextchunk before calling chunk_length"); +	return src.length; +}; + +fn read(st: *io::stream, buf: []u8) (size | io::EOF | io::error) = { +	let st = st: *reader; +	assert(st.vtable == &reader_vtable); + +	if (st.status == reader_status::NEXT) { +		return io::EOF; +	}; +	st.status = reader_status::READING; + +	if (st.length == 0) { +		let ckbuf: [4]u8 = [0...]; +		match (io::readall(st.src, ckbuf[..])?) { +		case io::EOF => +			return wraperror(invalid); +		case size => +			yield; +		}; +		st.status = reader_status::NEXT; +		const want = endian::begetu32(ckbuf); +		const have = crc32::sum32(&st.crc); +		if (want != have) { +			return wraperror(invalid); +		}; +		return io::EOF; +	}; + +	const max = if (len(buf) < st.length) { +		yield len(buf); +	} else { +		yield st.length; +	}; + +	const z = match (io::read(st.src, buf[..max])?) { +	case io::EOF => +		// Missing checksum +		return wraperror(invalid); +	case let z: size => +		yield z; +	}; + +	hash::write(&st.crc, buf[..z]); +	st.length -= z; +	return z; +}; + +@test fn nextchunk() void = { +	const src = memio::fixed(magic); +	const read = newreader(&src) as reader; +	assert(nextchunk(&read) is io::EOF); + +	const src = memio::fixed(simple_png); +	const read = newreader(&src) as reader; +	assert(nextchunk(&read) as u32 == IHDR); +	let buf: [32]u8 = [0...]; +	assert(io::read(&read, buf) as size == 13); +	assert(io::read(&read, buf) is io::EOF); +	assert(bytes::equal(buf[..13], simple_png[16..16+13])); + +	const src = memio::fixed(invalid_chunk); +	const read = newreader(&src) as reader; +	nextchunk(&read) as u32; +	assert(io::read(&read, buf) as size == 13); +	assert(io::read(&read, buf) is io::error); +}; diff --git a/image/png/test_data.ha b/image/png/test_data.ha new file mode 100644 index 0000000..3e7a616 --- /dev/null +++ b/image/png/test_data.ha @@ -0,0 +1,638 @@ +const simple_png: [_]u8 = [ +	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, +	0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, +	0x08, 0x02, 0x00, 0x00, 0x00, 0x26, 0x93, 0x09, 0x29, 0x00, 0x00, 0x00, +	0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x2e, 0x23, 0x00, 0x00, 0x2e, +	0x23, 0x01, 0x78, 0xa5, 0x3f, 0x76, 0x00, 0x00, 0x00, 0x1e, 0x49, 0x44, +	0x41, 0x54, 0x08, 0xd7, 0x3d, 0xc6, 0xa1, 0x01, 0x00, 0x00, 0x08, 0x03, +	0x20, 0xe6, 0xff, 0x3f, 0xcf, 0xa4, 0x24, 0x52, 0x90, 0xc2, 0xfc, 0x10, +	0x37, 0xe9, 0xfc, 0xb0, 0xab, 0xa3, 0x06, 0x05, 0x5f, 0xaa, 0xb1, 0x1e, +	0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +]; + +const invalid_chunk: [_]u8 = [ +	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, +	0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, +	0x08, 0x02, 0x00, 0x01, 0x00, 0x26, 0x93, 0x09, 0x29, +]; + +const palette_sample: [_]u8 = [ +	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, +	0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +	0x04, 0x03, 0x00, 0x00, 0x00, 0x81, 0x54, 0x67, 0xc7, 0x00, 0x00, 0x00, +	0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x01, 0x86, 0xa0, 0x31, 0xe8, 0x96, +	0x5f, 0x00, 0x00, 0x00, 0x03, 0x73, 0x42, 0x49, 0x54, 0x04, 0x04, 0x04, +	0x77, 0xf8, 0xb5, 0xa3, 0x00, 0x00, 0x00, 0x2d, 0x50, 0x4c, 0x54, 0x45, +	0x22, 0x00, 0xff, 0x00, 0xff, 0xff, 0x88, 0x00, 0xff, 0x22, 0xff, 0x00, +	0x00, 0x99, 0xff, 0xff, 0x66, 0x00, 0xdd, 0x00, 0xff, 0x77, 0xff, 0x00, +	0xff, 0x00, 0x00, 0x00, 0xff, 0x99, 0xdd, 0xff, 0x00, 0xff, 0x00, 0xbb, +	0xff, 0xbb, 0x00, 0x00, 0x44, 0xff, 0x00, 0xff, 0x44, 0xd2, 0xb0, 0x49, +	0xbd, 0x00, 0x00, 0x00, 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, +	0xe8, 0xe8, 0x08, 0x0d, 0x3d, 0x73, 0x66, 0xd5, 0xaa, 0xf2, 0x72, 0x63, +	0xe3, 0x77, 0xef, 0x66, 0xce, 0x64, 0x20, 0x43, 0x00, 0x95, 0x2b, 0x28, +	0x48, 0x8e, 0x00, 0x2a, 0xd7, 0xc5, 0x85, 0x1c, 0x01, 0x54, 0xee, 0xdd, +	0xbb, 0xe4, 0x08, 0xa0, 0x71, 0x19, 0xc8, 0x11, 0x40, 0xe5, 0x2a, 0x29, +	0x91, 0x23, 0x80, 0xca, 0x4d, 0x4b, 0x23, 0x47, 0x00, 0x95, 0xbb, 0x7b, +	0x37, 0x19, 0x02, 0x00, 0xe0, 0xc4, 0xea, 0xd1, 0x0f, 0x82, 0x05, 0x7d, +	0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +]; + +const no_filtering: [_]u8 = [ +	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, +	0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +	0x08, 0x00, 0x00, 0x00, 0x00, 0x56, 0x11, 0x25, 0x28, 0x00, 0x00, 0x01, +	0x06, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x85, 0xd2, 0x2f, 0x4c, 0x42, +	0x51, 0x14, 0xc7, 0xf1, 0xaf, 0xe0, 0x18, 0x73, 0x63, 0x06, 0x37, 0x37, +	0x02, 0x81, 0x62, 0xa0, 0x58, 0x48, 0xaf, 0xbc, 0xf4, 0x9a, 0x89, 0x66, +	0xb3, 0x11, 0x69, 0x54, 0x23, 0x8d, 0x48, 0xb3, 0xd1, 0x6c, 0x26, 0x12, +	0x89, 0x62, 0xb1, 0x58, 0x0c, 0x16, 0x37, 0x83, 0x9b, 0x1b, 0x9b, 0x9b, +	0x73, 0x0c, 0xe4, 0xe9, 0xfd, 0xe3, 0x76, 0xce, 0xf5, 0x85, 0x73, 0xeb, +	0xfd, 0xec, 0x9e, 0xdf, 0xfd, 0xdd, 0xcb, 0xf5, 0x64, 0x3a, 0xbb, 0x99, +	0xdf, 0xde, 0x2d, 0x96, 0xab, 0xfb, 0x87, 0xc7, 0xa7, 0xe7, 0x97, 0xd7, +	0xb7, 0xf7, 0xf5, 0xc7, 0xe7, 0xd7, 0x66, 0xbb, 0xfb, 0xde, 0x97, 0xe5, +	0x0f, 0x63, 0x43, 0x30, 0x32, 0x04, 0x43, 0x43, 0x70, 0x65, 0x08, 0x2e, +	0x0d, 0xc1, 0xc0, 0x10, 0x5c, 0x18, 0x82, 0x42, 0x0b, 0xc2, 0x4a, 0x04, +	0xb9, 0x12, 0x50, 0x15, 0x64, 0x22, 0xdc, 0x96, 0x9f, 0x92, 0x0a, 0xfa, +	0x22, 0x20, 0xe6, 0x00, 0x95, 0x83, 0x73, 0x11, 0x10, 0x92, 0xba, 0x13, +	0x54, 0x52, 0x7a, 0x22, 0xc0, 0x27, 0xf5, 0x21, 0xd4, 0x5d, 0x38, 0x13, +	0x81, 0x7f, 0xb9, 0x90, 0x52, 0xdd, 0x96, 0xae, 0x08, 0xf0, 0x39, 0x70, +	0x67, 0xa8, 0x3e, 0xe8, 0x88, 0x00, 0x37, 0x05, 0x7f, 0x5b, 0xd5, 0x18, +	0x6d, 0x11, 0xe1, 0xf4, 0x30, 0x45, 0x75, 0xca, 0xa9, 0x08, 0xbf, 0x1f, +	0xfb, 0x50, 0xad, 0x73, 0x22, 0xc2, 0xed, 0x27, 0x7d, 0x04, 0xc1, 0xb1, +	0x08, 0x48, 0xfa, 0x88, 0x82, 0x96, 0x08, 0xa2, 0x20, 0xf6, 0xf1, 0x27, +	0x38, 0x4a, 0x45, 0x58, 0xfa, 0xf5, 0x69, 0x56, 0x45, 0xf2, 0x3f, 0x68, +	0x24, 0x22, 0xcb, 0x8b, 0x7f, 0x3f, 0x88, 0x43, 0x43, 0x50, 0x37, 0x04, +	0x35, 0x43, 0x70, 0x60, 0x08, 0x2c, 0x81, 0x25, 0xb0, 0xc4, 0x2f, 0xc4, +	0x7d, 0xca, 0x58, 0x50, 0xa6, 0xce, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x49, +	0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +]; + +const no_filtering_data: [_]u8 = [ +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0xfc, 0xfd, 0xfe, 0xfe, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x00, 0x00, 0x00, 0x9d, 0xa4, +	0xab, 0xb2, 0x00, 0x00, 0x00, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x00, 0x00, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0x00, +	0x00, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x00, +	0x00, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0x00, 0x00, 0x00, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x00, 0x00, 0x7f, 0x87, 0x8e, +	0x96, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x00, 0x00, 0x76, 0x7f, 0x87, 0x00, 0x00, 0x00, 0x00, +	0x00, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x00, +	0x00, 0x6f, 0x76, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x00, 0x00, 0x67, 0x00, 0x00, +	0x00, 0x87, 0x8e, 0x00, 0x00, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x7f, 0x87, 0x00, +	0x00, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x00, +	0x00, 0x00, 0x00, 0x67, 0x6f, 0x76, 0x7f, 0x00, 0x00, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x00, 0x00, 0x00, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x00, 0x00, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x00, 0x00, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x00, +	0x00, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x00, +	0x00, 0x00, 0x4c, 0x52, 0x59, 0x60, 0x00, 0x00, 0x00, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x01, 0x02, 0x03, 0x04, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x00, 0x00, 0x00, 0x01, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, +]; + +const filter_sub_png: [_]u8 = [ +	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, +	0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +	0x08, 0x00, 0x00, 0x00, 0x00, 0x56, 0x11, 0x25, 0x28, 0x00, 0x00, 0x01, +	0x08, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x85, 0xd2, 0x21, 0x4b, 0xc4, +	0x41, 0x10, 0x05, 0xf0, 0xf7, 0x76, 0x76, 0x76, 0xf6, 0x04, 0x31, 0x08, +	0x82, 0xc1, 0x60, 0x31, 0x58, 0x2c, 0x26, 0x8b, 0xc9, 0x66, 0x12, 0x0c, +	0x36, 0xc1, 0x60, 0x14, 0x2e, 0x08, 0xa6, 0xe3, 0x92, 0x60, 0x38, 0xb8, +	0x22, 0x5c, 0x10, 0x0c, 0x82, 0x41, 0x30, 0x88, 0xc1, 0xe4, 0x27, 0xb0, +	0xf8, 0x8d, 0x0c, 0x1e, 0xf7, 0xdf, 0xd9, 0xb0, 0xbb, 0xf9, 0xc7, 0xbe, +	0x99, 0xe1, 0x71, 0x92, 0x2d, 0x9b, 0x99, 0xa5, 0x94, 0x54, 0x55, 0xa3, +	0x4a, 0x14, 0x11, 0x09, 0x21, 0x90, 0x24, 0xc8, 0xdb, 0x51, 0x47, 0xdc, +	0x58, 0x5b, 0xf0, 0x3a, 0x77, 0xc4, 0xa5, 0x75, 0xc4, 0x85, 0x75, 0xc4, +	0x99, 0x75, 0xc4, 0x69, 0x6a, 0x0b, 0x9e, 0x98, 0x13, 0xe7, 0xf8, 0xf6, +	0x82, 0xc7, 0xa9, 0x14, 0x57, 0xc0, 0x97, 0xff, 0x83, 0x47, 0x5a, 0x88, +	0x31, 0x80, 0x0f, 0x9f, 0xc2, 0xc3, 0x34, 0x88, 0x29, 0x00, 0xbc, 0xf9, +	0x39, 0x78, 0xa0, 0x2b, 0x31, 0x07, 0x66, 0x63, 0xbc, 0xf8, 0x49, 0xb9, +	0xaf, 0x2b, 0xb1, 0xc0, 0x24, 0xdf, 0xe1, 0xc9, 0xef, 0xc2, 0xbd, 0x38, +	0x88, 0x6c, 0xa3, 0x29, 0x1e, 0xfd, 0xb6, 0xdc, 0x55, 0x27, 0x1e, 0x30, +	0xf3, 0xf7, 0xe0, 0x4e, 0x74, 0x62, 0x8e, 0x7b, 0x7f, 0x31, 0x6e, 0x47, +	0x27, 0x16, 0xa8, 0x1a, 0xc4, 0x2d, 0x71, 0xe2, 0x19, 0x55, 0x83, 0xb8, +	0x29, 0x4e, 0xbc, 0xa2, 0x6a, 0x10, 0x37, 0xa2, 0x13, 0xef, 0xa8, 0x1a, +	0xc4, 0xf5, 0xe0, 0xc4, 0x27, 0xaa, 0x06, 0x71, 0x4d, 0x06, 0xf1, 0x83, +	0xff, 0x57, 0xa6, 0x30, 0x87, 0x41, 0xfc, 0x2e, 0x41, 0x99, 0xc2, 0x14, +	0x0a, 0x51, 0xde, 0x74, 0x29, 0x18, 0x43, 0x5b, 0x50, 0xd8, 0x16, 0x0c, +	0x6c, 0x0b, 0x92, 0x6d, 0x41, 0x74, 0x04, 0xd1, 0x11, 0x44, 0x47, 0xfc, +	0x01, 0x95, 0x51, 0x2c, 0x83, 0x13, 0x7f, 0xab, 0x0a, 0x00, 0x00, 0x00, +	0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +]; + +const filter_sub_data: [_]u8 = [ +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0xfc, 0xfd, 0xfe, 0xfe, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0x00, 0x00, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0x00, 0x00, 0x00, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x00, 0x00, 0x00, +	0x00, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x00, +	0x00, 0x00, 0x8e, 0x00, 0x00, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x00, 0x00, 0x7f, 0x87, 0x00, +	0x00, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x00, 0x00, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x00, 0x00, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x00, +	0x00, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x00, 0x00, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x00, 0x00, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x00, +	0x00, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x00, 0x00, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x00, 0x00, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x01, 0x02, 0x03, 0x04, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x00, 0x00, 0x00, 0x01, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, +]; + +const filter_up_png: [_]u8 = [ +	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, +	0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +	0x08, 0x00, 0x00, 0x00, 0x00, 0x56, 0x11, 0x25, 0x28, 0x00, 0x00, 0x01, +	0x2a, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x85, 0xd1, 0x2f, 0x4b, 0x83, +	0x51, 0x18, 0x05, 0xf0, 0xc3, 0xf9, 0x38, 0x16, 0x8b, 0x20, 0x88, 0x20, +	0x08, 0x82, 0x41, 0x0c, 0x03, 0x83, 0x4d, 0xd8, 0x07, 0x18, 0x2c, 0x58, +	0x87, 0x49, 0x30, 0x0c, 0x56, 0x04, 0xc3, 0x0b, 0x0b, 0x03, 0xc3, 0x60, +	0xe1, 0x4d, 0x82, 0x60, 0x12, 0xc1, 0x62, 0xb1, 0x18, 0x2c, 0x82, 0x41, +	0x10, 0x04, 0x41, 0xf4, 0x7d, 0xee, 0x5f, 0xc3, 0xa6, 0xf7, 0xb9, 0xef, +	0xc2, 0xbd, 0xf9, 0xc7, 0xe5, 0x9c, 0xf3, 0x70, 0x70, 0x3a, 0x3c, 0xaf, +	0x26, 0xd3, 0xfa, 0xea, 0xe6, 0xf6, 0xfe, 0xe1, 0xf1, 0xe9, 0xf9, 0xe5, +	0xf5, 0xed, 0xfd, 0xe3, 0xf3, 0xeb, 0xbb, 0x31, 0xd6, 0xf9, 0x10, 0x22, +	0x7f, 0x1a, 0x69, 0x44, 0x44, 0x8c, 0x31, 0xd6, 0x5a, 0xeb, 0xac, 0x77, +	0xde, 0x7b, 0x1f, 0x42, 0x88, 0x31, 0x46, 0x44, 0x4a, 0x41, 0xb0, 0x29, +	0x08, 0x4a, 0x41, 0x50, 0x0a, 0x82, 0x52, 0x10, 0x34, 0x05, 0x41, 0xd1, +	0xe2, 0x60, 0x7f, 0x77, 0x7b, 0x73, 0x3d, 0x13, 0x34, 0x4a, 0x74, 0x01, +	0x00, 0xc8, 0x04, 0x6d, 0x12, 0x7d, 0xa0, 0x9a, 0x4c, 0xeb, 0x5c, 0xd0, +	0x24, 0x01, 0x0c, 0x45, 0x44, 0x6a, 0x40, 0xe5, 0xa0, 0x4d, 0x02, 0x98, +	0x27, 0x05, 0x54, 0x52, 0xda, 0x24, 0x7a, 0xc7, 0xf3, 0x2e, 0x80, 0xea, +	0x42, 0xa7, 0xc4, 0xa2, 0x0b, 0xa0, 0xda, 0xd2, 0x2e, 0x89, 0x2e, 0xa0, +	0xf6, 0xa0, 0x6b, 0x8b, 0x3e, 0x50, 0xa9, 0xc5, 0xe8, 0x5a, 0xe2, 0x64, +	0xd1, 0xe5, 0x4f, 0xd0, 0xe7, 0x62, 0x04, 0x0c, 0xb2, 0xd5, 0xe9, 0x33, +	0x31, 0x06, 0x7a, 0xf9, 0x5d, 0xe8, 0xb4, 0x98, 0x01, 0x47, 0xad, 0xcb, +	0x31, 0x28, 0x71, 0x0d, 0x74, 0xda, 0xb7, 0xa5, 0x4f, 0xe2, 0x0e, 0xc0, +	0xec, 0x72, 0x7c, 0x31, 0x3a, 0x53, 0x82, 0x21, 0x09, 0xfc, 0x3f, 0xf5, +	0x07, 0x43, 0x12, 0x2b, 0xab, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b, 0x9d, 0x43, +	0x9d, 0x83, 0x41, 0x89, 0xe5, 0xd5, 0x45, 0x18, 0x0b, 0x82, 0xb1, 0x20, +	0x18, 0x0b, 0x82, 0xb1, 0x20, 0x88, 0x82, 0x20, 0x0a, 0xe2, 0x17, 0xe9, +	0xe4, 0x97, 0xbf, 0xbf, 0xcc, 0xeb, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x49, +	0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +]; + +const filter_up_data: [_]u8 = [ +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0xfc, 0xfd, 0xfe, 0xfe, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x00, 0x00, 0x00, 0x9d, 0xa4, +	0xab, 0xb2, 0x00, 0x00, 0x00, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x00, 0x00, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0x00, +	0x00, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x00, +	0x00, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0x00, 0x00, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0x00, 0x00, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x00, +	0x00, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x00, 0x00, 0x00, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x00, 0x00, 0x00, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x00, 0x00, 0x00, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x00, 0x00, 0x00, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x00, 0x00, +	0x00, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x00, 0x00, 0x00, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x00, 0x00, 0x00, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x01, 0x02, 0x03, 0x04, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x00, 0x00, 0x00, 0x01, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, +]; + +const filter_avg_png: [_]u8 = [ +	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, +	0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +	0x08, 0x00, 0x00, 0x00, 0x00, 0x56, 0x11, 0x25, 0x28, 0x00, 0x00, 0x01, +	0x4c, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x7d, 0xd2, 0xb1, 0x4b, 0x42, +	0x51, 0x14, 0xc7, 0xf1, 0xef, 0xe9, 0x84, 0x44, 0x51, 0x10, 0x11, 0x0d, +	0x21, 0x45, 0x82, 0x50, 0x14, 0x34, 0x04, 0x2e, 0x0e, 0x41, 0xcb, 0x03, +	0x07, 0xa1, 0x21, 0x08, 0x8a, 0x22, 0x10, 0x21, 0x03, 0x83, 0xa2, 0x48, +	0xcc, 0xe7, 0xda, 0x5f, 0x10, 0x42, 0x05, 0x41, 0xd0, 0x20, 0x38, 0x34, +	0xb5, 0x38, 0x08, 0x35, 0x34, 0x04, 0x0d, 0x41, 0xe0, 0x1f, 0xe0, 0xbf, +	0xf1, 0x1a, 0xd4, 0xe7, 0x79, 0xca, 0x7b, 0x77, 0xb9, 0x1c, 0xf8, 0x70, +	0xef, 0xb9, 0xf7, 0x77, 0xd4, 0x75, 0x32, 0xd9, 0xdd, 0xbd, 0xfd, 0xc3, +	0xa3, 0x93, 0x5c, 0xfe, 0xf4, 0xac, 0x78, 0x7e, 0x71, 0x79, 0x75, 0x7d, +	0x53, 0x2a, 0x97, 0x6f, 0x2b, 0x15, 0xd7, 0xad, 0xba, 0x55, 0x4d, 0x89, +	0x20, 0x80, 0xd0, 0xdb, 0x86, 0x4a, 0xdd, 0xf2, 0xa2, 0x85, 0x6e, 0x4a, +	0xb4, 0xd0, 0x0d, 0xa2, 0x85, 0xae, 0x12, 0x2d, 0x34, 0x49, 0xb4, 0xd0, +	0x04, 0xd1, 0x42, 0x97, 0xc4, 0x17, 0x85, 0x46, 0xfd, 0xf5, 0xe5, 0xf9, +	0xe9, 0xa1, 0x76, 0x9f, 0x1f, 0x08, 0x8d, 0xe3, 0x8b, 0x26, 0xfd, 0x95, +	0x1b, 0x9c, 0xa1, 0x8b, 0xf8, 0xa2, 0xfb, 0xa7, 0x75, 0xf8, 0x30, 0xb7, +	0xe8, 0x82, 0x0c, 0x84, 0x20, 0x1c, 0xc0, 0xbb, 0xed, 0x43, 0xe7, 0x09, +	0x88, 0x02, 0xd4, 0x03, 0x9d, 0xea, 0x1c, 0x56, 0x94, 0xe0, 0x31, 0xf8, +	0x16, 0x9d, 0xc5, 0x88, 0x3b, 0xe0, 0xad, 0x91, 0xb5, 0x42, 0x67, 0xcc, +	0xf3, 0xf9, 0xc6, 0x75, 0x9a, 0x04, 0x84, 0x4e, 0xdb, 0x0f, 0x4a, 0xa5, +	0x3d, 0x19, 0x12, 0x3a, 0x85, 0x15, 0x88, 0x27, 0x4e, 0x93, 0x8c, 0x89, +	0x7b, 0x92, 0x11, 0xd1, 0xc2, 0x31, 0x71, 0x4f, 0x30, 0x22, 0x3e, 0xd9, +	0x31, 0x71, 0xc7, 0xc4, 0x17, 0xad, 0x76, 0x37, 0xb9, 0x2f, 0xb6, 0x4d, +	0xdc, 0x31, 0xcf, 0x17, 0x1d, 0xda, 0x09, 0xa0, 0x06, 0x69, 0x13, 0xf7, +	0xb8, 0xf8, 0x22, 0xde, 0xa1, 0xfd, 0xf7, 0xfb, 0x03, 0x45, 0x93, 0xbe, +	0x2a, 0x01, 0x01, 0x70, 0x6c, 0xe7, 0x43, 0xc7, 0xb0, 0x62, 0x79, 0x25, +	0xb9, 0xb6, 0x1e, 0x98, 0x20, 0x15, 0xac, 0x08, 0x26, 0x27, 0x80, 0xf6, +	0xcb, 0x30, 0xd1, 0x05, 0x11, 0x42, 0x7b, 0x43, 0x16, 0x2a, 0xfa, 0x20, +	0x54, 0xf8, 0x20, 0x4c, 0x0c, 0x40, 0x88, 0xf8, 0x07, 0x63, 0x67, 0x5c, +	0x42, 0xbc, 0xfe, 0x0b, 0x39, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +	0x44, 0xae, 0x42, 0x60, 0x82, +]; + +const filter_avg_data: [_]u8 = [ +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0xfc, 0xfd, 0xfe, 0xfe, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0x00, 0x00, 0x00, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x00, 0x00, 0x00, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x00, 0x00, 0x00, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x00, 0x00, +	0x00, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x00, 0x00, 0x7f, 0x87, 0x00, 0x00, 0x00, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x00, 0x00, 0x00, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x00, +	0x00, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x00, 0x00, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x00, 0x00, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x00, 0x00, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x00, +	0x00, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x00, +	0x00, 0x00, 0x4c, 0x52, 0x59, 0x60, 0x00, 0x00, 0x00, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x01, 0x02, 0x03, 0x04, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x00, 0x00, 0x00, 0x01, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, +]; + +const filter_peath_png: [_]u8 = [ +	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, +	0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +	0x08, 0x00, 0x00, 0x00, 0x00, 0x56, 0x11, 0x25, 0x28, 0x00, 0x00, 0x00, +	0xd4, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x85, 0xd1, 0xc1, 0x6d, 0xc2, +	0x30, 0x14, 0x80, 0xe1, 0xdf, 0xf6, 0xb3, 0xcd, 0x4c, 0x9d, 0xa1, 0x62, +	0x06, 0xa4, 0x0e, 0xc0, 0x0d, 0x29, 0xa7, 0x6e, 0x80, 0xd4, 0x4b, 0x27, +	0xa8, 0x94, 0x2d, 0x58, 0x0b, 0x42, 0x21, 0xe6, 0xc0, 0x01, 0xdb, 0x0f, +	0xdb, 0x39, 0x44, 0x7a, 0xd1, 0xa7, 0xff, 0xd9, 0x8a, 0x7c, 0x6f, 0xe2, +	0x26, 0xc6, 0x18, 0x43, 0x08, 0xde, 0x7b, 0x2f, 0xde, 0x89, 0x73, 0xce, +	0x59, 0x6b, 0x8d, 0x31, 0x06, 0x23, 0x67, 0x5a, 0x8f, 0x05, 0x4c, 0x92, +	0xa5, 0x09, 0x9e, 0x42, 0x2e, 0x6d, 0x80, 0x05, 0x7a, 0x05, 0xb0, 0x23, +	0x80, 0x1d, 0x01, 0xac, 0x5c, 0xfb, 0x40, 0x15, 0xb6, 0x9c, 0x2a, 0xa0, +	0x0a, 0xd5, 0x07, 0xf9, 0x2f, 0xc6, 0x2f, 0x0d, 0xea, 0xc2, 0x5f, 0xb5, +	0xb3, 0x2c, 0x4c, 0x50, 0xdf, 0xaa, 0x5a, 0xc1, 0x51, 0x81, 0x5b, 0x36, +	0xfc, 0xe8, 0x40, 0x5d, 0x38, 0xa8, 0x5f, 0x93, 0x17, 0x66, 0x58, 0x60, +	0xe2, 0xb7, 0xb9, 0x82, 0xdd, 0x05, 0xa0, 0xa8, 0xc8, 0x3d, 0x9f, 0x96, +	0xec, 0xfd, 0x16, 0xcc, 0x00, 0x4c, 0x1c, 0x5b, 0x2b, 0xca, 0xd2, 0x13, +	0xac, 0x2f, 0xf1, 0xe1, 0x43, 0x0c, 0x71, 0x66, 0x1f, 0xb3, 0x53, 0xc8, +	0x1d, 0xd5, 0x28, 0x0f, 0xb9, 0xa2, 0xc4, 0x52, 0x83, 0x52, 0x7c, 0x06, +	0x0d, 0xf4, 0x96, 0x0c, 0xa4, 0x81, 0x90, 0x44, 0x5f, 0x48, 0xa2, 0x2f, +	0x24, 0xd1, 0x17, 0xc2, 0x40, 0x08, 0x03, 0xf1, 0x00, 0x16, 0x26, 0x4c, +	0x07, 0x21, 0x99, 0x60, 0x81, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +	0x44, 0xae, 0x42, 0x60, 0x82, +]; + +const filter_peath_data: [_]u8 = [ +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0xfc, 0xfd, 0xfe, 0xfe, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0xf8, 0xfa, 0xfb, 0xfc, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, 0xf8, 0xfa, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0xf1, 0xf4, 0xf6, 0xf8, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0x00, 0x00, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf6, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0x00, 0x00, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x00, 0x00, +	0x00, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0xe8, 0xeb, 0xee, 0xf1, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x00, 0x00, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0xee, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x00, 0x00, 0x00, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, 0xe8, 0xeb, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x00, 0x00, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0xdc, 0xe1, 0xe4, 0xe8, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x00, 0x00, 0x00, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0xe4, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x00, 0x00, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, 0xdc, 0xe1, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x00, 0x00, 0x00, 0x6f, 0x76, +	0x7f, 0x00, 0x00, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0xce, 0xd3, 0xd8, 0xdc, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x00, 0x00, 0x60, 0x67, 0x6f, 0x76, 0x00, 0x00, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0xd8, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x00, +	0x00, 0x59, 0x60, 0x67, 0x6f, 0x00, 0x00, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, 0xce, 0xd3, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0xbe, 0xc4, 0xc9, 0xce, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0xc9, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x00, 0x00, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, 0xbe, 0xc4, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x00, 0x00, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0xab, 0xb2, 0xb8, 0xbe, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x00, 0x00, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb8, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x96, 0x9d, 0xa4, 0xab, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0xa4, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, 0x96, 0x9d, 0x01, 0x02, 0x03, 0x04, +	0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, +	0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, +	0x7f, 0x87, 0x8e, 0x96, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, +	0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, +	0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x8e, +	0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, +	0x16, 0x19, 0x1d, 0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, +	0x52, 0x59, 0x60, 0x67, 0x6f, 0x76, 0x7f, 0x87, 0x00, 0x00, 0x00, 0x01, +	0x02, 0x03, 0x04, 0x06, 0x08, 0x0a, 0x0d, 0x0f, 0x13, 0x16, 0x19, 0x1d, +	0x21, 0x26, 0x2a, 0x2f, 0x34, 0x3a, 0x3f, 0x45, 0x4c, 0x52, 0x59, 0x60, +	0x67, 0x6f, 0x76, 0x7f, +]; diff --git a/image/png/types.ha b/image/png/types.ha new file mode 100644 index 0000000..b970175 --- /dev/null +++ b/image/png/types.ha @@ -0,0 +1,69 @@ +// The PNG magic number. +export const magic: [_]u8 = [137, 80, 78, 71, 13, 10, 26, 10]; + +def MAGIC_LEN: size = 8; + +// The chunk header type for an IHDR chunk. +export def IHDR: u32 = 0x49484452; + +// The chunk header type for a PLTE chunk. +export def PLTE: u32 = 0x504c5445; + +// The chunk header type for an IDAT chunk. +export def IDAT: u32 = 0x49444154; + +// The chunk header type for an IEND chunk. +export def IEND: u32 = 0x49454e44; + +// The chunk header type for a tRNS chunk. +export def TRNS: u32 = 0x74524e53; + +// The chunk header type for a gAMA chunk. +export def GAMA: u32 = 0x67414d41; + +// The chunk header type for an sRGB chunk. +export def SRGB: u32 = 0x73524742; + +// The chunk header type for an iCCP chunk. +export def ICCP: u32 = 0x69434350; + +// The chunk header type for a tEXT chunk. +export def TEXT: u32 = 0x74455854; + +// The chunk header type for a zTXT chunk. +export def ZTXT: u32 = 0x7a545854; + +// The chunk header type for an iTXT chunk. +export def ITXT: u32 = 0x69545854; + +// The chunk header type for a bKGD chunk. +export def BKGD: u32 = 0x624b4744; + +// The chunk header type for a pHYS chunk. +export def PHYS: u32 = 0x70485953; + +// The chunk header type for a sBIT chunk. +export def SBIT: u32 = 0x73424954; + +// The chunk header type for a sPLT chunk. +export def SPLT: u32 = 0x73504c54; + +// The chunk header type for a hIST chunk. +export def HIST: u32 = 0x68495354; + +// The chunk header type for a tIME chunk. +export def TIME: u32 = 0x74494d45; + +// Returns true if the given chunk type is a "critical" chunk. +export fn is_critical(ctype: u32) bool = { +	return ctype & (1 << 29) == 0; +}; + +@test fn is_critical() void = { +	assert(is_critical(IHDR) == true); +	assert(is_critical(PLTE) == true); +	assert(is_critical(IDAT) == true); +	assert(is_critical(IEND) == true); +	assert(is_critical(HIST) == false); +	assert(is_critical(TIME) == false); +}; @@ -0,0 +1,214 @@ +// Key codes as defined by the USB HID Usage Tables 1.4 specification, +// located at <https://usb.org/sites/default/files/hut1_4.pdf>. + +def KEY_A = 0x04: Key; +def KEY_B = 0x05: Key; +def KEY_C = 0x06: Key; +def KEY_D = 0x07: Key; +def KEY_E = 0x08: Key; +def KEY_F = 0x09: Key; +def KEY_G = 0x0a: Key; +def KEY_H = 0x0b: Key; +def KEY_I = 0x0c: Key; +def KEY_J = 0x0d: Key; +def KEY_K = 0x0e: Key; +def KEY_L = 0x0f: Key; +def KEY_M = 0x10: Key; +def KEY_N = 0x11: Key; +def KEY_O = 0x12: Key; +def KEY_P = 0x13: Key; +def KEY_Q = 0x14: Key; +def KEY_R = 0x15: Key; +def KEY_S = 0x16: Key; +def KEY_T = 0x17: Key; +def KEY_U = 0x18: Key; +def KEY_V = 0x19: Key; +def KEY_W = 0x1a: Key; +def KEY_X = 0x1b: Key; +def KEY_Y = 0x1c: Key; +def KEY_Z = 0x1d: Key; +def KEY_1 = 0x1e: Key; +def KEY_2 = 0x1f: Key; +def KEY_3 = 0x20: Key; +def KEY_4 = 0x21: Key; +def KEY_5 = 0x22: Key; +def KEY_6 = 0x23: Key; +def KEY_7 = 0x24: Key; +def KEY_8 = 0x25: Key; +def KEY_9 = 0x26: Key; +def KEY_0 = 0x27: Key; +def KEY_RETURN_ENTER = 0x28: Key; +def KEY_ESCAPE = 0x29: Key; +def KEY_BACKSPACE = 0x2a: Key; +def KEY_TAB = 0x2b: Key; +def KEY_SPACE = 0x2c: Key; +def KEY_HYPHEN = 0x2d: Key; +def KEY_EQUALS = 0x2e: Key; +def KEY_LBRACKET = 0x2f: Key; +def KEY_RBRACKET = 0x30: Key; +def KEY_BACKSLASH = 0x31: Key; +def KEY_NON_US_HASH = 0x32: Key; +def KEY_SEMICOLON = 0x33: Key; +def KEY_APOSTROPHE = 0x34: Key; +def KEY_GRAVE = 0x35: Key; +def KEY_COMMA = 0x36: Key; +def KEY_PERIOD = 0x37: Key; +def KEY_SLASH = 0x38: Key; +def KEY_CAPS_LOCK = 0x39: Key; +def KEY_F1 = 0x3a: Key; +def KEY_F2 = 0x3b: Key; +def KEY_F3 = 0x3c: Key; +def KEY_F4 = 0x3d: Key; +def KEY_F5 = 0x3e: Key; +def KEY_F6 = 0x3f: Key; +def KEY_F7 = 0x40: Key; +def KEY_F8 = 0x41: Key; +def KEY_F9 = 0x42: Key; +def KEY_F10 = 0x43: Key; +def KEY_F11 = 0x44: Key; +def KEY_F12 = 0x45: Key; +def KEY_PRINT_SCREEN = 0x46: Key; +def KEY_SCROLL_LOCK = 0x47: Key; +def KEY_PAUSE = 0x48: Key; +def KEY_INSERT = 0x49: Key; +def KEY_HOME = 0x4a: Key; +def KEY_PAGE_UP = 0x4b: Key; +def KEY_DELETE = 0x4c: Key; +def KEY_END = 0x4d: Key; +def KEY_PAGE_DOWN = 0x4e: Key; +def KEY_RIGHT = 0x4f: Key; +def KEY_LEFT = 0x50: Key; +def KEY_DOWN = 0x51: Key; +def KEY_UP = 0x52: Key; +def KEY_NUM_LOCK = 0x53: Key; +def KEY_PAD_DIVIDE = 0x54: Key; +def KEY_PAD_MULTIPLY = 0x55: Key; +def KEY_PAD_MINUS = 0x56: Key; +def KEY_PAD_PLUS = 0x57: Key; +def KEY_PAD_ENTER = 0x58: Key; +def KEY_PAD_1 = 0x59: Key; +def KEY_PAD_2 = 0x5a: Key; +def KEY_PAD_3 = 0x5b: Key; +def KEY_PAD_4 = 0x5c: Key; +def KEY_PAD_5 = 0x5d: Key; +def KEY_PAD_6 = 0x5e: Key; +def KEY_PAD_7 = 0x5f: Key; +def KEY_PAD_8 = 0x60: Key; +def KEY_PAD_9 = 0x61: Key; +def KEY_PAD_0 = 0x62: Key; +def KEY_PAD_PERIOD = 0x63: Key; +def KEY_NON_US_BACKSLASH = 0x64: Key; +def KEY_APPLICATION = 0x65: Key; +def KEY_PAD_EQUALS = 0x67: Key; +def KEY_F13 = 0x68: Key; +def KEY_F14 = 0x69: Key; +def KEY_F15 = 0x6a: Key; +def KEY_F16 = 0x6b: Key; +def KEY_F17 = 0x6c: Key; +def KEY_F18 = 0x6d: Key; +def KEY_F19 = 0x6e: Key; +def KEY_F20 = 0x6f: Key; +def KEY_F21 = 0x70: Key; +def KEY_F22 = 0x71: Key; +def KEY_F23 = 0x72: Key; +def KEY_F24 = 0x73: Key; +def KEY_EXECUTE = 0x74: Key; +def KEY_HELP = 0x75: Key; +def KEY_MENU = 0x76: Key; +def KEY_SELECT = 0x77: Key; +def KEY_STOP = 0x78: Key; +def KEY_AGAIN = 0x79: Key; +def KEY_UNDO = 0x7a: Key; +def KEY_CUT = 0x7b: Key; +def KEY_COPY = 0x7c: Key; +def KEY_PASTE = 0x7d: Key; +def KEY_FIND = 0x7e: Key; +def KEY_MUTE = 0x7f: Key; +def KEY_VOLUME_UP = 0x80: Key; +def KEY_VOLUME_DOWN = 0x81: Key; +def KEY_PAD_COMMA = 0x85: Key; +def KEY_PAD_EQUAL_SIGN = 0x86: Key; +def KEY_INTERNATIONAL1 = 0x87: Key; +def KEY_INTERNATIONAL2 = 0x88: Key; +def KEY_INTERNATIONAL3 = 0x89: Key; +def KEY_INTERNATIONAL4 = 0x8a: Key; +def KEY_INTERNATIONAL5 = 0x8b: Key; +def KEY_INTERNATIONAL6 = 0x8c: Key; +def KEY_INTERNATIONAL7 = 0x8d: Key; +def KEY_INTERNATIONAL8 = 0x8e: Key; +def KEY_INTERNATIONAL9 = 0x8f: Key; +def KEY_LANG1 = 0x90: Key; +def KEY_LANG2 = 0x91: Key; +def KEY_LANG3 = 0x92: Key; +def KEY_LANG4 = 0x93: Key; +def KEY_LANG5 = 0x94: Key; +def KEY_LANG6 = 0x95: Key; +def KEY_LANG7 = 0x96: Key; +def KEY_LANG8 = 0x97: Key; +def KEY_LANG9 = 0x98: Key; +def KEY_ALT_ERASE = 0x99: Key; +def KEY_SYSREQ = 0x9a: Key; +def KEY_CANCEL = 0x9b: Key; +def KEY_CLEAR = 0x9c: Key; +def KEY_PRIOR = 0x9d: Key; +def KEY_RETURN = 0x9e: Key; +def KEY_SEPARATOR = 0x9f: Key; +def KEY_OUT = 0xa0: Key; +def KEY_OPER = 0xa1: Key; +def KEY_CLEAR_AGAIN = 0xa2: Key; +def KEY_CRSEL = 0xa3: Key; +def KEY_EXSEL = 0xa4: Key; +def KEY_PAD_00 = 0xb0: Key; +def KEY_PAD_000 = 0xb1: Key; +def KEY_THOUSANDS_SEPARATOR = 0xb2: Key; +def KEY_DECIMAL_SEPARATOR = 0xb3: Key; +def KEY_CURRENCY_UNIT = 0xb4: Key; +def KEY_CURRENCY_SUB_UNIT = 0xb5: Key; +def KEY_PAD_LPAREN = 0xb6: Key; +def KEY_PAD_RPAREN = 0xb7: Key; +def KEY_PAD_LBRACE = 0xb8: Key; +def KEY_PAD_RBRACE = 0xb9: Key; +def KEY_PAD_TAB = 0xba: Key; +def KEY_PAD_BACKSPACE = 0xbb: Key; +def KEY_PAD_A = 0xbc: Key; +def KEY_PAD_B = 0xbd: Key; +def KEY_PAD_C = 0xbe: Key; +def KEY_PAD_D = 0xbf: Key; +def KEY_PAD_E = 0xc0: Key; +def KEY_PAD_F = 0xc1: Key; +def KEY_PAD_XOR = 0xc2: Key; +def KEY_PAD_POWER = 0xc3: Key; +def KEY_PAD_PERCENT = 0xc4: Key; +def KEY_PAD_LESS = 0xc5: Key; +def KEY_PAD_GREATER = 0xc6: Key; +def KEY_PAD_AND = 0xc7: Key; +def KEY_PAD_ANDAND = 0xc8: Key; +def KEY_PAD_OR = 0xc9: Key; +def KEY_PAD_OROR = 0xca: Key; +def KEY_PAD_COLON = 0xcb: Key; +def KEY_PAD_HASH = 0xcc: Key; +def KEY_PAD_SPACE = 0xcd: Key; +def KEY_PAD_AT = 0xce: Key; +def KEY_PAD_EXCLAMATION = 0xcf: Key; +def KEY_PAD_MEMORY_STORE = 0xd0: Key; +def KEY_PAD_MEMORY_RECALL = 0xd1: Key; +def KEY_PAD_MEMORY_CLEAR = 0xd2: Key; +def KEY_PAD_MEMORY_ADD = 0xd3: Key; +def KEY_PAD_MEMORY_SUBTRACT = 0xd4: Key; +def KEY_PAD_MEMORY_MULTIPLY = 0xd5: Key; +def KEY_PAD_MEMORY_DIVIDE = 0xd6: Key; +def KEY_PAD_PLUS_MINUS = 0xd7: Key; +def KEY_PAD_CLEAR = 0xd8: Key; +def KEY_PAD_CLEAR_ENTRY = 0xd9: Key; +def KEY_PAD_BINARY = 0xda: Key; +def KEY_PAD_OCTAL = 0xdb: Key; +def KEY_PAD_DECIMAL = 0xdc: Key; +def KEY_PAD_HEXADECIMAL = 0xdd: Key; +def KEY_LCTRL = 0xe0: Key; +def KEY_LSHIFT = 0xe1: Key; +def KEY_LALT = 0xe2: Key; +def KEY_LGUI = 0xe3: Key; +def KEY_RCTRL = 0xe4: Key; +def KEY_RSHIFT = 0xe5: Key; +def KEY_RALT = 0xe6: Key; +def KEY_RGUI = 0xe7: Key; diff --git a/layers.ha b/layers.ha new file mode 100644 index 0000000..ebe9ac2 --- /dev/null +++ b/layers.ha @@ -0,0 +1,73 @@ +type Layer = struct { +	blocks_input: *fn() bool, +	input: *fn(InputEvent) bool, +	is_opaque: *fn() bool, +	render: *fn() void, +}; + +type InputEvent = (CancelEvent | KeyEvent | +	MouseButtonEvent | MouseOverEvent); + +type CancelEvent = void; + +type KeyEvent = struct { +	status: ButtonStatus, +	key: Key, +}; + +type Key = uint; + +type MouseButtonEvent = struct { +	status: ButtonStatus, +	button: MouseButton, +}; + +type MouseButton = enum u8 { +	LEFT, +	MIDDLE, +	RIGHT, +	X1, +	X2, +}; + +type ButtonStatus = enum u8 { +	UP, +	HELD, +	DOWN, +}; + +type MouseOverEvent = struct { +	covered: bool, +}; + +const LAYERS = [ +	&LAYER_GAME, +	&LAYER_HUD, +	&LAYER_DEATH, +	&LAYER_GAME_WAITING, +	&LAYER_CLIENT_WAITING, +]; + +fn layers_input(event: InputEvent, top: size, all: bool) size = { +	for (top > 0) { +		top -= 1; +		if (LAYERS[top].input(event) && !all) { +			break; +		}; +	}; +	return top; +}; + +fn layers_render() void = { +	let bottom = len(LAYERS); +	for (bottom != 0) { +		bottom -= 1; +		if (LAYERS[bottom].is_opaque()) { +			break; +		}; +	}; + +	for (let i = bottom; i < len(LAYERS); i += 1) { +		LAYERS[i].render(); +	}; +}; diff --git a/login.ha b/login.ha new file mode 100644 index 0000000..d59ae7a --- /dev/null +++ b/login.ha @@ -0,0 +1,64 @@ +use mcproto; +use strings; +use trace; +use uuid; + +fn login_start() void = { +	let buf: []u8 = []; +	mcproto::encode_handshake(&buf, &mcproto::Handshake { +		proto_ver = PROTO_VER, +		// TODO: is there a way to get these from the dial api? +		server_addr = CLIENT_ADDR, +		server_port = 25565, +		next_state = mcproto::NextState::LOGIN, +	}); +	network_send(mcproto::SB_HANDSHAKE, buf); + +	let buf: []u8 = []; +	mcproto::encode_string(&buf, CLIENT_USERNAME); +	mcproto::encode_bool(&buf, false); +	network_send(0x00, buf); +}; + +fn login_handle_packet(ctx: *mcproto::Context, packet_id: i32) +		(void | trace::failed) = { +	switch (packet_id) { +	case 0x00 => +		const ctx = mcproto::context(ctx, "0x00 disconnect"); + +		const ctx_ = mcproto::context(&ctx, "reason"); +		const reason = mcproto::decode_string(&ctx_, 262144)?; +		mcproto::expect_end(&ctx)?; + +		return trace::error(&trace::root, "Kicked by server: {}", reason); +	case 0x04 => +		const ctx = mcproto::context(ctx, "0x04 login plugin request"); + +		const ctx_ = mcproto::context(&ctx, "id"); +		const id = mcproto::decode_varint(&ctx_)?; + +		let buf: []u8 = []; +		mcproto::encode_varint(&buf, id); +		network_send(0x02, buf); +	case 0x02 => +		const ctx = mcproto::context(ctx, "0x02 login success"); + +		const ctx_ = mcproto::context(&ctx, "uuid"); +		const uuid = mcproto::decode_uuid(&ctx_)?; +		const ctx_ = mcproto::context(&ctx, "username"); +		const username = mcproto::decode_string(&ctx_, 16)?; +		// TODO: more stuff... + +		free(CLIENT_USERNAME); +		CLIENT_USERNAME = strings::dup(username); + +		trace::info(&trace::root, "logged in as {} ({})", +			username, uuid::encodestr(uuid)); + +		CLIENT_STATE = ClientState::JOIN; +	case => +		return mcproto::error(ctx, +			"Unexpected packet id 0x{:02x} (only uncompressed offline mode is supported)", +			packet_id); +	}; +}; diff --git a/main+android.ha b/main+android.ha new file mode 100644 index 0000000..3ccd4d1 --- /dev/null +++ b/main+android.ha @@ -0,0 +1,38 @@ +use bufio; +use fmt; +use getopt; +use io; +use mcproto; +use memio; +use net; +use net::dial; +use os; +use strings; +use trace; +use unix::signal; +use uuid; + +export fn main() void = { +	signal::ignore(signal::sig::PIPE); +	dial::registersvc("tcp", "minecraft", [], 25565); + +	let tracer = newtracer(); +	trace::setroot(&tracer); +	defer trace::setroot(&trace::silent); + +	// (2024 note): change this as needed, obviously. +	window_run("192.168.8.2", "Player"); +}; + +fn error(fmt: str, args: fmt::field...) void = { +	let s = memio::dynamic(); +	defer io::close(&s)!; +	fmt::fprintf(&s, "hacraft: ")!; +	fmt::fprintfln(&s, fmt, args...)!; +	androlog(7, memio::string(&s)!); +}; + +fn die(fmt: str, args: fmt::field...) never = { +	error(fmt, args...); +	os::exit(1); +}; @@ -0,0 +1,60 @@ +use fmt; +use getopt; +use io; +use net::dial; +use os; +use trace; +use unix::signal; + +const help: [_]getopt::help = [ +	"minecraft client", +	('u', "name", "username for login"), +	"addr", +]; + +export fn main() void = { +	signal::ignore(signal::sig::PIPE); +	dial::registersvc("tcp", "minecraft", [], 25565); + +	let tracer = newtracer(os::stderr); +	trace::setroot(&tracer); +	defer trace::setroot(&trace::silent); + +	const cmd = getopt::parse(os::args, help...); +	defer getopt::finish(&cmd); + +	let username = "Player"; + +	for (let i = 0z; i < len(cmd.opts); i += 1) { +		const (flag, param) = cmd.opts[i]; + +		switch (flag) { +		case 'u' => +			username = param; +		case => abort(); +		}; +	}; + +	if (len(cmd.args) != 1) { +		die_usage("expected exactly 1 positional argument"); +	}; +	const addr = cmd.args[0]; + +	window_run(addr, username); +}; + +fn error(fmt: str, args: fmt::field...) void = { +	fmt::errorf("{}: ", os::args[0]): void; +	fmt::errorfln(fmt, args...): void; +}; + +fn die(fmt: str, args: fmt::field...) never = { +	error(fmt, args...); +	os::exit(1); +}; + +fn die_usage(fmt: str, args: fmt::field...) never = { +	error(fmt, args...); +	getopt::printusage(os::stderr, os::args[0], help)!; +	os::exit(1); +}; diff --git a/mcproto/+test.ha b/mcproto/+test.ha new file mode 100644 index 0000000..5ce070c --- /dev/null +++ b/mcproto/+test.ha @@ -0,0 +1,47 @@ +use bytes; +use trace; + +fn varint_roundtrip(value: i32, bytes: []u8) void = { +	let buf: []u8 = []; +	encode_varint(&buf, value); +	assert(bytes::equal(buf, bytes)); +	let dec = Decoder { +		input = buf, +		pos = 0, +		tracer = &trace::silent, +	}; +	assert(decode_varint(&root(&dec))! == value); +}; + +fn varint_invalid(bytes: []u8) void = { +	let dec = Decoder { +		input = bytes, +		pos = 0, +		tracer = &trace::silent, +	}; +	assert(decode_varint(&root(&dec)) is trace::failed); +}; + +@test fn varints() void = { +        // sample varints from https://wiki.vg/protocol?oldid=17184#varint_and_varlong +        varint_roundtrip(0, [0x00]); +        varint_roundtrip(1, [0x01]); +        varint_roundtrip(2, [0x02]); +        varint_roundtrip(127, [0x7f]); +        varint_roundtrip(128, [0x80, 0x01]); +        varint_roundtrip(255, [0xff, 0x01]); +        varint_roundtrip(25565, [0xdd, 0xc7, 0x01]); +        varint_roundtrip(2097151, [0xff, 0xff, 0x7f]); +        varint_roundtrip(2147483647, [0xff, 0xff, 0xff, 0xff, 0x07]); +        varint_roundtrip(-1, [0xff, 0xff, 0xff, 0xff, 0x0f]); +        varint_roundtrip(-2147483648, [0x80, 0x80, 0x80, 0x80, 0x08]); +}; + +@test fn varints_invalid() void = { +	varint_invalid([]); +	varint_invalid([0x8f]); +	varint_invalid([0x8f, 0x8f]); +	varint_invalid([0x80, 0x80, 0x80, 0x80, 0x80, 0x00]); +	varint_invalid([0x80, 0x80, 0x80, 0x80, 0x10]); +	varint_invalid([0xff, 0xff, 0xff, 0xff, 0xff]); +}; diff --git a/mcproto/decode.ha b/mcproto/decode.ha new file mode 100644 index 0000000..bd020c4 --- /dev/null +++ b/mcproto/decode.ha @@ -0,0 +1,193 @@ +use encoding::utf8; +use endian; +use fmt; +use io; +use strings; +use trace; +use uuid; + +export type Decoder = struct { +	input: []u8, +	pos: size, +	tracer: *trace::tracer, +}; + +export type Context = struct { +	dec: *Decoder, +	pos: size, +	fmt: str, +	fields: []fmt::field, +	up: nullable *Context, +}; + +export fn log( +	ctx: *Context, +	lvl: trace::level, +	fmt: str, +	fields: fmt::field... +) void = { +	log_(ctx, null, lvl, fmt, fields...); +}; + +fn log_( +	ctx: *Context, +	trace_ctx: nullable *trace::context, +	lvl: trace::level, +	fmt: str, +	fields: fmt::field... +) void = { +	let s = ""; +	defer free(s); +	if (len(ctx.fmt) != 0) { +		s = fmt::asprintf(ctx.fmt, ctx.fields...); +		// TODO: is this legal? works at the moment due to qbe +		// semantics, but who knows... +		trace_ctx = &trace::context { +			fmt = "{} (offset {})", +			fields = [s, ctx.pos], +			next = trace_ctx, +		}; +	}; +	match (ctx.up) { +	case let ctx_: *Context => +		log_(ctx_, trace_ctx, lvl, fmt, fields...); +	case null => +		trace::log(ctx.dec.tracer, trace_ctx, lvl, fmt, fields...); +	}; +}; + +export fn error(ctx: *Context, fmt: str, fields: fmt::field...) trace::failed = { +	log(ctx, trace::level::ERROR, fmt, fields...); +	return trace::failed; +}; + +export fn root(dec: *Decoder) Context = { +	return Context { +		dec = dec, +		pos = dec.pos, +		... +	}; +}; + +export fn context(ctx: *Context, fmt: str, fields: fmt::field...) Context = { +	return Context { +		dec = ctx.dec, +		pos = ctx.dec.pos, +		fmt = fmt, +		fields = fields, +		up = ctx, +	}; +}; + +export fn decode_nbytes(ctx: *Context, length: size) +		([]u8 | trace::failed) = { +	const dec = ctx.dec; +	if (len(dec.input) - dec.pos < length) { +		return error(ctx, "Expected {} bytes, found only {}", +			length, len(dec.input) - dec.pos); +	}; +	const res = dec.input[dec.pos..dec.pos + length]; +	dec.pos += length; +	return res; +}; + +export fn decode_byte(ctx: *Context) (u8 | trace::failed) = { +	const b = decode_nbytes(ctx, 1)?; +	return b[0]; +}; +export fn decode_short(ctx: *Context) (u16 | trace::failed) = { +	const b = decode_nbytes(ctx, 2)?; +	return endian::begetu16(b); +}; +export fn decode_int(ctx: *Context) (u32 | trace::failed) = { +	const b = decode_nbytes(ctx, 4)?; +	return endian::begetu32(b); +}; +export fn decode_long(ctx: *Context) (u64 | trace::failed) = { +	const b = decode_nbytes(ctx, 8)?; +	return endian::begetu64(b); +}; + +export fn decode_bool(ctx: *Context) (bool | trace::failed) = { +	const b = decode_byte(ctx)?; +	if (b >= 2) { +		return error(ctx, "Invalid boolean"); +	}; +	return b != 0; +}; + +export fn decode_float(ctx: *Context) (f32 | trace::failed) = { +	const v = decode_int(ctx)?; +	return *(&v: *f32); +}; +export fn decode_double(ctx: *Context) (f64 | trace::failed) = { +	const v = decode_long(ctx)?; +	return *(&v: *f64); +}; + +export fn try_decode_varint(ctx: *Context) (i32 | !(trace::failed | TooShort)) = { +	let res = 0u32; +	const dec = ctx.dec; + +	for (let i = 0u32; dec.pos + i < len(dec.input); i += 1) { +		const b = dec.input[dec.pos + i]; + +		if (i == 4 && b & 0xf0 != 0) { +			return error(ctx, "VarInt too long"); +		}; + +		res |= (b & 0x7f): u32 << (7 * i); + +		if (b & 0x80 == 0) { +			dec.pos += i + 1; +			return res: i32; +		}; +	}; + +	return TooShort; +}; + +export fn decode_varint(ctx: *Context) (i32 | trace::failed) = { +	match (try_decode_varint(ctx)) { +	case let res: i32 => +		return res; +	case => +		return error(ctx, "VarInt too short"); +	}; +}; + +export fn decode_string(ctx: *Context, maxlen: size) (str | trace::failed) = { +	const length = decode_varint(&context(ctx, "string length"))?; +	const length = length: size; + +	if (length >= maxlen * 4) { +		return error(ctx, +			"String length {} exceeds limit of {} bytes", +			length, maxlen * 4); +	}; + +	const ctx_ = context(ctx, "string data ({} bytes)", length); +	const bytes = decode_nbytes(&ctx_, length)?; +	match (strings::fromutf8(bytes)) { +	case let string: str => +		// don't bother checking length in code points. doesn't seem +		// very useful. +		return string; +	case utf8::invalid => +		return error(&ctx_, "Invalid UTF-8"); +	}; +}; + +export fn decode_uuid(ctx: *Context) (uuid::uuid | trace::failed) = { +	let uuid: [16]u8 = [0...]; +	uuid[..] = decode_nbytes(ctx, 16)?; +	return uuid; +}; + +export fn expect_end(ctx: *Context) (void | trace::failed) = { +	if (ctx.dec.pos != len(ctx.dec.input)) { +		return error(ctx, +			"Expected end of input, but found {} extra bytes starting at {}", +			len(ctx.dec.input) - ctx.dec.pos, ctx.dec.pos); +	}; +}; diff --git a/mcproto/encode.ha b/mcproto/encode.ha new file mode 100644 index 0000000..de30871 --- /dev/null +++ b/mcproto/encode.ha @@ -0,0 +1,51 @@ +use endian; +use strings; +use uuid; + +export fn encode_short(out: *[]u8, v: u16) void = { +	const buf: [2]u8 = [0...]; +	endian::beputu16(buf, v); +	append(out, buf...); +}; +export fn encode_int(out: *[]u8, v: u32) void = { +	const buf: [4]u8 = [0...]; +	endian::beputu32(buf, v); +	append(out, buf...); +}; +export fn encode_long(out: *[]u8, v: u64) void = { +	const buf: [8]u8 = [0...]; +	endian::beputu64(buf, v); +	append(out, buf...); +}; + +export fn encode_bool(out: *[]u8, v: bool) void = { +	append(out, if (v) 1 else 0); +}; + +export fn encode_float(out: *[]u8, v: f32) void = { +	encode_int(out, *(&v: *u32)); +}; +export fn encode_double(out: *[]u8, v: f64) void = { +	encode_long(out, *(&v: *u64)); +}; + +export fn encode_varint(out: *[]u8, v: i32) void = { +	let v = v: u32; + +	for (true) { +		const continues = v & 0x7f != v; +		const high_bit: u8 = if (continues) 0x80 else 0x00; +		append(out, (v & 0x7f): u8 | high_bit); +		v >>= 7; +		if (!continues) return; +	}; +}; + +export fn encode_string(out: *[]u8, string: str) void = { +	encode_varint(out, len(string): i32); +	append(out, strings::toutf8(string)...); +}; + +export fn encode_uuid(out: *[]u8, uuid: uuid::uuid) void = { +	append(out, uuid...); +}; diff --git a/mcproto/error.ha b/mcproto/error.ha new file mode 100644 index 0000000..092210d --- /dev/null +++ b/mcproto/error.ha @@ -0,0 +1 @@ +export type TooShort = !void; diff --git a/mcproto/frame.ha b/mcproto/frame.ha new file mode 100644 index 0000000..d5ee4c1 --- /dev/null +++ b/mcproto/frame.ha @@ -0,0 +1,22 @@ +use bufio; +use io; +use trace; + +export fn write_frame(out: io::handle, in: []u8) (void | io::error) = { +	assert(len(in) <= 0x1fffff, "write_frame: too long"); +	let length_buf: [3]u8 = [0...]; +	let length_buf = length_buf[..0]; +	encode_varint(&length_buf, len(in): i32); +	io::writeall(out, length_buf)?; +	io::writeall(out, in)?; +}; + +export fn write_packet(out: io::handle, packet_id: i32, payload: []u8) +		(void | io::error) = { +	static let packet_buf: [0x1fffff]u8 = [0...]; + +	let packet = packet_buf[..0]; +	encode_packet(&packet, packet_id, payload); + +	write_frame(out, packet)?; +}; diff --git a/mcproto/handshake.ha b/mcproto/handshake.ha new file mode 100644 index 0000000..8df5254 --- /dev/null +++ b/mcproto/handshake.ha @@ -0,0 +1,46 @@ +use trace; + +export def SB_HANDSHAKE: i32 = 0x00; + +export type Handshake = struct { +	proto_ver: i32, +	server_addr: str, +	server_port: u16, +	next_state: NextState, +}; + +export type NextState = enum i32 { +	STATUS = 1, +	LOGIN = 2, +}; + +export fn encode_handshake(out: *[]u8, pkt: *Handshake) void = { +	encode_varint(out, pkt.proto_ver); +	encode_string(out, pkt.server_addr); +	encode_short(out, pkt.server_port); +	encode_varint(out, pkt.next_state); +}; + +export fn decode_handshake(ctx: *Context) (Handshake | trace::failed) = { +	const ctx_ = context(ctx, "protocol version"); +	const proto_ver = decode_varint(&ctx_)?; +	const ctx_ = context(ctx, "server address"); +	const server_addr = decode_string(&ctx_, 255)?; +	const ctx_ = context(ctx, "server port"); +	const server_port = decode_short(&ctx_)?; +	const ctx_ = context(ctx, "next state"); +	const next_state = decode_varint(&ctx_)?: NextState; +	if (next_state != NextState::STATUS +			&& next_state != NextState::LOGIN) { +		return error(&ctx_, "Invalid next state 0x{:02x}", +			next_state: i32); +	}; +	expect_end(ctx)?; + +	return Handshake { +		proto_ver = proto_ver, +		server_addr = server_addr, +		server_port = server_port, +		next_state = next_state, +	}; +}; diff --git a/mcproto/packet.ha b/mcproto/packet.ha new file mode 100644 index 0000000..669df56 --- /dev/null +++ b/mcproto/packet.ha @@ -0,0 +1,13 @@ +use math; +use trace; + +export fn encode_packet(out: *[]u8, packet_id: i32, in: []u8) void = { +	let id_size = math::bit_size_u32(packet_id: u32); +	if (id_size == 0) id_size = 1; +	const id_size = id_size / 7 + id_size % 7; +	assert(len(in) + id_size <= 0x1fffff, +		"TODO: sent packet too long. this should be handled better."); + +	encode_varint(out, packet_id); +	append(out, in...); +}; diff --git a/mcproto/status/ids.ha b/mcproto/status/ids.ha new file mode 100644 index 0000000..89d6bb4 --- /dev/null +++ b/mcproto/status/ids.ha @@ -0,0 +1,5 @@ +export def SB_REQUEST: i32 = 0x00; +export def SB_PING: i32 = 0x01; + +export def CB_RESPONSE: i32 = 0x00; +export def CB_PONG: i32 = 0x01; diff --git a/mcproto/status/ping.ha b/mcproto/status/ping.ha new file mode 100644 index 0000000..00ff7cf --- /dev/null +++ b/mcproto/status/ping.ha @@ -0,0 +1,9 @@ +use mcproto; +use trace; + +export fn decode_ping(ctx: *mcproto::Context) (i64 | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "ping id"); +	const ping_id = mcproto::decode_long(&ctx_)?: i64; +	mcproto::expect_end(ctx)?; +	return ping_id; +}; diff --git a/mcproto/status/response.ha b/mcproto/status/response.ha new file mode 100644 index 0000000..e93df47 --- /dev/null +++ b/mcproto/status/response.ha @@ -0,0 +1,111 @@ +use dejson; +use encoding::json; +use mcproto; +use strings; +use trace; +use uuid; + +export type Response = struct { +	description: str, +	version_name: str, +	version_protocol: i32, +	players_online: u32, +	players_max: u32, +	players_sample: [](str, uuid::uuid), +	previews_chat: bool, +	forces_reportable_chat: bool, +}; + +export fn decode_response(ctx: *mcproto::Context) (Response | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "json"); +	const json = mcproto::decode_string(&ctx_, 32767)?; +	mcproto::expect_end(ctx)?; + +	const json = match (json::loadstr(json)) { +	case let json: json::value => +		yield json; +	case let err: json::error => +		return mcproto::error(&ctx_, "Invalid JSON: {}", json::strerror(err)); +	}; +	defer json::finish(json); + +	const deser = dejson::newdeser(&json); +	match (deser_response(&deser)) { +	case let res: Response => +		return res; +	case let err: dejson::error => +		defer free(err); +		return mcproto::error(&ctx_, "Invalid response contents: {}", err); +	}; +}; + +export fn deser_response(de: *dejson::deser) (Response | dejson::error) = { +	let success = false; + +	let res = Response { ... }; +	defer if (!success) response_finish(res); + +	res.description = match (dejson::optfield(de, "description")?) { +	case let de_description: dejson::deser => +		yield json::dumpstr(*de_description.val); +	case void => +		yield ""; +	}; + +	const de_version = dejson::field(de, "version")?; +	res.version_name = strings::dup(dejson::string( +		&dejson::field(&de_version, "name")?)?); +	res.version_protocol = dejson::number_i32( +		&dejson::field(&de_version, "protocol")?)?; + +	const de_players = dejson::field(de, "players")?; +	res.players_online = dejson::number_u32( +		&dejson::field(&de_players, "online")?)?; +	res.players_max = dejson::number_u32( +		&dejson::field(&de_players, "max")?)?; +	match (dejson::optfield(&de_players, "sample")?) { +	case let de_sample: dejson::deser => +		const nsample = dejson::length(&de_sample)?; +		for (let i = 0z; i < nsample; i += 1) { +			const de_player = dejson::index(&de_sample, i)?; +			const name = dejson::string( +				&dejson::field(&de_player, "name")?)?; +			const de_id = dejson::field(&de_player, "id")?; +			const id = dejson::string(&de_id)?; +			const id = match (uuid::decodestr(id)) { +			case let id: uuid::uuid => +				yield id; +			case uuid::invalid => +				return dejson::fail(&de_id, "Invalid UUID"); +			}; +			append(res.players_sample, (strings::dup(name), id)); +		}; +	case void => void; +	}; + +	res.previews_chat = match (dejson::optfield(de, "previewsChat")) { +	case let de_previews_chat: dejson::deser => +		yield dejson::boolean(&de_previews_chat)?; +	case void => +		yield false; +	}; +	res.forces_reportable_chat = match ( +		dejson::optfield(de, "enforcesSecureChat")) { +	case let de_forces_reportable_chat: dejson::deser => +		yield dejson::boolean(&de_forces_reportable_chat)?; +	case void => +		yield false; +	}; + +	success = true; +	return res; +}; + +export fn response_finish(res: Response) void = { +	free(res.description); +	free(res.version_name); +	for (let i = 0z; i < len(res.players_sample); i += 1) { +		free(res.players_sample[i].0); +	}; +	free(res.players_sample); +}; diff --git a/models.ha b/models.ha new file mode 100644 index 0000000..71a8e05 --- /dev/null +++ b/models.ha @@ -0,0 +1,653 @@ +use dejson; +use encoding::json; +use glm; +use math; +use strings; +use trace; + +type Model = struct { +	Object, +	decl: nullable *ModelDecl, +	parent: nullable *Model, +	geom: nullable *ModelGeom, +	owns_geom: bool, +	textures: []*Sprite, +}; + +type ModelGeom = struct { +	textures: []str, +	faces: []Face, +}; + +type Face = struct { +	dir: Dir, // used for uvlock; probably a temporary hack. +	cull_face: CullFace, +	texture: u8, +	normal: [3]i8, +	texcoord: [4]u8, +	rotation: u8, +	vertices: [4][3]u16, +}; + +type CullFace = enum u8 { +	WEST, +	EAST, +	DOWN, +	UP, +	NORTH, +	SOUTH, +	NONE, +}; + +let MODELS = OBJREG_EMPTY; + +fn models_find(ident: str) nullable *Model = +	objreg_find(&MODELS, ident): nullable *Model; + +type ModelsIter = struct { +	inner: ObjectRegistryIterator, +}; + +fn models_iter() ModelsIter = +	ModelsIter { inner = objreg_iter(&MODELS) }; + +fn models_next(it: *ModelsIter) nullable *Model = +	objreg_next(&it.inner): nullable *Model; + +fn load_models(assets: *Pack) void = { +	const tr = &trace::root; +	trace::info(tr, "loading models..."); + +	objreg_register(&MODELS, alloc(Model { +		name = strings::dup(BUILTIN_MISSING), +		... +	})); +	objreg_register(&MODELS, alloc(Model { +		name = strings::dup("minecraft:builtin/entity"), +		... +	})); +	objreg_register(&MODELS, alloc(Model { +		name = strings::dup("minecraft:builtin/generated"), +		... +	})); + +	const results = resource_search(assets, "models", ".json"); +	for (let i = 0z; i < len(results); i+= 1) { +		const (ident, ext) = results[i]; + +		const tr = trace::ctx(tr, "load model {}", ident); + +		const model = alloc(Model { +			name = strings::dup(ident), +			... +		}); +		objreg_register(&MODELS, model); + +		const json = match (resource_load_json( +			assets, "models", ident, ".json", &tr)) { +		case let json: json::value => +			yield json; +		case trace::failed => +			continue; +		}; +		defer json::finish(json); + +		const decl = { +			const deser = dejson::newdeser(&json); +			yield match (deser_model_decl(&deser)) { +			case let x: ModelDecl => +				yield x; +			case let err: dejson::error => +				defer free(err); +				trace::error(&tr, "deser: {}", ident, err): void; +				continue; +			}; +		}; + +		model.decl = alloc(decl); +	}; + +	let it = models_iter(); +	for (true) match (models_next(&it)) { +	case let model: *Model => +		if (model.decl == null) +			model.decl = alloc(missingno_model_decl()); +	case null => break; +	}; + +	let it = models_iter(); +	for (true) match (models_next(&it)) { +	case let model: *Model => +		const tr = trace::ctx(tr, "load model {}", model.name); + +		const decl = model.decl as *ModelDecl; + +		match (decl.parent) { +		case let parent: str => +			model.parent = models_find(parent); +			if (model.parent == null) { +				trace::error(&tr, "Unknown parent {}", parent): void; +				model.parent = +					models_find(BUILTIN_MISSING) as *Model; +			}; +		case void => void; +		}; + +		const elements = match (decl.elements) { +		case let elements: []ModelDeclElement => +			yield elements; +		case void => void; +			if (model.parent == null) +				yield []: []ModelDeclElement; +			yield void; // TODO: harec bug? +		}; + +		match (elements) { +		case let elements: []ModelDeclElement => +			model.geom = alloc(build_model_geom(elements)); +			model.owns_geom = true; +		case void => void; +		}; +	case null => break; +	}; + +	let it = models_iter(); +	for (true) match (models_next(&it)) { +	case let model: *Model => +		const tr = trace::ctx(tr, "load model {}", model.name); + +		if (model.geom == null) { +			let i = model.parent; +			for (true) match (i) { +			case let model_: *Model => +				i = model_.parent; +				match (model_.geom) { +				case let geom: *ModelGeom => +					model.geom = geom; +					break; +				case null => void; +				}; +			case null => abort(); +			}; +		}; +		const geom = model.geom as *ModelGeom; + +		model.textures = alloc([], len(geom.textures)); + +		for (let i = 0z; i < len(geom.textures); i += 1) { +			const spr = model_resolve_texture_name( +				model, geom.textures[i], &tr); +			const spr = match (spr) { +			case let spr: *Sprite => +				yield spr; +			case trace::failed => +				yield atlas_findsprite(&ATLAS_BLOCKS, +					MISSINGNO) as *Sprite; +			}; +			static append(model.textures, spr); +		}; +	case null => break; +	}; +}; + +fn build_model_geom(elements: []ModelDeclElement) ModelGeom = { +	// west, east, down, up, north, south +	// (naxis, uaxis, vaxis, vertices) +	// vertices = [top_left, bottom_left, bottom_right, top_right] +	// vertices[_] = 0bZYX where 0: from, 1: to +	static const face_info: [6](u8, u8, u8, [4]u8) = [ +		(0, 2, 1, [0b010, 0b000, 0b100, 0b110]), +		(0, 2, 1, [0b111, 0b101, 0b001, 0b011]), +		(1, 0, 2, [0b100, 0b000, 0b001, 0b101]), +		(1, 0, 2, [0b010, 0b110, 0b111, 0b011]), +		(2, 0, 1, [0b011, 0b001, 0b000, 0b010]), +		(2, 0, 1, [0b110, 0b100, 0b101, 0b111]), +	]; + +	let textures: []str = []; +	let faces: []Face = []; + +	for (let i = 0z; i < len(elements); i += 1) { +		const element = &elements[i]; + +		let trans = glm::m4_new_ident(); + +		let (rot_axis, rescale_axes): ([3]f32, [3]f32) = +			switch (element.rot_axis) { +		case Axis::X => +			yield ([1.0, 0.0, 0.0], [0.0, 1.0, 1.0]); +		case Axis::Y => +			yield ([0.0, 1.0, 0.0], [1.0, 0.0, 1.0]); +		case Axis::Z => +			yield ([0.0, 0.0, 1.0], [1.0, 1.0, 0.0]); +		}; +		glm::translate(&trans, &({ +			let v = element.rot_origin; +			glm::v3_negate(&v); +			yield v; +		})); +		const angle = glm::rad(element.rot_angle); +		glm::rotate(&trans, angle, &rot_axis); +		if (element.rot_rescale) { +			const sin = math::sinf64(angle): f32; +			const cos = math::cosf64(angle): f32; +			const rescale = 1.0 +				/ (if (cos > sin) cos else sin) +				- 1.0; +			glm::v3_scale(&rescale_axes, rescale); +			rescale_axes = glm::v3_add(&rescale_axes, +				&glm::v3_new(1.0, 1.0, 1.0)); +			glm::scale(&trans, &rescale_axes); +		}; +		glm::translate(&trans, &element.rot_origin); + +		const from = element.from; +		const to = element.to; +		const from_to = [from, to]; + +		let vertices: [8][3]u16 = [[0...]...]; +		for (let j = 0z; j < 8; j += 1) { +			let v: [3]f32 = [from_to[j & 1][0], +				from_to[j >> 1 & 1][1], +				from_to[j >> 2 & 1][2]]; +			v = glm::affine_mul_v3(&trans, &v); +			for (let k = 0z; k < 3; k += 1) +				vertices[j][k] = ((v[k] + 16.0) * 128.0): u16; +		}; + +		for (let j = 0z; j < 6; j += 1) { +			const finfo = &face_info[j]; +			const naxis = finfo.0; +			const uaxis = finfo.1; +			const vaxis = finfo.2; +			const faceverts = &finfo.3; + +			const face = match (element.faces[j]) { +			case let x: ModelDeclFace => +				yield x; +			case void => +				continue; +			}; + +			let texnum = 0u8; +			for (texnum < len(textures); texnum += 1) { +				if (textures[texnum] == face.texture) { +					break; +				}; +			}; +			if (texnum == len(textures)) { +				append(textures, face.texture); +			}; + +			let normal: [3]f32 = [0.0...]; +			normal[naxis] = if (faceverts[0] & 1 << naxis != 0) +				127.0 else -127.0; +			normal = glm::affine_mul_v3(&trans, &normal); +			const intnormal = +				[normal[0]: i8, normal[1]: i8, normal[2]: i8]; + +			const uv: [4]f32 = match (face.uv) { +			case let uv: [4]f32 => +				yield uv; +			case void => +				const u = if (faceverts[0] & 1 << uaxis == 0) +					[from[uaxis], to[uaxis]] else +					[16.0 - to[uaxis], 16.0 - from[uaxis]]; +				const v = if (faceverts[0] & 1 << vaxis == 0) +					[from[vaxis], to[vaxis]] else +					[16.0 - to[vaxis], 16.0 - from[vaxis]]; +				yield [u[0], v[0], u[1], v[1]]; +			}; + +			let intuv: [4]u8 = [0...]; +			for (let k = 0z; k < 4; k += 1) { +				const a = uv[k]; +				if (a < 0.0) a = 0.0; +				if (a > 16.0) a = 16.0; +				intuv[k] = (a * 8.0): u8; +			}; + +			append(faces, Face { +				dir = j: Dir, +				cull_face = face.cull_face, +				texture = texnum, +				normal = intnormal, +				texcoord = intuv, +				rotation = face.rotation, +				vertices = [ +					vertices[faceverts[0]], +					vertices[faceverts[1]], +					vertices[faceverts[2]], +					vertices[faceverts[3]], +				], +			}); +		}; +	}; + +	return ModelGeom { +		textures = textures, +		faces = faces, +	}; +}; + +fn model_resolve_texture_name(model: *Model, name: str, tr: *trace::tracer) +		(*Sprite | trace::failed) = { +	let names: []str = []; +	defer free(names); +	let model_ = model; +	for :resolve (true) { +		if (!strings::hasprefix(name, '#')) break; +		const var = strings::trimprefix(name, "#"); + +		const decl = model_.decl as *ModelDecl; + +		for (let j = 0z; j < len(decl.textures); j += 1) { +			if (decl.textures[j].0 != var) { +				continue; +			}; + +			name = decl.textures[j].1; + +			for (let k = 0z; k < len(names); k += 1) { +				if (names[k] == name) { +					break :resolve; +				}; +			}; +			append(names, name); + +			model_ = model; +			continue :resolve; +		}; + +		match (model_.parent) { +		case let parent: *Model => +			model_ = parent; +		case null => break; +		}; +	}; + +	if (strings::hasprefix(name, "#")) { +		return trace::error(tr, "Failed to resolve texture name {}", name); +	}; + +	const texident = ident_qual(name); +	defer free(texident); + +	match (atlas_findsprite(&ATLAS_BLOCKS, texident)) { +	case let spr: *Sprite => +		return spr; +	case null => +		return trace::error(tr, "Unknown texture {}", texident); +	}; +}; + +type ModelDecl = struct { +	parent: (str | void), +	textures: [](str, str), +	elements: ([]ModelDeclElement | void), +}; + +type ModelDeclElement = struct { +	from: [3]f32, +	to: [3]f32, +	rot_origin: [3]f32, +	rot_axis: Axis, +	rot_angle: f32, +	rot_rescale: bool, +	faces: [6](ModelDeclFace | void), // west, east, down, up, north, south +}; + +type Axis = enum u8 { +	X, +	Y, +	Z, +}; + +type ModelDeclFace = struct { +	uv: ([4]f32 | void), +	rotation: u8, // [0,4) 90° steps +	texture: str, +	cull_face: CullFace, +}; + +fn model_decl_finish(decl: ModelDecl) void = { +	match (decl.parent) { +	case let parent: str => +		free(parent); +	case void => void; +	}; +	for (let i = 0z; i < len(decl.textures); i += 1) { +		free(decl.textures[i].0); +		free(decl.textures[i].1); +	}; + +	match (decl.elements) { +	case let elements: []ModelDeclElement => +		for (let i = 0z; i < len(elements); i += 1) { +			model_decl_element_finish(elements[i]); +		}; +	case void => void; +	}; +}; + +fn model_decl_element_finish(element: ModelDeclElement) void = { +	for (let i = 0z; i < 6; i += 1) { +		match (element.faces[i]) { +		case let face: ModelDeclFace => +			free(face.texture); +		case void => void; +		}; +	}; +}; + +fn missingno_model_decl() ModelDecl = { +	let faces: [6](ModelDeclFace | void) = [void...]; +	for (let i = 0u8; i < 6; i += 1) { +		faces[i] = ModelDeclFace { +			uv = void, +			rotation = 0, +			texture = strings::dup(MISSINGNO), +			cull_face = i: CullFace, +		}; +	}; +	return ModelDecl { +		parent = void, +		textures = [], +		elements = alloc([ModelDeclElement { +			from = [0.0...], +			to = [16.0...], +			rot_origin = [0.0...], +			rot_axis = Axis::X, +			rot_angle = 0.0, +			rot_rescale = false, +			faces = faces, +		}]), +	}; +}; + +fn deser_model_decl(de: *dejson::deser) (ModelDecl | dejson::error) = { +	let success = false; +	wassert_fields(de, "parent", "textures", "elements")?; + +	let res = ModelDecl { +		parent = void, +		elements = void, +		... +	}; +	defer if (!success) model_decl_finish(res); +	match (dejson::optfield(de, "parent")?) { +	case let de_parent: dejson::deser => +		res.parent = ident_qual(dejson::string(&de_parent)?); +	case void => void; +	}; + +	match (dejson::optfield(de, "textures")?) { +	case let de_textures: dejson::deser => +		res.textures = alloc([], dejson::count(&de_textures)?); +		let it = dejson::iter(&de_textures)?; +		for (true) match (dejson::next(&it)) { +		case let entry: (str, dejson::deser) => +			const var = strings::dup(entry.0); +			const tex = strings::dup(dejson::string(&entry.1)?); +			append(res.textures, (var, tex)); +		case void => break; +		}; +	case void => void; +	}; + +	match (dejson::optfield(de, "elements")?) { +	case let de_elements: dejson::deser => +		const nelements = dejson::length(&de_elements)?; +		res.elements = alloc([], nelements); +		for (let i = 0z; i < nelements; i += 1) { +			// XXX: waiting for tagged union overhaul... +			let elements = res.elements: []ModelDeclElement; +			append(elements, deser_model_decl_element( +				&dejson::index(&de_elements, i)?)?); +			res.elements = elements; +		}; +	case void => void; +	}; + +	success = true; +	return res; +}; + +fn deser_model_decl_element(de: *dejson::deser) +		(ModelDeclElement | dejson::error) = { +	wassert_fields(de, "from", "to", "faces", "rotation")?; + +	static const facenames = ["west", "east", "down", "up", +		"north", "south"]; +	const de_faces = dejson::field(de, "faces")?; +	wassert_fields(&de_faces, facenames...)?; +	const faces: [6](ModelDeclFace | void) = [void...]; +	for (let j = 0z; j < 6; j += 1) { +		match (dejson::optfield(&de_faces, facenames[j])?) { +		case let de_face: dejson::deser => +			faces[j] = deser_model_decl_face(&de_face)?; +		case void => void; +		}; +	}; + +	let res = ModelDeclElement { +		from = deser_model_decl_pos( +			&dejson::field(de, "from")?)?, +		to = deser_model_decl_pos( +			&dejson::field(de, "to")?)?, +		rot_origin = [0.0...], +		rot_axis = Axis::X, +		rot_angle = 0.0, +		rot_rescale = false, +		faces = faces, +	}; + +	match (dejson::optfield(de, "rotation")?) { +	case let de_rotation: dejson::deser => +		wassert_fields(&de_rotation, +			"origin", "axis", "angle", "rescale")?; +		res.rot_origin = deser_model_decl_pos( +			&dejson::field(&de_rotation, "origin")?)?; +		const de_rot_axis = dejson::field(&de_rotation, "axis")?; +		const rot_axis = dejson::string(&de_rot_axis)?; +		res.rot_axis = switch (rot_axis) { +		case "x" => +			yield Axis::X; +		case "y" => +			yield Axis::Y; +		case "z" => +			yield Axis::Z; +		case => +			const s = dejson::strfield(rot_axis); +			defer free(s); +			return dejson::fail(&de_rot_axis, "Invalid axis {}", s); +		}; +		res.rot_angle = dejson::number( +			&dejson::field(&de_rotation, "angle")?)?: f32; +		match (dejson::optfield(&de_rotation, "rescale")) { +		case let de_rescale: dejson::deser => +			res.rot_rescale = dejson::boolean(&de_rescale)?; +		case void => void; +		}; +	case void => void; +	}; + +	return res; +}; + +fn deser_model_decl_pos(de: *dejson::deser) ([3]f32 | dejson::error) = { +	dejson::assert_length(de, 3)?; +	// TODO: check valid range? +	return [ +		dejson::number(&dejson::index(de, 0)?)?: f32, +		dejson::number(&dejson::index(de, 1)?)?: f32, +		dejson::number(&dejson::index(de, 2)?)?: f32, +	]; +}; + +fn deser_model_decl_face(de: *dejson::deser) (ModelDeclFace | dejson::error) = { +	wassert_fields(de, "uv", "rotation", "cullface", "texture")?; + +	const uv = match (dejson::optfield(de, "uv")?) { +	case let de_uv: dejson::deser => +		dejson::assert_length(&de_uv, 4)?; +		let uv: [4]f32 = [0.0...]; +		for (let i = 0z; i < 4; i += 1) +			uv[i] = dejson::number_frange( +				&dejson::index(&de_uv, i)?, +				0.0, 16.0)?: f32; +		yield uv; +	case void => void; +	}; + +	const rotation = match (dejson::optfield(de, "rotation")?) { +	case let de_rotation: dejson::deser => +		yield deser_90deg_angle(&de_rotation)?; +	case void => +		yield 0u8; +	}; + +	const cull_face = match (dejson::optfield(de, "cullface")?) { +	case let de_cull_face: dejson::deser => +		const s = dejson::string(&de_cull_face)?; +		yield switch (s) { +		case "west" => +			yield CullFace::WEST; +		case "east" => +			yield CullFace::EAST; +		case "down" => +			yield CullFace::DOWN; +		case "up" => +			yield CullFace::UP; +		case "north" => +			yield CullFace::NORTH; +		case "south" => +			yield CullFace::SOUTH; +		case => +			const s = dejson::strfield(s); +			defer free(s); +			trace::warn(&trace::root, "Invalid face {}", s); +			yield CullFace::NONE; +		}; +	case void => +		yield CullFace::NONE; +	}; + +	const texture = strings::dup(dejson::string( +		&dejson::field(de, "texture")?)?); + +	return ModelDeclFace { +		uv = uv, +		rotation = rotation, +		texture = texture, +		cull_face = cull_face, +	}; +}; + +fn deser_90deg_angle(de: *dejson::deser) (u8 | dejson::error) = { +	const v = dejson::number_i64(de)?; +	if (v % 90 != 0) +		return dejson::fail(de, +			"Angle {} is not aligned to 90° increments", v); +	return (v / 90 & 3): u8; +}; diff --git a/nbt/load.ha b/nbt/load.ha new file mode 100644 index 0000000..9e54bbb --- /dev/null +++ b/nbt/load.ha @@ -0,0 +1,152 @@ +use endian; +use strings; + +export type Invalid = !void; + +type Tag = enum i8 { +	END = 0, +	BYTE = 1, +	SHORT = 2, +	INT = 3, +	LONG = 4, +	FLOAT = 5, +	DOUBLE = 6, +	BYTE_ARRAY = 7, +	STRING = 8, +	LIST = 9, +	COMPOUND = 10, +	INT_ARRAY = 11, +	LONG_ARRAY = 12, +}; + +// XXX: these are duplicated from mcproto; not sure what to do about that. + +fn decode_nbytes(in: *[]u8, length: size) ([]u8 | Invalid) = { +	if (len(in) < length) return Invalid; +	const res = in[..length]; +	*in = in[length..]; +	return res; +}; + +fn decode_byte(in: *[]u8) (i8 | Invalid) = +	decode_nbytes(in, 1)?[0]: i8; +fn decode_short(in: *[]u8) (i16 | Invalid) = +	endian::begetu16(decode_nbytes(in, 2)?): i16; +fn decode_int(in: *[]u8) (i32 | Invalid) = +	endian::begetu32(decode_nbytes(in, 4)?): i32; +fn decode_long(in: *[]u8) (i64 | Invalid) = +	endian::begetu64(decode_nbytes(in, 8)?): i64; + +fn decode_bool(in: *[]u8) (bool | Invalid) = +	decode_byte(in)? != 0; + +fn decode_float(in: *[]u8) (f32 | Invalid) = +	*(&decode_int(in)?: *f32); +fn decode_double(in: *[]u8) (f64 | Invalid) = +	*(&decode_long(in)?: *f64); + +fn decode_string(in: *[]u8) (str | Invalid) = { +	const length = decode_short(in)?; +	if (length < 0) return Invalid; +	// TODO: need to deal with braindead java utf8. +	match (strings::fromutf8(decode_nbytes(in, length: size)?)) { +	case let s: str => +		return strings::dup(s); +	case => +		return Invalid; +	}; +}; + +// TODO: depth limit +export fn load(in: *[]u8) ((str, Object) | Invalid) = { +	const tag = decode_byte(in)?: Tag; +	if (tag != Tag::COMPOUND) return Invalid; +	const name = decode_string(in)?; +	match (_load(in, tag)?) { +	case let obj: Object => +		return (name, obj); +	case => +		return Invalid; +	}; +}; + +fn _load(in: *[]u8, tag: Tag) (Value | Invalid) = { +	switch (tag) { +	case Tag::BYTE => +		return decode_byte(in)?; +	case Tag::SHORT => +		return decode_short(in)?; +	case Tag::INT => +		return decode_int(in)?; +	case Tag::LONG => +		return decode_long(in)?; +	case Tag::FLOAT => +		return decode_float(in)?; +	case Tag::DOUBLE => +		return decode_double(in)?; +	case Tag::STRING => +		return decode_string(in)?; +	case Tag::BYTE_ARRAY => +		const length = decode_int(in)?; +		if (length < 0) return Invalid; +		return alloc(decode_nbytes(in, length: size)?...): []i8; +	case Tag::LIST => +		let success = false; + +		const tag = decode_byte(in)?: Tag; +		const length = decode_int(in)?; +		if (length < 0) return Invalid; + +		let list = alloc([]: [0]Value, length: size); +		defer if (!success) finish(list); +		for (let i = 0i32; i < length; i += 1) { +			static append(list, _load(in, tag)?); +		}; + +		success = true; +		return list; +	case Tag::COMPOUND => +		let success = false; + +		let object = newobject(0); +		defer if (!success) finish(object); +		for (true) { +			const tag = decode_byte(in)?: Tag; +			if (tag == Tag::END) break; +			const name = decode_string(in)?; +			defer free(name); +			set(&object, name, _load(in, tag)?); +		}; + +		success = true; +		return object; +	case Tag::INT_ARRAY => +		let success = false; +		const length = decode_int(in)?; +		if (length < 0) return Invalid; + +		let array = alloc([]: [0]i32, length: size); +		defer if (!success) free(array); +		for (let i = 0i32; i < length; i += 1) { +			static append(array, decode_int(in)?); +		}; + +		success = true; +		return array; +	case Tag::LONG_ARRAY => +		let success = false; +		const length = decode_int(in)?; +		if (length < 0) return Invalid; + +		let array = alloc([]: [0]i64, length: size); +		defer if (!success) free(array); +		for (let i = 0i32; i < length; i += 1) { +			static append(array, decode_long(in)?); +		}; + +		success = true; +		return array; +	case => +		return Invalid; +	}; +}; diff --git a/nbt/value.ha b/nbt/value.ha new file mode 100644 index 0000000..cf4aa17 --- /dev/null +++ b/nbt/value.ha @@ -0,0 +1,141 @@ +use hash::fnv; +use htab; +use strings; + +export type Value = ( +	i8 | i16 | i32 | i64 | f32 | f64 +	| []i8 | []i32 | []i64 | str +	| []Value | Object); + +export type Object = struct { +	table: htab::table, +}; + +type Entry = (str, Value); + +fn eq_fn(ctx: *opaque, key: *opaque) bool = +	*(ctx: *str) == *(key: *str); + +fn _get(object: *Object, hash: u64, key: str) nullable *Entry = +	htab::get(&object.table, hash, &eq_fn, &key, size(Entry)): +		nullable *Entry; + +export fn newobject(cap: size) Object = +	Object { table = htab::new(cap, size(Entry)) }; + +export fn count(object: *Object) size = +	return htab::count(&object.table); + +export fn get(object: *Object, key: str) nullable *Value = { +	const hash = fnv::string64(key); +	match (_get(object, hash, key)) { +	case let entry: *Entry => +		return &entry.1; +	case null => +		return null; +	}; +}; + +export fn set(object: *Object, key: str, value: Value) void = { +	const hash = fnv::string64(key); +	match (_get(object, hash, key)) { +	case let entry: *Entry => +		finish(entry.1); +		entry.1 = value; +	case null => +		const entry = htab::add(&object.table, hash, size(Entry)): +			*Entry; +		*entry = (strings::dup(key), value); +	}; +}; + +export fn del(object: *Object, key: str) (Value | void) = { +	const hash = fnv::string64(key); +	match (_get(object, hash, key)) { +	case let entry: *Entry => +		free(entry.0); +		const value = entry.1; +		htab::del(&object.table, entry, size(Entry)); +		return value; +	case null => void; +	}; +}; + +export fn _clear(object: *Object) void = { +	let it = htab::iter(&object.table); +	for (true) match (htab::next(&it, size(Entry)): nullable *Entry) { +	case let entry: *Entry => +		free(entry.0); +		finish(entry.1); +	case null => break; +	}; +}; + +export fn clear(object: *Object) void = { +	_clear(object); +	htab::clear(&object.table, size(Entry)); +}; + +export type Iterator = struct { +	iter: htab::iterator, +}; + +export fn iter(object: *Object) Iterator = +	Iterator { iter = htab::iter(&object.table) }; + +export fn next(it: *Iterator) ((str, *Value) | void) = { +	match (htab::next(&it.iter, size(Entry)): nullable *Entry) { +	case let entry: *Entry => +		return (entry.0, &entry.1); +	case null => void; +	}; +}; + +export fn dup(value: *Value) Value = { +	match (*value) { +	case let array: []i8 => +		return alloc(array...); +	case let array: []i32 => +		return alloc(array...); +	case let array: []i64 => +		return alloc(array...); +	case let string: str => +		return strings::dup(string); +	case let list: []Value => +		let list_ = alloc([]: [0]Value, len(list)); +		for (let i = 0z; i < len(list); i +=  1) { +			append(list_, dup(&list[i])); +		}; +		return list_; +	case let object: Object => +		let object_ = newobject(count(&object)); +		let it = iter(&object); +		for (true) match (next(&it)) { +		case let entry: (str, *Value) => +			set(&object_, entry.0, dup(entry.1)); +		case void => break; +		}; +		return object_; +	}; +}; + +export fn finish(value: Value) void = { +	match (value) { +	case (i8 | i16 | i32 | i64 | f32 | f64) => void; +	case let array: []i8 => +		free(array); +	case let array: []i32 => +		free(array); +	case let array: []i64 => +		free(array); +	case let string: str => +		free(string); +	case let list: []Value => +		for (let i = 0z; i < len(list); i +=  1) { +			finish(list[i]); +		}; +		free(list); +	case let object: Object => +		_clear(&object); +	}; +}; diff --git a/objreg.ha b/objreg.ha new file mode 100644 index 0000000..2630328 --- /dev/null +++ b/objreg.ha @@ -0,0 +1,64 @@ +use hash::fnv; +use htab; + +type ObjectRegistry = struct { +	table: htab::table, // *Object +}; + +type Object = struct { +	name: str, +}; + +def OBJREG_EMPTY = ObjectRegistry { +	table = HTAB_EMPTY, +}; + +fn newobjreg() ObjectRegistry = +	ObjectRegistry { +		table = htab::new(0, size(*Object)), +	}; + +fn objreg_eqfunc(ctx: *opaque, entry: *opaque) bool = +	return *(ctx: *str) == (entry: **Object).name; + +fn objreg_find(reg: *ObjectRegistry, name: str) nullable *opaque = { +	const hash = fnv::string64(name); +	match (htab::get(®.table, hash, +		&objreg_eqfunc, &name, size(*Object))) { +	case let entry: *opaque => +		return *(entry: **Object); +	case null => +		return null; +	}; +}; + +fn objreg_register(reg: *ObjectRegistry, obj: *Object) void = { +	assert(objreg_find(reg, obj.name) == null, "already registered"); +	const hash = fnv::string64(obj.name); +	const entry = htab::add(®.table, hash, size(*Object)); +	*(entry: **Object) = obj; +}; + +fn objreg_count(reg: *ObjectRegistry) size = +	htab::count(®.table); + +fn objreg_clear(reg: *ObjectRegistry) void = +	htab::clear(®.table, size(*Object)); + +type ObjectRegistryIterator = struct { +	inner: htab::iterator, +}; + +fn objreg_iter(reg: *ObjectRegistry) ObjectRegistryIterator = +	ObjectRegistryIterator { +		inner = htab::iter(®.table), +	}; + +fn objreg_next(it: *ObjectRegistryIterator) nullable *Object = { +	match (htab::next(&it.inner, size(*Object))) { +	case let entry: *opaque => +		return *(entry: **Object); +	case null => +		return null; +	}; +}; diff --git a/player.ha b/player.ha new file mode 100644 index 0000000..e2ab10d --- /dev/null +++ b/player.ha @@ -0,0 +1,67 @@ +use glm; +use mcproto; + +def PLAYER_MAX_HEALTH = 20.0f32; +def PLAYER_MAX_FOOD = 20i32; +def PLAYER_MAX_SATURATION = 5.0f32; + +let PLAYER_POS: glm::v3 = [0.0...]; +let PLAYER_YAW = 0.0f32; +let PLAYER_PITCH = 0.0f32; +let PLAYER_HEALTH = PLAYER_MAX_HEALTH; +let PLAYER_FOOD = PLAYER_MAX_FOOD; +let PLAYER_SATURATION = PLAYER_MAX_SATURATION; + +let PLAYER_CONTROL_WALK = 0.0f32; +let PLAYER_CONTROL_STRAFE = 0.0f32; +let PLAYER_CONTROL_JUMP = false; +let PLAYER_CONTROL_SNEAK = false; + +fn player_despawn() void = { +	PLAYER_POS = [0.0...]; +	PLAYER_YAW = 0.0; +	PLAYER_PITCH = 0.0; +	PLAYER_HEALTH = PLAYER_MAX_HEALTH; +	PLAYER_FOOD = PLAYER_MAX_FOOD; +	PLAYER_SATURATION = PLAYER_MAX_SATURATION; + +	PLAYER_CONTROL_WALK = 0.0; +	PLAYER_CONTROL_STRAFE = 0.0; +	PLAYER_CONTROL_JUMP = false; +	PLAYER_CONTROL_SNEAK = false; +}; + +fn player_control(control: *Control) void = { +	PLAYER_YAW += control.yaw; +	PLAYER_PITCH += control.pitch; +	PLAYER_CONTROL_WALK = control.walk; +	PLAYER_CONTROL_STRAFE = control.strafe; +	PLAYER_CONTROL_JUMP = control.jump; +	PLAYER_CONTROL_SNEAK = control.sneak; +}; + +fn player_tick() void = { +	// as noted in game.ha, we need to negate yaw to obtain +	// a conventionally oriented angle. +	const yaw_trans = glm::rotation_make(-glm::rad(PLAYER_YAW), +		&glm::v3_new(0.0, 1.0, 0.0)); +	const motion: glm::v3 = [ +		PLAYER_CONTROL_STRAFE, +		(if (PLAYER_CONTROL_JUMP) 1.0f32 else 0.0f32) +			- (if (PLAYER_CONTROL_SNEAK) 1.0f32 else 0.0f32), +		PLAYER_CONTROL_WALK, +	]; +	glm::v3_scale(&motion, 1.0); +	motion = glm::affine_mul_v3(&yaw_trans, &motion); +	PLAYER_POS = glm::v3_add(&PLAYER_POS, &motion); + +	let out: []u8 = []; +	defer free(out); +	mcproto::encode_double(&out, PLAYER_POS[0]); +	mcproto::encode_double(&out, PLAYER_POS[1]); +	mcproto::encode_double(&out, PLAYER_POS[2]); +	mcproto::encode_float(&out, PLAYER_YAW); +	mcproto::encode_float(&out, PLAYER_PITCH); +	mcproto::encode_bool(&out, true); +	network_send(0x14, out); +}; diff --git a/position.ha b/position.ha new file mode 100644 index 0000000..aa0e36d --- /dev/null +++ b/position.ha @@ -0,0 +1,49 @@ +use glm; + +type ChunkPos = struct { +	x: i32, +	z: i32, +}; + +type SectionPos = union { +	chunk: ChunkPos, +	struct { +		ChunkPos, +		y: i8, +	}, +}; + +type BlockPos = struct { +	x: i32, +	y: i16, +	z: i32, +}; + +type Dir = enum u8 { +	WEST, +	EAST, +	DOWN, +	UP, +	NORTH, +	SOUTH, +}; + +fn block_section(pos: BlockPos) SectionPos = { +	return SectionPos { +		x = pos.x >> 4, +		y = (pos.y >> 4): i8, +		z = pos.z >> 4, +	}; +}; + +fn section_origin(pos: SectionPos) glm::v3 = { +	return glm::v3_new( +		pos.x: f32 * 16.0, +		pos.y: f32 * 16.0, +		pos.z: f32 * 16.0, +	); +}; + +fn block_origin(pos: BlockPos) glm::v3 = { +	return glm::v3_new(pos.x: f32, pos.y: f32, pos.z: f32); +}; diff --git a/proto.ha b/proto.ha new file mode 100644 index 0000000..01e0d33 --- /dev/null +++ b/proto.ha @@ -0,0 +1,715 @@ +use comparray; +use endian; +use mcproto; +use nbt; +use fmt; +use strings; +use trace; + +fn decode_position(ctx: *mcproto::Context) (BlockPos | trace::failed) = { +	const v = mcproto::decode_long(ctx)?: i64; +	return BlockPos { +		x = (v >> 38): i32, +		y = (v << 52 >> 52): i16, +		z = (v << 26 >> 38): i32, +	}; +}; + +fn decode_nbt(ctx: *mcproto::Context) ((str, nbt::Object) | trace::failed) = { +	let in = ctx.dec.input[ctx.dec.pos..]; +	match (nbt::load(&in)) { +	case let res: (str, nbt::Object) => +		ctx.dec.pos += len(ctx.dec.input) - ctx.dec.pos - len(in); +		return res; +	case nbt::Invalid => +		return mcproto::error(ctx, "Invalid NBT"); +	}; +}; + +type Handler = fn(ctx: *mcproto::Context) +	(void | trace::failed); + +fn game_handle_packet(ctx: *mcproto::Context, packet_id: i32) +		(void | trace::failed) = { +	const handler = if (packet_id: size < len(PROTO_HANDLERS)) +		PROTO_HANDLERS[packet_id: size] else null; +	match (handler) { +	case let handler: *Handler => +		const ctx_ = mcproto::context(ctx, "0x{:02x}", packet_id); +		return handler(&ctx_); +	case null => +		// TODO: implement all the packets ._. +		// erroring here would spam too much for now... +		void; +	}; +}; + +const PROTO_HANDLERS: [_]nullable *Handler = [ +	null, // 0x00 +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	&handle_block_update, +	null, +	null, +	null, +	null, +	null, +	null, +	null, // 0x10 +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	&handle_unload_chunk, +	null, +	null, +	null, +	null, // handle_keep_alive; handled in client_handle_packet. +	&handle_chunk_data_and_update_light, +	null, +	null, +	null, +	null, // handle_login; handled in client_handle_packet. +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, // 0x30 +	null, +	null, +	null, +	&handle_combat_death, +	null, +	null, +	null, +	&handle_synchronize_player_position, +	null, +	null, +	null, +	null, +	&handle_respawn, +	null, +	&handle_update_section_blocks, +	null, // 0x40 +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	&handle_set_center_chunk, +	null, +	&handle_set_default_spawn_position, +	null, +	null, +	null, +	null, // 0x50 +	null, +	null, +	&handle_set_health, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, // 0x60 +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +	null, +]; + +fn handle_login(ctx: *mcproto::Context) (void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "player id"); +	const player_id = mcproto::decode_int(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "is hardcore"); +	const is_hardcore = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "gamemode"); +	const gamemode = mcproto::decode_byte(&ctx_)?: Gamemode; +	if (gamemode >= Gamemode::COUNT) { +		return mcproto::error(&ctx_, "Invalid gamemode 0x{:02x}", +			gamemode: u8); +	}; +	const ctx_ = mcproto::context(ctx, "previous gamemode"); +	const prev_gamemode = mcproto::decode_byte(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "dimension count"); +	const dim_count = mcproto::decode_varint(&ctx_)?; +	for (let i = 0i32; i < dim_count; i += 1) { +		const ctx_ = mcproto::context(ctx, "dimension name {}", i); +		const dim_name = mcproto::decode_string(&ctx_, 0x7fff)?; +	}; +	const ctx_ = mcproto::context(ctx, "registry"); +	const registry = decode_nbt(&ctx_)?; +	free(registry.0); +	const registry = registry.1; +	defer nbt::finish(registry); +	const ctx_ = mcproto::context(ctx, "dimension type"); +	const dim_type = mcproto::decode_string(&ctx_, 0x7fff)?; +	const ctx_ = mcproto::context(ctx, "dimension name"); +	const dim_name = mcproto::decode_string(&ctx_, 0x7fff)?; +	const ctx_ = mcproto::context(ctx, "hashed seed"); +	const hashed_seed = mcproto::decode_long(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "max players"); +	const max_players = mcproto::decode_varint(&ctx_)?; +	if (max_players < 0) { +		return mcproto::error(&ctx_, "Max players must not be negative"); +	}; +	const ctx_ = mcproto::context(ctx, "view distance"); +	const view_distance = mcproto::decode_varint(&ctx_)?; +	if (view_distance <= 0) { +		return mcproto::error(&ctx_, "View distance must be positive"); +	}; +	const ctx_ = mcproto::context(ctx, "simulation distance"); +	const sim_distance = mcproto::decode_varint(&ctx_)?; +	if (sim_distance <= 0) { +		return mcproto::error(&ctx_, +			"Simulation distance must be positive"); +	}; +	const ctx_ = mcproto::context(ctx, "reduced debug info"); +	const reduced_debug_info = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "enable respawn screen"); +	const enable_respawn_screen = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "is debug"); +	const is_debug = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "is flat"); +	const is_flat = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "has death location"); +	if (mcproto::decode_bool(&ctx_)?) { +		const ctx_ = mcproto::context(ctx, "death dimension"); +		const death_dim = mcproto::decode_string(&ctx_, 0x7fff)?; +		const ctx_ = mcproto::context(ctx, "death position"); +		const death_pos = decode_position(&ctx_)?; +	}; +	mcproto::expect_end(ctx)?; + +	GAMEMODE = gamemode; +	trace::info(&trace::root, "gamemode {}", strgamemode(GAMEMODE)); + +	assert(len(DIM_TYPES) == 0); +	match (nbt_get(®istry, "minecraft:dimension_type")) { +	case let reg: nbt::Object => +		match (nbt_get(®, "value")) { +		case let reg: []nbt::Value => +			for (let i = 0z; i < len(reg); i += 1) { +				const entry = match (reg[i]) { +				case let entry: nbt::Object => +					yield entry; +				case => +					return mcproto::error(ctx, "Invalid registry"); +				}; +				const name = match (nbt_get(&entry, "name")) { +				case let name: str => +					yield strings::dup(name); +				case => +					return mcproto::error(ctx, "Invalid registry"); +				}; +				const elem = match (nbt_get(&entry, "element")) { +				case let elem: nbt::Object => +					yield elem; +				case => +					return mcproto::error(ctx, "Invalid registry"); +				}; +				const min_y = match (nbt_get(&elem, "min_y")) { +				case let min_y: i32 => +					if (min_y & 0xf != 0) +						return mcproto::error(ctx, "Invalid registry"); +					min_y >>= 4; +					if (min_y: i8 != min_y) +						return mcproto::error(ctx, "Invalid registry"); +					yield min_y: i8; +				case => +					return mcproto::error(ctx, "Invalid registry"); +				}; +				const height = match (nbt_get(&elem, "height")) { +				case let height: i32 => +					if (height & 0xf != 0) +						return mcproto::error(ctx, "Invalid registry"); +					height >>= 4; +					if (height: u8 != height: u32) +						return mcproto::error(ctx, "Invalid registry"); +					yield height: u8; +				case => +					return mcproto::error(ctx, "Invalid registry"); +				}; +				if (min_y + height: i8 < min_y) { +					return mcproto::error(ctx, "Invalid registry"); +				}; +				append(DIM_TYPES, DimType { +					name = name, +					min_y = min_y, +					height = height, +				}); +			}; +		case => +			return mcproto::error(ctx, "Invalid registry"); +		}; +	case => +		return mcproto::error(ctx, "Invalid registry"); +	}; + +	let found = false; +	for (let i = 0z; i < len(DIM_TYPES); i += 1) { +		if (DIM_TYPES[i].name == dim_type) { +			found = true; +			DIM_TYPE = i; +		}; +	}; +	if (!found) { +		return mcproto::error(ctx, "Unknown dimension type {}", dim_type); +	}; +	trace::info(&trace::root, "dimension type {}", DIM_TYPES[DIM_TYPE].name); + +	VIEW_DISTANCE = view_distance; +	trace::info(&trace::root, "view distance {}", VIEW_DISTANCE); + +	game_init(); +}; + +fn handle_respawn(ctx: *mcproto::Context) (void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "dimension type"); +	const dim_type = mcproto::decode_string(&ctx_, 0x7fff)?; +	const ctx_ = mcproto::context(ctx, "dimension name"); +	const dim_name = mcproto::decode_string(&ctx_, 0x7fff)?; +	const ctx_ = mcproto::context(ctx, "hashed seed"); +	const hashed_seed = mcproto::decode_long(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "gamemode"); +	const gamemode = mcproto::decode_byte(&ctx_)?: Gamemode; +	if (gamemode >= Gamemode::COUNT) { +		return mcproto::error(&ctx_, "Invalid gamemode 0x{:02x}", +			gamemode: u8); +	}; +	const ctx_ = mcproto::context(ctx, "previous gamemode"); +	const prev_gamemode = mcproto::decode_byte(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "is debug"); +	const is_debug = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "is flat"); +	const is_flat = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "copy metadata"); +	const copy_metadata = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "has death location"); +	if (mcproto::decode_bool(&ctx_)?) { +		const ctx_ = mcproto::context(ctx, "death dimension"); +		const death_dim = mcproto::decode_string(&ctx_, 0x7fff)?; +		const ctx_ = mcproto::context(ctx, "death position"); +		const death_pos = decode_position(&ctx_)?; +	}; +	mcproto::expect_end(ctx)?; + +	game_despawn(); + +	GAMEMODE = gamemode; +	trace::info(&trace::root, "gamemode {}", strgamemode(GAMEMODE)); + +	let found = false; +	for (let i = 0z; i < len(DIM_TYPES); i += 1) { +		if (DIM_TYPES[i].name == dim_type) { +			found = true; +			DIM_TYPE = i; +		}; +	}; +	if (!found) { +		return mcproto::error(ctx, "Unknown dimension type {}", +			dim_type); +	}; +	trace::info(&trace::root, "dimension type {}", +		DIM_TYPES[DIM_TYPE].name); + +	game_respawn(); +}; + +fn handle_keep_alive(ctx: *mcproto::Context) (void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "id"); +	const id = mcproto::decode_long(&ctx_)?; +	mcproto::expect_end(ctx)?; + +	let out: []u8 = []; +	defer free(out); +	mcproto::encode_long(&out, id); +	network_send(0x11, out); +}; + +fn handle_set_center_chunk(ctx: *mcproto::Context) +		(void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "x"); +	const x = mcproto::decode_varint(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "z"); +	const z = mcproto::decode_varint(&ctx_)?; +	mcproto::expect_end(ctx)?; + +	setview(ChunkPos { x = x, z = z }); +}; + +type SyncPositionFlags = enum u8 { +	X = 0x1, +	Y = 0x2, +	Z = 0x4, +	// TODO: confirm that these are the correct way around; +	// update wiki to clarify. +	YAW = 0x8, +	PITCH = 0xa, +}; + +fn handle_synchronize_player_position(ctx: *mcproto::Context) +		(void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "x"); +	let x = mcproto::decode_double(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "y"); +	let y = mcproto::decode_double(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "z"); +	let z = mcproto::decode_double(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "yaw"); +	let yaw = mcproto::decode_float(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "pitch"); +	let pitch = mcproto::decode_float(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "flags"); +	const flags = mcproto::decode_byte(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "teleport id"); +	const id = mcproto::decode_varint(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "dismount"); +	const dismount = mcproto::decode_bool(&ctx_)?; +	mcproto::expect_end(ctx)?; + +	if (flags & SyncPositionFlags::X != 0) x += PLAYER_POS[0]; +	if (flags & SyncPositionFlags::Y != 0) y += PLAYER_POS[1]; +	if (flags & SyncPositionFlags::Z != 0) z += PLAYER_POS[2]; +	if (flags & SyncPositionFlags::YAW != 0) yaw += PLAYER_YAW; +	if (flags & SyncPositionFlags::PITCH != 0) pitch += PLAYER_PITCH; + +	PLAYER_POS = [x: f32, y: f32, z: f32]; +	PLAYER_YAW = yaw; +	PLAYER_PITCH = pitch; + +	let out: []u8 = []; +	defer free(out); +	mcproto::encode_varint(&out, id); +	network_send(0x00, out); + +	// TODO: is this necessary? (probably for anticheat reasons, at +	// least...) +	let out: []u8 = []; +	defer free(out); +	mcproto::encode_double(&out, PLAYER_POS[0]); +	mcproto::encode_double(&out, PLAYER_POS[1]); +	mcproto::encode_double(&out, PLAYER_POS[2]); +	mcproto::encode_float(&out, PLAYER_YAW); +	mcproto::encode_float(&out, PLAYER_PITCH); +	mcproto::encode_bool(&out, true); +	network_send(0x14, out); +}; + +fn handle_set_health(ctx: *mcproto::Context) (void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "health"); +	const health = mcproto::decode_float(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "food"); +	const food = mcproto::decode_varint(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "saturation"); +	const saturation = mcproto::decode_float(&ctx_)?; +	mcproto::expect_end(ctx)?; + +	PLAYER_HEALTH = health; +	PLAYER_FOOD = food; +	PLAYER_SATURATION = saturation; +}; + +fn handle_combat_death(ctx: *mcproto::Context) (void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "player id"); +	const player_id = mcproto::decode_varint(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "entity id"); +	const entity_id = mcproto::decode_int(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "message"); +	const message = mcproto::decode_string(&ctx_, 0x7fff)?; +	mcproto::expect_end(ctx)?; + +	trace::info(&trace::root, "death: {}", message); + +	death_show(message); +}; + +fn handle_set_default_spawn_position(ctx: *mcproto::Context) +		(void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "position"); +	const pos = decode_position(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "yaw"); +	const yaw = mcproto::decode_float(&ctx_)?; + +	LOADING_RECEIVED_SPAWN_POSITION = true; +}; + +fn handle_block_update(ctx: *mcproto::Context) (void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "position"); +	const pos = decode_position(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "blockstate"); +	const bstate = mcproto::decode_varint(&ctx_)?; +	if (bstate & ~0xffff != 0) { +		return mcproto::error(&ctx_, "Blockstate id too large"); +	}; +	const bstate = bstate: u16; +	mcproto::expect_end(&ctx_)?; + +	if (getsection(block_section(pos)) is null) { +		mcproto::log(ctx, trace::level::WARN, +			"Block update references nonexistent chunk: ( {} {} {} )", +			pos.x, pos.y, pos.z); +		return; +	}; + +	setblock(pos, bstate); +}; + +fn handle_update_section_blocks(ctx: *mcproto::Context) +		(void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "section position"); +	const section_pos = mcproto::decode_long(&ctx_)?: i64; +	const section_pos = SectionPos { +		x = (section_pos >> 42): i32, +		y = (section_pos << 44 >> 44): i8, +		z = (section_pos << 22 >> 42): i32, +	}; +	if (getsection(section_pos) is null) { +		mcproto::log(ctx, trace::level::WARN, +			"Section update references nonexistent chunk: [ {} {} {} ]", +			section_pos.x, section_pos.y, section_pos.z); +		return; +	}; +	const ctx_ = mcproto::context(ctx, "suppress light updates"); +	const suppress_light_updates = mcproto::decode_bool(&ctx_)?; +	const ctx_ = mcproto::context(ctx, "block count"); +	const nblocks = mcproto::decode_varint(&ctx_)?; +	for (let i = 0i32; i < nblocks; i += 1) { +		const ctx_ = mcproto::context(ctx, "entry {}", i); +		// TODO: should be varlong +		const entry = mcproto::decode_varint(&ctx_)?; +		const pos = BlockPos { +			x = (section_pos.x << 4) + (entry >> 8 & 0xf), +			y = (section_pos.y: i16 << 4) + (entry & 0xf): i16, +			z = (section_pos.z << 4) + (entry >> 4 & 0xf), +		}; +		const bstate = entry >> 12; +		if (bstate & ~0xffff != 0) { +			return mcproto::error(&ctx_, "Blockstate id too large"); +		}; +		const bstate = bstate: u16; + +		setblock(pos, bstate); +	}; +	mcproto::expect_end(ctx)?; +}; + +fn handle_chunk_data_and_update_light(ctx: *mcproto::Context) +		(void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "x"); +	const x = mcproto::decode_int(&ctx_)?: i32; +	const ctx_ = mcproto::context(ctx, "z"); +	const z = mcproto::decode_int(&ctx_)?: i32; +	const chunk_pos = ChunkPos { x = x, z = z }; +	if (getchunk(chunk_pos) is null) { +		return mcproto::error(ctx, +			"Chunk out of range: [ {} {} ]", +			chunk_pos.x, chunk_pos.z); +	}; +	const ctx_ = mcproto::context(ctx, "heightmaps"); +	const heightmaps = decode_nbt(&ctx_)?; +	free(heightmaps.0); +	const heightmaps = heightmaps.1; +	defer nbt::finish(heightmaps); +	const ctx_ = mcproto::context(ctx, "data length"); +	const datalen = mcproto::decode_varint(&ctx_)?; +	if (datalen < 0) { +		return mcproto::error(&ctx_, "Data length must not be negative"); +	}; +	const datalen = datalen: u32; +	const ctx_ = mcproto::context(ctx, "chunk data"); +	mcproto::decode_nbytes(&ctx_, datalen)?; +	let cdec = *ctx.dec; +	cdec.input = cdec.input[..cdec.pos]; +	cdec.pos -= datalen; +	const cctx = mcproto::root(&cdec); + +	const chunk = chunk_init(chunk_pos); + +	for (let i = 0z; i < CHUNKS_HEIGHT; i += 1) { +		const cctx_ = mcproto::context(&cctx, "block count"); +		const block_count = mcproto::decode_short(&cctx_)?; +		const cctx_ = mcproto::context(&cctx, "bits per entry"); +		const bpe = mcproto::decode_byte(&cctx_)?; + +		const bstates = if (bpe == 0) { // constant +			const cctx_ = mcproto::context(&cctx, "constant value"); +			const value = mcproto::decode_varint(&cctx_)?; +			if (value > 0xffff) { +				return mcproto::error(&cctx_, "Blockstate id too large"); +			}; +			const cctx_ = mcproto::context(&cctx, "array length"); +			const arraylen = mcproto::decode_varint(&cctx_)?; +			if (arraylen != 0) { +				return mcproto::error(&cctx_, +					"Chunk data array must be empty when bpe = 0"); +			}; +			let array = comparray::new(1, 4096); +			comparray::clear(&array, value: u16); +			yield array; +		} else { +			let array = if (bpe >= 9) { // direct +				yield comparray::new(0, 4096); +			} else { // indirect +				const cctx_ = mcproto::context(&cctx, +					"palette length"); +				const palettelen = +					mcproto::decode_varint(&cctx_)?: u32; +				if (palettelen >= 256 || palettelen < 2) { +					// = 256 is actually possible, but it's +					// going to be a huge pain. oh well. +					return mcproto::error(&cctx_, "Uh oh."); +				}; +				let array = +					comparray::new(palettelen: u8, 4096); +				let palette = comparray::get_palette(&array); +				for (let i = 0z; i < palettelen; i += 1) { +					const cctx_ = mcproto::context(&cctx, +						"palette entry {}", i); +					const value = +						mcproto::decode_varint(&cctx_)?; +					if (value > 0xffff) { +						return mcproto::error(&cctx_, +							"Blockstate id too large"); +					}; +					palette[i] = value: u16; +				}; +				yield array; +			}; + +			const bpe = if (bpe <= 4) 4u8 +				else if (bpe <= 8) bpe: u8 +				else 15u8; + +			const cctx_ = mcproto::context(&cctx, "array length"); +			const arraylen = mcproto::decode_varint(&cctx_)?; +			const epl = 64 / bpe; +			const arraylen_ = (4096z + epl - 1) / epl; +			if (arraylen: size != arraylen_) { +				return mcproto::error(&cctx_, +					"Chunk data array with bpe = {} must have length {}, not {}", +					bpe, arraylen_, arraylen); +			}; +			const cctx_ = mcproto::context(&cctx, "array data"); +			let arraydata = +				mcproto::decode_nbytes(&cctx_, +					arraylen: size * 8)?; + +			let pos = 0z; +			let long = 0u64; +			let shift = 64u8; +			const mask = (1u64 << bpe) - 1; +			for (let i = 0z; i < 4096; i += 1) { +				if (shift + bpe > 64) { +					long = endian::begetu64( +						arraydata[pos..pos + 8]); +					pos += 8; +					shift = 0; +				}; +				const value = long >> shift & mask; +				shift += bpe; +				if (array.palette_size != 0 +						&& value > array.palette_size) { +					return mcproto::error(&cctx_, +						"Palette index out of range (entry {})", +						i); +				}; +				if (array.palette_size == 0 && value > 0xffff) { +					return mcproto::error(&cctx_, +						"Blockstate id too large (entry {})", +						i); +				}; +				comparray::set(&array, i, value: u16); +			}; + +			yield array; +		}; + +		const cctx_ = mcproto::context(&cctx, "bits per entry"); +		const bpe = mcproto::decode_byte(&cctx_)?; +		if (bpe == 0) { // constant +			const cctx_ = mcproto::context(&cctx, "constant value"); +			mcproto::decode_varint(&cctx_)?; +		} else if (bpe < 4) { // indirect +			const cctx_ = mcproto::context(&cctx, "palette length"); +			const palettelen = mcproto::decode_varint(&cctx)?: u32; +			for (let i = 0z; i < palettelen; i += 1) { +				const cctx_ = mcproto::context(&cctx, +					"palette entry {}", i); +				mcproto::decode_varint(&cctx_)?; +			}; +		}; +		const cctx_ = mcproto::context(&cctx, "array length"); +		const arraylen = mcproto::decode_varint(&cctx_)?: u32; +		const cctx_ = mcproto::context(&cctx, "array data"); +		mcproto::decode_nbytes(&cctx_, arraylen: size * 8)?; + +		const section = &(chunk.sections as *[*]Section)[i]; +		section.bstates = bstates; +		section.dirty = true; +	}; + +	// other stuff we don't care about for now. +}; + +fn handle_unload_chunk(ctx: *mcproto::Context) +		(void | trace::failed) = { +	const ctx_ = mcproto::context(ctx, "x"); +	const x = mcproto::decode_int(&ctx_)?: i32; +	const ctx_ = mcproto::context(ctx, "z"); +	const z = mcproto::decode_int(&ctx_)?: i32; +	chunk_destroy(ChunkPos { x = x, z = z }); +}; + +// this is really awkward, but i hear a "match overhaul" is coming that should +// improve things... +fn nbt_get(obj: *nbt::Object, key: str) +		(...nbt::Value | void) = { +	match (nbt::get(obj, key)) { +	case let value: *nbt::Value => +		return *value; +	case null => +		return void; +	}; +}; @@ -0,0 +1,105 @@ +use errors; +use io; +use mcproto; +use net; + +type Receiver = struct { +	buf: []u8, +	start: size, +	avail: size, +	packet_length: (size | void), +}; + +fn newrecv(bufsize: size) Receiver = { +	assert(bufsize & (bufsize - 1) == 0, "bufsize must be a power of 2"); + +	return Receiver { +		buf = alloc([0...], bufsize), +		start = 0, +		avail = 0, +		packet_length = void, +	}; +}; + +fn recv_finish(recv: *Receiver) void = { +	free(recv.buf); +}; + +fn recv_poll(recv: *Receiver, s: io::handle, out: []u8) (size | void) = { +	for (true) { +		for (true) match (recv.packet_length) { +		case void => +			match (recv_read_varint(recv)) { +			case void => +				break; +			case let length: i32 => +				if (length: u32 > len(recv.buf)) { +					die("packet too long: {}", length); +				}; +				recv.packet_length = length: u32; +			}; +		case let length: size => +			if (recv.avail < length) { +				break; +			}; +			recv.packet_length = void; + +			assert(len(out) >= length, +				"not enough space in output buffer"); + +			let payload = out[..0]; +			const pl_end = recv.start + length & len(recv.buf) - 1; +			if (recv.start < pl_end || length == 0) { +				static append(payload, +					recv.buf[recv.start..pl_end]...); +			} else { +				static append(payload, +					recv.buf[recv.start..]...); +				static append(payload, +					recv.buf[..pl_end]...); +			}; +			assert(len(payload) == length); +			recv_advance(recv, length); + +			return length; +		}; + +		assert(recv.avail < len(recv.buf)); +		const end = recv.start + recv.avail & len(recv.buf) - 1; +		const limit = if (recv.start <= end) len(recv.buf) +			else recv.start; +		match (io::read(s, recv.buf[end..limit])) { +		case let nread: size => +			recv.avail += nread; +		case io::EOF => +			die("disconnected"); +		case errors::again => +			return; +		case let err: io::error => +			die("read: {}", io::strerror(err)); +		}; +	}; +}; + +fn recv_read_varint(recv: *Receiver) (i32 | void) = { +	let res = 0u32; + +	for (let i = 0u32; i < 3; i += 1) { +		if (i >= recv.avail) { +			return; +		}; +		const b = recv.buf[recv.start + i & len(recv.buf) - 1]; +		res |= (b & 0x7f): u32 << (7 * i); +		if (b & 0x80 == 0) { +			recv_advance(recv, i + 1); +			return res: i32; +		}; +	}; + +	die("varint should have ended by now"); +}; + +fn recv_advance(recv: *Receiver, n: size) void = { +	recv.start = recv.start + n & len(recv.buf) - 1; +	recv.avail -= n; +}; diff --git a/render.ha b/render.ha new file mode 100644 index 0000000..9754936 --- /dev/null +++ b/render.ha @@ -0,0 +1,94 @@ +use gl::*; +use glm; +use glw; +use math; +use sdl2::*; +use time; +use trace; + +type Vertex = struct { +	position: [3]u16, +	normal: [3]i8, +	texcoord: [2]u16, +	flags: u8, +}; + +type VertexFlags = enum u8 { +	U_EXCL = 1 << 0, +	V_EXCL = 1 << 1, +}; + +fn render_init(assets: *Pack) void = { +	const t = time::now(time::clock::MONOTONIC); +	const u = time::now(time::clock::PROCESS_CPU); +	load_textures(assets); +	trace::debug(&trace::root, "texture loading took rt {} ms / cpu {} ms", +		time::diff(t, time::now(time::clock::MONOTONIC)) / 1000000, +		time::diff(u, time::now(time::clock::PROCESS_CPU)) / 1000000); + +	const t = time::now(time::clock::MONOTONIC); +	const u = time::now(time::clock::PROCESS_CPU); +	load_atlases(assets); +	trace::debug(&trace::root, "atlas loading took rt {} ms / cpu {} ms", +		time::diff(t, time::now(time::clock::MONOTONIC)) / 1000000, +		time::diff(u, time::now(time::clock::PROCESS_CPU)) / 1000000); + +	const t = time::now(time::clock::MONOTONIC); +	const u = time::now(time::clock::PROCESS_CPU); +	load_fonts(assets); +	trace::debug(&trace::root, "font loading took rt {} ms / cpu {} ms", +		time::diff(t, time::now(time::clock::MONOTONIC)) / 1000000, +		time::diff(u, time::now(time::clock::PROCESS_CPU)) / 1000000); + +	const t = time::now(time::clock::MONOTONIC); +	const u = time::now(time::clock::PROCESS_CPU); +	load_models(assets); +	trace::debug(&trace::root, "model loading took rt {} ms / cpu {} ms", +		time::diff(t, time::now(time::clock::MONOTONIC)) / 1000000, +		time::diff(u, time::now(time::clock::PROCESS_CPU)) / 1000000); + +	const t = time::now(time::clock::MONOTONIC); +	const u = time::now(time::clock::PROCESS_CPU); +	load_render_bstates(assets); +	trace::debug(&trace::root, "render bstate loading took rt {} ms / cpu {} ms", +		time::diff(t, time::now(time::clock::MONOTONIC)) / 1000000, +		time::diff(u, time::now(time::clock::PROCESS_CPU)) / 1000000); + +	const t = time::now(time::clock::MONOTONIC); +	const u = time::now(time::clock::PROCESS_CPU); +	shaders_init(); +	trace::debug(&trace::root, "shader loading took rt {} ms / cpu {} ms", +		time::diff(t, time::now(time::clock::MONOTONIC)) / 1000000, +		time::diff(u, time::now(time::clock::PROCESS_CPU)) / 1000000); + +	hud_load(); +}; + +fn render_destroy() void = { +	// TODO: +	// shaders_finish(); +	// render_bstates_finish(); +	// models_finish(); +	// atlases_finish(); +	finish_textures(); +}; + +fn render_wait_screen(text: str) void = { +	let (width, height) = drawable_size(); +	glViewport(0, 0, width: i32, height: i32); + +	let gui_width = width / gui_scale(); +	let gui_height = height / gui_scale(); + +	glClearColor(0.0, 0.0, 0.0, 1.0); +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +	const font = fonts_find("minecraft:default") as *Font; +	const metrics = font_measure(font, text); +	const text_trans = glm::translation_make(&[ +		(gui_width: f32 - metrics.width) / 2.0, +		gui_height: f32 / 2.0, +		0.0]); +	const text_trans = glm::m4_mul(gui_proj(), &text_trans); +	render_text_shadow(text, font, &text_trans, [255...]); +}; diff --git a/render_bstates.ha b/render_bstates.ha new file mode 100644 index 0000000..e4bcad2 --- /dev/null +++ b/render_bstates.ha @@ -0,0 +1,559 @@ +use dejson; +use encoding::json; +use strings; +use trace; + +type BstateRender = struct { +	parts: []BstateRenderPart, +}; + +type BstateRenderPart = struct { +	model: *Model, +	flags: BstateRenderPartFlags, +	swizzle: u8, // X,Y,Z = 0,1,2; axis_ = swizzle >> 2 * axis & 3 +	// bits 0-5: west,east,down,up,north,south +	swap_uv: u8, +	flip_u: u8, +	flip_v: u8, +}; + +type BstateRenderPartFlags = enum u8 { +	FLIP_X = 0x1, +	FLIP_Y = 0x2, +	FLIP_Z = 0x4, +}; + +let BSTATES_RENDER: []BstateRender = []; + +fn load_render_bstates(assets: *Pack) void = { +	const tr = &trace::root; +	trace::info(tr, "loading blockstate decls..."); + +	for (let blk: BlockId = 0; blk < blocks_count(); blk += 1) { +		const bstates = BLOCKS_BSTATES[blk]; +		const ident = block_getident(blk); +		const tr = trace::ctx(tr, "load blockstate information for {}", +			ident); + +		const decl = match (resource_load_json( +			assets, "blockstates", ident, ".json", &tr)) { +		case let json: json::value => +			defer json::finish(json); + +			const deser = dejson::newdeser(&json); +			yield match (deser_bstate_decl(&deser)) { +			case let x: BstateDecl => +				yield x; +			case let err: dejson::error => +				trace::error(&tr, "deser: {}", err): void; +				yield bstate_decl_missingno(); +			}; +		case trace::failed => +			yield bstate_decl_missingno(); +		}; +		defer bstate_decl_finish(decl); + +		for (let i = 0z; i < len(decl.cases); i += 1) { +			const case_ = &decl.cases[i]; +			if (!bstate_decl_cond_validate(&case_.0, blk, &tr)) { +				bstate_decl_cond_finish(case_.0); +				bstate_decl_variant_finish(case_.1); +				delete(decl.cases[i]); +				i -= 1; +			}; +		}; + +		for (let i = 0u32; i < bstates.nstates; i += 1) { +			append(BSTATES_RENDER, load_bstate_render( +				&decl, bstates.state0 + i, &tr)); +		}; +	}; +}; + +fn load_bstate_render( +	decl: *BstateDecl, +	bstate: BstateId, +	tr: *trace::tracer, +) BstateRender = { +	let parts: []BstateRenderPart = []; + +	for (let i = 0z; i < len(decl.cases); i += 1) { +		const case_ = &decl.cases[i]; +		const variant = &case_.1; + +		if (!bstate_decl_cond_test(&case_.0, bstate)) +			continue; + +		if (!decl.multipart && len(parts) != 0) { +			// TODO: print blockstate properties. +			trace::error(tr, +				"Multiple variants match blockstate {}", +				bstate: u32): void; +			parts[0] = missingno_bstate_render_part(); +			break; +		}; + +		const model = match (models_find(variant.model)) { +		case let model: *Model => +			yield model; +		case null => +			trace::error(tr, "Unknown model {}", +				variant.model): void; +			yield models_find(BUILTIN_MISSING) as *Model; +		}; + +		let swizzle: [3]u8 = [0, 1, 2]; // X, Y, Z +		let flip: [3]bool = [false...]; + +		load_bstate_render_rotate( +			variant.x, 2, 1, &swizzle, &flip); +		load_bstate_render_rotate( +			variant.y, 0, 2, &swizzle, &flip); + +		let flags: BstateRenderPartFlags = 0; +		if (flip[0]) flags |= BstateRenderPartFlags::FLIP_X; +		if (flip[1]) flags |= BstateRenderPartFlags::FLIP_Y; +		if (flip[2]) flags |= BstateRenderPartFlags::FLIP_Z; + +		let flip_u = 0u8; +		let flip_v = 0u8; +		let swap_uv = 0u8; +		if (variant.uvlock) { +			// Mojang's uvlock implementation is an incomprehensible +			// clusterfuck, and I'm not convinced this is any better +			// in that regard. :/ +			// this is also incompatible when rotated or flipped +			// textures are used, but those cases never appear in +			// vanilla resources, and honestly just feel like bugs +			// on Mojang's part. + +			let face_rots: [6]u8 = [0...]; + +			face_rots[Dir::WEST] += variant.x; +			face_rots[Dir::EAST] -= variant.x; +			switch (variant.x) { +			case 1 => +				face_rots[Dir::UP] += 2; +				face_rots[Dir::NORTH] += 2; +			case 2 => +				face_rots[Dir::SOUTH] += 2; +				face_rots[Dir::NORTH] += 2; +			case 3 => +				face_rots[Dir::DOWN] += 2; +				face_rots[Dir::NORTH] += 2; +			case => void; +			}; + +			static const round: [4]Dir = +				[Dir::DOWN, Dir::NORTH, Dir::UP, Dir::SOUTH]; +			const down = round[variant.x]; +			const up = round[2 + variant.x & 3]; +			face_rots[down] += variant.y; +			face_rots[up] -= variant.y; + +			for (let j = 0u8; j < 6; j += 1) { +				const mask = 1 << j; +				switch (face_rots[j] & 3) { +				case 1 => +					swap_uv |= mask; +					flip_v |= mask; +				case 2 => +					flip_u |= mask; +					flip_v |= mask; +				case 3 => +					swap_uv |= mask; +					flip_u |= mask; +				case => void; +				}; +			}; +		}; + +		append(parts, BstateRenderPart { +			model = model, +			flags = flags, +			swizzle = swizzle[0] +				| swizzle[1] << 2 +				| swizzle[2] << 4, +			flip_u = flip_u, +			flip_v = flip_v, +			swap_uv = swap_uv, +		}); +	}; + +	if (!decl.multipart && len(parts) == 0) { +		// TODO: print blockstate properties. +		trace::error(tr, "No variants match blockstate {}", +			bstate: u32): void; +		append(parts, missingno_bstate_render_part()); +	}; + +	return BstateRender { +		parts = parts, +	}; +}; + +fn load_bstate_render_rotate( +	angle: u8, +	a: u8, +	b: u8, +	swizzle: *[3]u8, +	flip: *[3]bool, +) void = { +	if (angle & 1 == 1) { +		const tmp = swizzle[a]; +		swizzle[a] = swizzle[b]; +		swizzle[b] = tmp; +		const tmp = flip[a]; +		flip[a] = flip[b]; +		flip[b] = tmp; +	}; + +	flip[a] ^^= (angle == 1 || angle == 2); +	flip[b] ^^= (angle == 3 || angle == 2); +}; + +fn missingno_bstate_render_part() BstateRenderPart = +	BstateRenderPart { +		model = models_find(BUILTIN_MISSING) as *Model, +		flags = 0, +		swizzle = 0b100100, +		flip_u = 0, +		flip_v = 0, +		swap_uv = 0, +	}; + +type BstateDecl = struct { +	multipart: bool, +	cases: [](BstateDeclCond, BstateDeclVariant), +}; + +type BstateDeclCond = ((str, str) | BstateDeclAnd | BstateDeclOr); +type BstateDeclAnd = []BstateDeclCond; +type BstateDeclOr = []BstateDeclCond; +type BstateDeclVariant = struct { +	model: str, +	uvlock: bool, +	// rotations in steps of 90 degrees +	x: u8, +	y: u8, +}; + +fn bstate_decl_missingno() BstateDecl = +	BstateDecl { +		multipart = false, +		cases = alloc([([]: BstateDeclAnd, BstateDeclVariant { +			model = strings::dup(BUILTIN_MISSING), +			... +		})]...), +	}; + +fn bstate_decl_finish(decl: BstateDecl) void = { +	for (let i = 0z; i < len(decl.cases); i += 1) { +		bstate_decl_cond_finish(decl.cases[i].0); +		bstate_decl_variant_finish(decl.cases[i].1); +	}; +	free(decl.cases); +}; + +fn bstate_decl_cond_finish(cond: BstateDeclCond) void = { +	const operands = match (cond) { +	case let ops: BstateDeclAnd => +		yield ops: []BstateDeclCond; +	case let ops: BstateDeclOr => +		yield ops: []BstateDeclCond; +	case let kv: (str, str) => +		free(kv.0); +		free(kv.1); +		return; +	}; +	for (let i = 0z; i < len(operands); i += 1) { +		bstate_decl_cond_finish(operands[i]); +	}; +	free(operands); +}; + +fn bstate_decl_variant_finish(variant: BstateDeclVariant) void = { +	free(variant.model); +}; + +fn bstate_decl_cond_validate( +	cond: *BstateDeclCond, +	blk: BlockId, +	tr: *trace::tracer, +) bool = { +	let ok = true; + +	match (*cond) { +	case let conds: BstateDeclAnd => +		for (let i = 0z; i < len(conds); i += 1) { +			if (!bstate_decl_cond_validate(&conds[i], blk, tr)) { +				ok = false; +			}; +		}; +	case let conds: BstateDeclOr => +		for (let i = 0z; i < len(conds); i += 1) { +			if (!bstate_decl_cond_validate(&conds[i], blk, tr)) { +				ok = false; +			}; +		}; +	case let kv: (str, str) => +		match (block_findprop(blk, kv.0)) { +		case let prop: BlockPropId => +			if (block_findpropval(blk, prop, kv.1) is void) { +				trace::error(tr, +					"Property '{}' has no value '{}'", +					kv.0, kv.1): void; +				ok = false; +			}; +		case void => +			trace::error(tr, +				"Block has no property '{}'", +				kv.0): void; +			ok = false; +		}; +	}; + +	return ok; +}; + +fn bstate_decl_cond_test(cond: *BstateDeclCond, bstate: BstateId) bool = { +	match (*cond) { +	case let conds: BstateDeclAnd => +		for (let i = 0z; i < len(conds); i += 1) { +			if (!bstate_decl_cond_test(&conds[i], bstate)) { +				return false; +			}; +		}; +		return true; +	case let conds: BstateDeclOr => +		for (let i = 0z; i < len(conds); i += 1) { +			if (bstate_decl_cond_test(&conds[i], bstate)) { +				return true; +			}; +		}; +		return false; +	case let kv: (str, str) => +		const blk = bstate_getblock(bstate); +		const prop = block_findprop(blk, kv.0) as BlockPropId; +		const val = bstate_getprop(bstate, blk, prop); +		return block_propvalname(blk, prop, val) == kv.1; +	}; +}; + +fn deser_bstate_decl(de: *dejson::deser) (BstateDecl | dejson::error) = { +	wassert_fields(de, "variants", "multipart")?; + +	const de_variants = dejson::optfield(de, "variants")?; +	const de_multipart = dejson::optfield(de, "multipart")?; + +	if (de_variants is void && de_multipart is void) +		return dejson::fail(de, +			`One of the keys "variants" and "multipart" must be present`); + +	if (de_variants is dejson::deser) { +		if (de_multipart is dejson::deser) +			return dejson::fail(de, +				`Can't specify both "variants" and "multipart"`); + +		return BstateDecl { +			multipart = false, +			cases = deser_bstate_decl_variants( +				&(de_variants as dejson::deser))?, +		}; +	} else { +		return BstateDecl { +			multipart = true, +			cases = deser_bstate_decl_multipart( +				&(de_multipart as dejson::deser))?, +		}; +	}; +}; + +fn deser_bstate_decl_variants(de: *dejson::deser) +		([](BstateDeclCond, BstateDeclVariant) | dejson::error) = { +	let success = false; + +	let cases: [](BstateDeclCond, BstateDeclVariant) = +		alloc([], dejson::count(de)?); +	defer if (!success) free(cases); +	defer if (!success) for (let i = 0z; i < len(cases); i += 1) { +		bstate_decl_cond_finish(cases[i].0); +		bstate_decl_variant_finish(cases[i].1); +	}; + +	// TODO: this is reliant on hash table order, so it's probably incorrect +	let it = dejson::iter(de)?; +	for (true) match (dejson::next(&it)) { +	case let entry: (str, dejson::deser) => +		let success = false; + +		let conds: []BstateDeclCond = []; +		defer if (!success) +			bstate_decl_cond_finish(conds: BstateDeclAnd); +		// TODO: non-standard format: verify/correct details. +		let tok = strings::tokenize(entry.0, ","); +		for (true) match (strings::next_token(&tok)) { +		case let s: str => +			const (k, v) = if (strings::contains(s, "=")) { +				yield strings::cut(s, "="); +			} else { +				yield ("", ""); +			}; +			if (len(k) == 0 || len(v) == 0) +				return dejson::fail(&entry.1, +					"Invalid key-value pair"); +			append(conds, (strings::dup(k), strings::dup(v))); +		case done => break; +		}; +		const cond = conds: BstateDeclAnd; + +		const variant = deser_bstate_decl_variant(&entry.1)?; + +		success = true; +		static append(cases, (cond, variant)); +	case void => break; +	}; + +	success = true; +	return cases; +}; + +fn deser_bstate_decl_multipart(de: *dejson::deser) +		([](BstateDeclCond, BstateDeclVariant) | dejson::error) = { +	let success = false; + +	const ncases = dejson::length(de)?; + +	let cases: [](BstateDeclCond, BstateDeclVariant) = alloc([], ncases); +	defer if (!success) free(cases); +	defer if (!success) for (let i = 0z; i < len(cases); i += 1) { +		bstate_decl_cond_finish(cases[i].0); +		bstate_decl_variant_finish(cases[i].1); +	}; + +	for (let i = 0z; i < ncases; i += 1) { +		let success = false; + +		const de_case = dejson::index(de, i)?; +		wassert_fields(&de_case, "when", "apply")?; +		const cond: BstateDeclCond = match ( +			dejson::optfield(&de_case, "when")?) { +		case let de_when: dejson::deser => +			yield deser_bstate_decl_cond(&de_when)?; +		case void => +			yield []: BstateDeclAnd; +		}; +		defer if (!success) bstate_decl_cond_finish(cond); + +		const variant = deser_bstate_decl_variant( +			&dejson::field(&de_case, "apply")?)?; + +		success = true; +		static append(cases, (cond, variant)); +	}; + +	success = true; +	return cases; +}; + +fn deser_bstate_decl_cond(de: *dejson::deser) +		(BstateDeclCond | dejson::error) = { +	let success = false; + +	const de_and = dejson::optfield(de, "AND")?; +	const de_or = dejson::optfield(de, "OR")?; + +	if (de_and is dejson::deser || de_or is dejson::deser) { +		if (dejson::count(de)? != 1) +			return dejson::fail(de, +				`No other keys allowed when "AND" or "OR" is present`); + +		const de_conds = if (de_and is dejson::deser) +			de_and: dejson::deser +			else de_or: dejson::deser; +		const nconds = dejson::length(&de_conds)?; +		let conds: []BstateDeclCond = alloc([], nconds); +		defer if (!success) +			bstate_decl_cond_finish(conds: BstateDeclAnd); +		for (let i = 0z; i < nconds; i += 1) { +			static append(conds, deser_bstate_decl_cond( +				&dejson::index(&de_conds, i)?)?); +		}; +		const cond = if (de_and is dejson::deser) +			conds: BstateDeclAnd +			else conds: BstateDeclOr; + +		success = true; +		return cond; +	}; + +	let conds: []BstateDeclCond = alloc([], dejson::count(de)?); +	defer if (!success) bstate_decl_cond_finish(conds: BstateDeclAnd); +	let it = dejson::iter(de)?; +	for (true) match (dejson::next(&it)) { +	case let entry: (str, dejson::deser) => +		const value = dejson::string(&entry.1)?; +		// TODO: validate value properly +		if (strings::contains(value, "|")) { +			let conds_: []BstateDeclCond = []; +			let tok = strings::tokenize(value, "|"); +			for (true) match (strings::next_token(&tok)) { +			case let v: str => +				append(conds_, (strings::dup(entry.0), +					strings::dup(v))); +			case done => break; +			}; +			static append(conds, conds_: BstateDeclOr); +		} else { +			static append(conds, +				(strings::dup(entry.0), strings::dup(value))); +		}; +	case void => break; +	}; +	const cond = conds: BstateDeclAnd; + +	success = true; +	return cond; +}; + +fn deser_bstate_decl_variant(de: *dejson::deser) +		(BstateDeclVariant | dejson::error) = { +	const de = match (*de.val) { +	case json::object => +		yield *de; +	case []json::value => +		// TODO: random variants +		yield dejson::index(de, 0)?; +	case => +		return dejson::fail(de, "Expected object or array, found {}", +			dejson::typename(de.val)); +	}; + +	const uvlock = match (dejson::optfield(&de, "uvlock")?) { +	case let de_uvlock: dejson::deser => +		yield dejson::boolean(&de_uvlock)?; +	case void => +		yield false; +	}; +	const x = match (dejson::optfield(&de, "x")?) { +	case let de_x: dejson::deser => +		yield deser_90deg_angle(&de_x)?; +	case void => +		yield 0u8; +	}; +	const y = match (dejson::optfield(&de, "y")?) { +	case let de_y: dejson::deser => +		yield deser_90deg_angle(&de_y)?; +	case void => +		yield 0u8; +	}; +	const model = dejson::string(&dejson::field(&de, "model")?)?; +	const model = ident_qual(model); + +	return BstateDeclVariant { +		model = model, +		uvlock = uvlock, +		x = x, +		y = y, +	}; +}; diff --git a/render_chunks.ha b/render_chunks.ha new file mode 100644 index 0000000..d56d912 --- /dev/null +++ b/render_chunks.ha @@ -0,0 +1,113 @@ +use gl::*; +use glm; +use glw; +use time; +use trace; + +fn render_chunks_frame() void = { +	let nprep = 0; +	for :prepare (let z = 0i32; z < CHUNKS_SIZE; z += 1) +	for (let x = 0i32; x < CHUNKS_SIZE; x += 1) +	for (let y = 0u8; y < CHUNKS_HEIGHT; y += 1) { +		const pos = SectionPos { +			x = CHUNKS_POS.x + x, +			y = CHUNKS_MIN_Y + y: i8, +			z = CHUNKS_POS.z + z, +		}; + +		if (render_chunks_prepare_section(pos)) { +			nprep += 1; +			if (nprep >= 80) break :prepare; +		}; +	}; +}; + +fn render_chunks_prepare_section(pos: SectionPos) bool = { +	const section = match (getsection(pos)) { +	case let section: *Section => +		yield section; +	case null => +		return false; +	}; + +	if (!section.dirty) return false; +	section.dirty = false; + +	const t0 = time::now(time::clock::MONOTONIC); +	const vertices = section_build_geometry(pos); +	const t = time::diff(t0, time::now(time::clock::MONOTONIC)); +	defer free(vertices); + +//	trace::debug(&trace::root, +//		"[ {} {} {} ]: {} vertices / {} bytes / took {} µs / palette {} items", +//		pos.x, pos.y, pos.z, +//		len(vertices), len(vertices) * size(Vertex), +//		t / 1000, section.bstates.palette_size); + +	if (len(vertices) == 0) { +		if (section.vertexbuf != 0) { +			glDeleteBuffers(1, §ion.vertexbuf); +			section.vertexbuf = 0; +		}; +		return true; +	}; + +	if (section.vertexbuf == 0) { +		glGenBuffers(1, §ion.vertexbuf); +	}; + +	glBindBuffer(GL_ARRAY_BUFFER, section.vertexbuf); +	glw::buffer_data( +		GL_ARRAY_BUFFER, +		vertices, size(Vertex), +		GL_STATIC_DRAW, +	); + +	section.vertexcount = len(vertices): i32; + +	return true; +}; + +fn render_chunks_section_destroy(section: *Section) void = { +	glDeleteBuffers(1, §ion.vertexbuf); +}; + +fn render_chunks_render_section(pos: SectionPos) void = { +	const section = match (getsection(pos)) { +	case let section: *Section => +		yield section; +	case null => +		return; +	}; + +	if (section.vertexbuf == 0) return; + +	const origin = [ +		(pos.x - CHUNKS_POS.x): f32 * 16.0, +		pos.y: f32 * 16.0, +		(pos.z - CHUNKS_POS.z): f32 * 16.0, +	]; +	glUniform3fv(1, 1, &origin: *f32); + +	glBindVertexBuffer(0, section.vertexbuf, 0, size(Vertex): i32); +	glDrawArrays(GL_TRIANGLES, 0, section.vertexcount); +}; + +fn render_chunks_render(trans: *glm::m4) void = { +	glUseProgram(SHADER_BLOCKS); +	glBindTexture(GL_TEXTURE_2D, ATLAS_BLOCKS.gl_texture); +	glUniformMatrix4fv(0, 1, 0, trans: *f32); +	glBindVertexArray(VAO_BLOCKS); + +	for (let z = 0i32; z < CHUNKS_SIZE; z += 1) +	for (let x = 0i32; x < CHUNKS_SIZE; x += 1) +	for (let y = 0u8; y < CHUNKS_HEIGHT; y += 1) { +		const pos = SectionPos { +			x = CHUNKS_POS.x + x, +			y = CHUNKS_MIN_Y + y: i8, +			z = CHUNKS_POS.z + z, +		}; + +		render_chunks_render_section(pos); +	}; +}; diff --git a/render_gui.ha b/render_gui.ha new file mode 100644 index 0000000..8bde4ca --- /dev/null +++ b/render_gui.ha @@ -0,0 +1,73 @@ +use gl::*; +use glm; + +type GuiVertex = struct { +	position: [2]f32, +	texcoord: [2]f32, +	color: [4]u8, +}; + +fn render_rect_textured( +	trans: *glm::m4, +	x: f32, y: f32, +	w: f32, h: f32, +	color: [4]u8, +	u: f32, v: f32, +	sprw: f32, sprh: f32, +	tex: uint, texw: u32, texh: u32, +) void = { +	const x0 = x; +	const x1 = x + w; +	const y0 = y; +	const y1 = y + h; +	const u0 = u / texw: f32; +	const u1 = (u + sprw) / texw: f32; +	const v0 = v / texh: f32; +	const v1 = (v + sprh) / texh: f32; +	const quad = [ +		GuiVertex { +			position = [x0, y0], +			texcoord = [u0, v0], +			color = color, +		}, +		GuiVertex { +			position = [x0, y1], +			texcoord = [u0, v1], +			color = color, +		}, +		GuiVertex { +			position = [x1, y1], +			texcoord = [u1, v1], +			color = color, +		}, +		GuiVertex { +			position = [x1, y0], +			texcoord = [u1, v0], +			color = color, +		}, +	]; +	const vertices = [ +		quad[0], quad[1], quad[2], +		quad[2], quad[3], quad[0], +	]; + +	glDisable(GL_CULL_FACE); +	glDisable(GL_DEPTH_TEST); +	glUseProgram(SHADER_GUI); +	glUniformMatrix4fv(0, 1, 0, trans: *f32); +	glBindTexture(GL_TEXTURE_2D, tex); + +	let vbo = 0u; +	glGenBuffers(1, &vbo); +	defer glDeleteBuffers(1, &vbo); +	glBindBuffer(GL_ARRAY_BUFFER, vbo); +	glBufferData(GL_ARRAY_BUFFER, +		(size(GuiVertex) * len(vertices)): uintptr, +		&vertices: *[*]GuiVertex, +		GL_STREAM_DRAW); + +	glBindVertexArray(VAO_GUI); +	glBindVertexBuffer(0, vbo, 0, size(GuiVertex): i32); +	glDrawArrays(GL_TRIANGLES, 0, len(vertices): i32); +	glBindVertexArray(0); +}; diff --git a/resource.ha b/resource.ha new file mode 100644 index 0000000..6b393f2 --- /dev/null +++ b/resource.ha @@ -0,0 +1,191 @@ +use bufio; +use dejson; +use encoding::json; +use errors; +use fs; +use io; +use os; +use path; +use strings; +use trace; + +def MISSINGNO = "minecraft:missingno"; +def BUILTIN_MISSING = "minecraft:builtin/missing"; + +type Pack = struct { +	fs: *fs::fs, +	kind: str, +}; + +fn resource_splitpath(path: str) (str, str, str, str, str) = { +	const (base, path) = strings::cut(path, "/"); +	const (ns, path) = strings::cut(path, "/"); +	const (kind, path) = strings::cut(path, "/"); +	const bnameindex = match (strings::rindex(path, '/')) { +	case let index: size => +		yield index + 1; +	case void => +		yield 0z; +	}; +	const extindex = match (strings::rindex( +		strings::sub(path, bnameindex, strings::end), '.')) { +	case let index: size => +		yield bnameindex + index; +	case void => +		yield len(path); +	}; +	const name = strings::sub(path, 0, extindex); +	const ext = strings::sub(path, extindex, strings::end); +	return (base, ns, kind, name, ext); +}; + +fn resource_open( +	pack: *Pack, +	kind: str, +	ident: str, +	ext: str, +	tr: *trace::tracer, +) (io::handle | trace::failed) = { +	const (ns, name) = ident_split(ident); +	const fname = strings::concat(name, ext); +	defer free(fname); +	let path = path::init()!; +	if (path::set(&path, pack.kind, ns, kind, fname) is path::too_long) { +		return trace::error(tr, "Path too long"); +	}; +	const path = path::string(&path); + +	match (fs::open(pack.fs, path, fs::flag::RDONLY)) { +	case let f: io::handle => +		return f; +	case let err: fs::error => +		return trace::error(tr, "open: {}", fs::strerror(err)); +	}; +}; + +fn resource_load_json( +	pack: *Pack, +	kind: str, +	ident: str, +	ext: str, +	tr: *trace::tracer, +) (json::value | trace::failed) = { +	const f = resource_open(pack, kind, ident, ext, tr)?; + +	let rbuf: [os::BUFSZ]u8 = [0...]; +	let buf = bufio::init(f, rbuf, []); + +	const json = match (json::load(&buf)) { +	case let json: json::value => +		yield json; +	case let err: json::error => +		io::close(f): void; +		return trace::error(tr, "Invalid JSON: {}", +			json::strerror(err)); +	}; + +	match (io::close(f)) { +	case void => void; +	case let err: io::error => +		json::finish(json); +		return trace::error(tr, "close: {}", io::strerror(err)); +	}; + +	return json; +}; + +fn resource_search( +	pack: *Pack, +	kind: str, +	exts: str... +) [](str, str) = { +	const tr = trace::ctx(&trace::root, "resource search"); + +	let out: [](str, str) = []; +	let path = path::init()!; + +	const it = match (fs::iter(pack.fs, pack.kind)) { +	case let x: *fs::iterator => +		yield x; +	case let err: fs::error => +		trace::error(&tr, "{}: fs::iter: {}", +			pack.kind, fs::strerror(err)): void; +		return out; +	}; +	defer fs::finish(it); +	for (true) match (fs::next(it)) { +	case let ent: fs::dirent => +		if (!fs::isdir(ent.ftype)) continue; +		if (strings::hasprefix(ent.name, ".")) continue; +		if (path::set(&path, pack.kind, ent.name, kind) +				is path::too_long) { + +			trace::error(&tr, "{}/{}/{}: Path too long", +				pack.kind, ent.name, kind): void; +			continue; +		}; +		resource_search_ns(pack, &out, path::string(&path), &tr, exts...); +	case done => break; +	}; + +	return out; +}; + +fn resource_search_ns( +	pack: *Pack, +	out: *[](str, str), +	parent: str, +	tr: *trace::tracer, +	exts: str... +) void = { +	let path = path::init()!; + +	const it = match (fs::iter(pack.fs, parent)) { +	case let x: *fs::iterator => +		yield x; +	case errors::noentry => +		return; +	case let err: fs::error => +		trace::error(tr, "{}: fs::iter: {}", +			parent, fs::strerror(err)): void; +		return; +	}; +	defer fs::finish(it); +	for (true) match (fs::next(it)) { +	case let ent: fs::dirent => +		if (strings::hasprefix(ent.name, ".")) continue; +		if (path::set(&path, parent, ent.name) is path::too_long) { +			trace::error(tr, "{}/{}: Path too long", +				parent, ent.name): void; +			continue; +		}; +		const path = path::string(&path); +		if (fs::isdir(ent.ftype)) { +			resource_search_ns(pack, out, path, tr, exts...); +		} else if (fs::isfile(ent.ftype)) { +			const (_, ns, _, name, ext) = +				resource_splitpath(path); +			for (let i = 0z; i < len(exts); i += 1) { +				if (ext == exts[i]) { +					const ident = ident_make(ns, name); +					// yes, this borrow from input is +					// intentional. needs to be documented +					// later. +					append(out, (ident, exts[i])); +					break; +				}; +			}; +		}; +	case done => break; +	}; +}; + +fn wassert_fields(de: *dejson::deser, names: str...) (void | dejson::error) = { +	dejson::object(de)?; +	match (dejson::assert_fields(de, names...)) { +	case let err: dejson::error => +		defer free(err); +		trace::warn(&trace::root, "{}", err); +	case void => void; +	}; +}; diff --git a/scripts/gen_blocks b/scripts/gen_blocks new file mode 100755 index 0000000..08bc64a --- /dev/null +++ b/scripts/gen_blocks @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +import json +import os +import sys + + +reportsdir = sys.argv[1] +with open(os.path.join(reportsdir, "blocks.json")) as f: +    blocks = json.load(f) + +nstates = 0 +for blkname, block in blocks.items(): +    nstates += len(block["states"]) +bstates = [None] * nstates + +props = set() +valueses = set() + +for blkname, block in blocks.items(): +    for propname, values in blocks[blkname].get("properties", {}).items(): +        props.add(propname) +        valueses.add(tuple(values)) + +    for state in block["states"]: +        bstates[state["id"]] = blkname + +print("// generated by scripts/gen_blocks") +print() +print("fn register_blocks() void = {") + +for propname in props: +    print(f"\tstatic const p_{propname} = {json.dumps(propname)};") + +print() + +for values in valueses: +    init = ", ".join(f"{json.dumps(v)}" for v in values) +    print(f"\tstatic const v_{'_'.join(values)} = [{init}];") + +lastblk = None +for i, blkname in enumerate(bstates): +    if blkname == lastblk: +        continue + +    print() + +    print(f"\tconst blk = blocks_register({json.dumps(blkname)}); // {i}") +    props = list(blocks[blkname].get("properties", {}).items()) +    props.sort(key=lambda p: p[0], reverse=True); +    for propname, values in props: +        print(f"\tblock_addprop(blk, p_{propname}, v_{'_'.join(values)});") + +    lastblk = blkname + +print("};") diff --git a/sdl2/COPYING b/sdl2/COPYING new file mode 100644 index 0000000..1ad757e --- /dev/null +++ b/sdl2/COPYING @@ -0,0 +1,371 @@ +sample.ogg: lancelottjones CC-BY 3.0  + +hare-sdl2: + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" +    means each individual or legal entity that creates, contributes to +    the creation of, or owns Covered Software. + +1.2. "Contributor Version" +    means the combination of the Contributions of others (if any) used +    by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" +    means Covered Software of a particular Contributor. + +1.4. "Covered Software" +    means Source Code Form to which the initial Contributor has attached +    the notice in Exhibit A, the Executable Form of such Source Code +    Form, and Modifications of such Source Code Form, in each case +    including portions thereof. + +1.5. "Incompatible With Secondary Licenses" +    means + +    (a) that the initial Contributor has attached the notice described +        in Exhibit B to the Covered Software; or + +    (b) that the Covered Software was made available under the terms of +        version 1.1 or earlier of the License, but not also under the +        terms of a Secondary License. + +1.6. "Executable Form" +    means any form of the work other than Source Code Form. + +1.7. "Larger Work" +    means a work that combines Covered Software with other material, in  +    a separate file or files, that is not Covered Software. + +1.8. "License" +    means this document. + +1.9. "Licensable" +    means having the right to grant, to the maximum extent possible, +    whether at the time of the initial grant or subsequently, any and +    all of the rights conveyed by this License. + +1.10. "Modifications" +    means any of the following: + +    (a) any file in Source Code Form that results from an addition to, +        deletion from, or modification of the contents of Covered +        Software; or + +    (b) any new file in Source Code Form that contains any Covered +        Software. + +1.11. "Patent Claims" of a Contributor +    means any patent claim(s), including without limitation, method, +    process, and apparatus claims, in any patent Licensable by such +    Contributor that would be infringed, but for the grant of the +    License, by the making, using, selling, offering for sale, having +    made, import, or transfer of either its Contributions or its +    Contributor Version. + +1.12. "Secondary License" +    means either the GNU General Public License, Version 2.0, the GNU +    Lesser General Public License, Version 2.1, the GNU Affero General +    Public License, Version 3.0, or any later versions of those +    licenses. + +1.13. "Source Code Form" +    means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") +    means an individual or a legal entity exercising rights under this +    License. For legal entities, "You" includes any entity that +    controls, is controlled by, or is under common control with You. For +    purposes of this definition, "control" means (a) the power, direct +    or indirect, to cause the direction or management of such entity, +    whether by contract or otherwise, or (b) ownership of more than +    fifty percent (50%) of the outstanding shares or beneficial +    ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) +    Licensable by such Contributor to use, reproduce, make available, +    modify, display, perform, distribute, and otherwise exploit its +    Contributions, either on an unmodified basis, with Modifications, or +    as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer +    for sale, have made, import, and otherwise transfer either its +    Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; +    or + +(b) for infringements caused by: (i) Your and any other third party's +    modifications of Covered Software, or (ii) the combination of its +    Contributions with other software (except as part of its Contributor +    Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of +    its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code +    Form, as described in Section 3.1, and You must inform recipients of +    the Executable Form how they can obtain a copy of such Source Code +    Form by reasonable means in a timely manner, at a charge no more +    than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this +    License, or sublicense it under different terms, provided that the +    license for the Executable Form does not attempt to limit or alter +    the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +*                                                                      * +*  6. Disclaimer of Warranty                                           * +*  -------------------------                                           * +*                                                                      * +*  Covered Software is provided under this License on an "as is"       * +*  basis, without warranty of any kind, either expressed, implied, or  * +*  statutory, including, without limitation, warranties that the       * +*  Covered Software is free of defects, merchantable, fit for a        * +*  particular purpose or non-infringing. The entire risk as to the     * +*  quality and performance of the Covered Software is with You.        * +*  Should any Covered Software prove defective in any respect, You     * +*  (not any Contributor) assume the cost of any necessary servicing,   * +*  repair, or correction. This disclaimer of warranty constitutes an   * +*  essential part of this License. No use of any Covered Software is   * +*  authorized under this License except under this disclaimer.         * +*                                                                      * +************************************************************************ + +************************************************************************ +*                                                                      * +*  7. Limitation of Liability                                          * +*  --------------------------                                          * +*                                                                      * +*  Under no circumstances and under no legal theory, whether tort      * +*  (including negligence), contract, or otherwise, shall any           * +*  Contributor, or anyone who distributes Covered Software as          * +*  permitted above, be liable to You for any direct, indirect,         * +*  special, incidental, or consequential damages of any character      * +*  including, without limitation, damages for lost profits, loss of    * +*  goodwill, work stoppage, computer failure or malfunction, or any    * +*  and all other commercial damages or losses, even if such party      * +*  shall have been informed of the possibility of such damages. This   * +*  limitation of liability shall not apply to liability for death or   * +*  personal injury resulting from such party's negligence to the       * +*  extent applicable law prohibits such limitation. Some               * +*  jurisdictions do not allow the exclusion or limitation of           * +*  incidental or consequential damages, so this exclusion and          * +*  limitation may not apply to You.                                    * +*                                                                      * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + +  This Source Code Form is subject to the terms of the Mozilla Public +  License, v. 2.0. If a copy of the MPL was not distributed with this +  file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. diff --git a/sdl2/audio.ha b/sdl2/audio.ha new file mode 100644 index 0000000..1b78880 --- /dev/null +++ b/sdl2/audio.ha @@ -0,0 +1,31 @@ +// Audio format flags. +// +// Current representation (unspecified bits are always zero): +// +// 	++-----------------------sample is signed if set +// 	|| +// 	||       ++-----------sample is bigendian if set +// 	||       || +// 	||       ||          ++---sample is float if set +// 	||       ||          || +// 	||       ||          || +---sample bit size---+ +// 	||       ||          || |                     | +// 	15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 +export type SDL_AudioFormat = u16; + +// Unsigned 8-bit samples +export def AUDIO_U8: SDL_AudioFormat = 0x0008; +// Signed 8-bit samples +export def AUDIO_S8: SDL_AudioFormat = 0x8008; +// Unsigned 16-bit samples, little-endian +export def AUDIO_U16LSB: SDL_AudioFormat = 0x0010; +// Signed 16-bit samples, little-endian +export def AUDIO_S16LSB: SDL_AudioFormat = 0x8010; +// Unsigned 16-bit samples, big-endian +export def AUDIO_U16MSB: SDL_AudioFormat = 0x1010; +// Signed 16-bit samples, big-endian +export def AUDIO_S16MSB: SDL_AudioFormat = 0x9010; +// Unsigned 16-bit samples +export def AUDIO_U16: SDL_AudioFormat = AUDIO_U16LSB; +// Signed 16-bit samples +export def AUDIO_S16: SDL_AudioFormat = AUDIO_S16LSB; diff --git a/sdl2/blendmode.ha b/sdl2/blendmode.ha new file mode 100644 index 0000000..25acab6 --- /dev/null +++ b/sdl2/blendmode.ha @@ -0,0 +1,11 @@ +// TODO: Flesh me out + +// The blend mode used in SDL_RenderCopy() and drawing operations. +export type SDL_BlendMode = enum { +	NONE = 0x00000000, +	BLEND = 0x00000001, +	ADD = 0x00000002, +	MOD = 0x00000004, +	MUL = 0x00000008, +	INVALID = 0x7FFFFFFF +}; diff --git a/sdl2/errors.ha b/sdl2/errors.ha new file mode 100644 index 0000000..a848667 --- /dev/null +++ b/sdl2/errors.ha @@ -0,0 +1,31 @@ +use types::c; + +// Returned when an error occurs in an SDL function. +export type error = !str; + +// Converts an SDL error into a human-friendly string. +export fn strerror(err: error) str = { +	return err: str; +}; + +@symbol("SDL_GetError") fn SDL_GetError() const *c::char; + +export fn wrapvoid(ret: int) (void | error) = { +	wrapint(ret)?; +}; + +export fn wrapint(ret: int) (int | error) = { +	if (ret < 0) { +		return c::tostr(SDL_GetError()): error; +	}; +	return ret; +}; + +export fn wrapptr(ret: nullable *opaque) (*opaque | error) = { +	match (ret) { +	case let v: *opaque => +		return v; +	case null => +		return c::tostr(SDL_GetError()): error; +	}; +}; diff --git a/sdl2/events.ha b/sdl2/events.ha new file mode 100644 index 0000000..35b7808 --- /dev/null +++ b/sdl2/events.ha @@ -0,0 +1,494 @@ +use types::c; + +export type SDL_EventType = enum u32 { +	FIRSTEVENT = 0, + +	QUIT = 0x100, + +	APP_TERMINATING, +	APP_LOWMEMORY, +	APP_WILLENTERBACKGROUND, +	APP_DIDENTERBACKGROUND, +	APP_WILLENTERFOREGROUND, +	APP_DIDENTERFOREGROUND, + +	DISPLAYEVENT = 0x150, + +	WINDOWEVENT = 0x200, +	SYSWMEVENT, + +	KEYDOWN = 0x300, +	KEYUP, +	TEXTEDITING, +	TEXTINPUT, +	KEYMAPCHANGED, + +	MOUSEMOTION = 0x400, +	MOUSEBUTTONDOWN, +	MOUSEBUTTONUP, +	MOUSEWHEEL, + +	JOYAXISMOTION = 0x600, +	JOYBALLMOTION, +	JOYHATMOTION, +	JOYBUTTONDOWN, +	JOYBUTTONUP, +	JOYDEVICEADDED, +	JOYDEVICEREMOVED, + +	CONTROLLERAXISMOTION = 0x650, +	CONTROLLERBUTTONDOWN, +	CONTROLLERBUTTONUP, +	CONTROLLERDEVICEADDED, +	CONTROLLERDEVICEREMOVED, +	CONTROLLERDEVICEREMAPPED, + +	FINGERDOWN = 0x700, +	FINGERUP, +	FINGERMOTION, + +	DOLLARGESTURE = 0x800, +	DOLLARRECORD, +	MULTIGESTURE, + +	CLIPBOARDUPDATE = 0x900, + +	DROPFILE = 0x1000, +	DROPTEXT, +	DROPBEGIN, +	DROPCOMPLETE, + +	AUDIODEVICEADDED = 0x1100, +	AUDIODEVICEREMOVED, + +	SENSORUPDATE = 0x1200, + +	RENDER_TARGETS_RESET = 0x2000, +	RENDER_DEVICE_RESET, + +	USEREVENT = 0x8000, + +	LASTEVENT = 0xFFFF +}; + +// Fields shared by every event +export type SDL_CommonEvent = struct { +	event_type: SDL_EventType, +	timestamp: u32, +}; + +// Display state change event data (event.display.*) +export type SDL_DisplayEvent = struct { +	SDL_CommonEvent, +	display: u32, +	event: u8, +	padding1: u8, +	padding2: u8, +	padding3: u8, +	data1: i32, +}; + +// Event subtype for window events +export type SDL_WindowEventID = enum u8 { +	NONE, +	SHOWN, +	HIDDEN, +	EXPOSED, +	MOVED, +	RESIZED, +	SIZE_CHANGED, +	MINIMIZED, +	MAXIMIZED, +	RESTORED, +	ENTER, +	LEAVE, +	FOCUS_GAINED, +	FOCUS_LOST, +	CLOSE, +	TAKE_FOCUS, +	HIT_TEST, +	ICCPROF_CHANGED, +	DISPLAY_CHANGED +}; + +// Window state change event data (event.window.*) +export type SDL_WindowEvent = struct { +	SDL_CommonEvent, +	window_id: u32, +	event: SDL_WindowEventID, +	padding1: u8, +	padding2: u8, +	padding3: u8, +	data1: i32, +	data2: i32, +}; + +// Keyboard button event structure (event.key.*) +export type SDL_KeyboardEvent = struct { +	SDL_CommonEvent, +	window_id: u32, +	state: u8, +	repeat: u8, +	padding2: u8, +	padding3: u8, +	keysym: SDL_Keysym, +}; + +// Size of the [[SDL_TextEditingEvent]] 'text' field. +export def TEXTEDITINGEVENT_TEXT_SIZE: size = 32; + +// Keyboard text editing event structure (event.edit.*) +export type SDL_TextEditingEvent = struct { +	SDL_CommonEvent, +	window_id: u32, +	text: [TEXTEDITINGEVENT_TEXT_SIZE]c::char, +	start: i32, +	length: i32, +}; + +// Size of the [[SDL_TextInputEvent]] 'text' field. +export def TEXTINPUTEVENT_TEXT_SIZE: size = 32; + +// Keyboard text input event structure (event.text.*) +export type SDL_TextInputEvent = struct { +	SDL_CommonEvent, +	window_id: u32, +	text: [TEXTINPUTEVENT_TEXT_SIZE]c::char, +}; + +// Mouse motion event structure (event.motion.*) +export type SDL_MouseMotionEvent = struct { +	SDL_CommonEvent, +	window_id: u32, +	which: u32, +	state: u32, +	x: i32, +	y: i32, +	xrel: i32, +	yrel: i32, +}; + +// Mouse button event structure (event.button.*) +export type SDL_MouseButtonEvent = struct { +	SDL_CommonEvent, +	window_id: u32, +	which: u32, +	button: u8, +	state: u8, +	clicks: u8, +	padding1: u8, +	x: i32, +	y: i32, +}; + +// Mouse wheel event structure (event.wheel.*) +export type SDL_MouseWheelEvent = struct { +	SDL_CommonEvent, +	window_id: u32, +	which: u32, +	x: i32, +	y: i32, +	direction: u32, +}; + +// Joystick axis motion event structure (event.jaxis.*) +export type SDL_JoyAxisEvent = struct { +	SDL_CommonEvent, +	which: i32, // TODO: Rig me up with the JoystickID type +	axis: u8, +	padding1: u8, +	padding2: u8, +	padding3: u8, +	value: i16, +	padding4: u16, +}; + +// Joystick trackball motion event structure (event.jball.*) +export type SDL_JoyBallEvent = struct { +	SDL_CommonEvent, +	which: i32, // TODO: Rig me up with the JoystickID type +	ball: u8, +	padding1: u8, +	padding2: u8, +	padding3: u8, +	xrel: i16, +	yrel: i16, +}; + +// Joystick hat position change event structure (event.jhat.*) +export type SDL_JoyHatEvent = struct { +	SDL_CommonEvent, +	which: i32, // TODO: Rig me up with the JoystickID type +	hat: u8, +	value: u8, // TODO: Rig me up with HAT_UP et al +	padding1: u8, +	padding2: u8, +}; + +// Joystick button event structure (event.jbutton.*) +export type SDL_JoyButtonEvent = struct { +	SDL_CommonEvent, +	which: i32, // TODO: Rig me up with the JoystickID type +	button: u8, +	state: u8, +	padding1: u8, +	padding2: u8, +}; + +// Joystick device event structure (event.jdevice.*) +export type SDL_JoyDeviceEvent = struct { +	SDL_CommonEvent, +	which: i32, +}; + +// Game controller axis motion event structure (event.caxis.*) +export type SDL_ControllerAxisEvent = struct { +	SDL_CommonEvent, +	which: i32, // TODO +	axis: SDL_GameControllerAxis, +	padding1: u8, +	padding2: u8, +	padding3: u8, +	value: i16, +	padding4: u16, +}; + +// Game controller button event structure (event.cbutton.*) +export type SDL_ControllerButtonEvent = struct { +	SDL_CommonEvent, +	which: i32, +	button: u8, +	state: u8, +	padding1: u8, +	padding2: u8, +}; + +// Controller device event structure (event.cdevice.*) +export type SDL_ControllerDeviceEvent = struct { +	SDL_CommonEvent, +	which: i32, +}; + +// Audio device event structure (event.adevice.*) +export type SDL_AudioDeviceEvent = struct { +	SDL_CommonEvent, +	which: u32, +	iscapture: u8, +	padding1: u8, +	padding2: u8, +	padding3: u8, +}; + +// Touch finger event structure (event.tfinger.*) +export type SDL_TouchFingerEvent = struct { +	SDL_CommonEvent, +	touch_id: i64, // TODO +	finger_id: i64, // TODO +	x: f32, +	y: f32, +	dx: f32, +	dy: f32, +	pressure: f32, +}; + +// Multiple Finger Gesture Event (event.mgesture.*) +export type SDL_MultiGestureEvent = struct { +	SDL_CommonEvent, +	touch_id: i64, // TODO +	dtheta: f32, +	ddist: f32, +	x: f32, +	y: f32, +	num_fingers: u16, +	padding: u16, +}; + +// Dollar Gesture Event (event.dgesture.*) +export type SDL_DollarGestureEvent = struct { +	SDL_CommonEvent, +	touch_id: i64, // TODO +	gesture_id: i64, // TODO +	num_fingers: u32, +	error: f32, +	x: f32, +	y: f32, +}; + +// An event used to request a file open by the system (event.drop.*) +// This event is enabled by default, you can disable it with [[eventstate]]. +// If this event is enabled, you must free the filename in the event. +export type SDL_DropEvent = struct { +	SDL_CommonEvent, +	file: *c::char, +	window_id: u32, +}; + +// Sensor event structure (event.sensor.*) +export type SDL_SensorEvent = struct { +	SDL_CommonEvent, +	which: i32, +	data: [6]f32, +}; + +// The "quit requested" event +export type SDL_QuitEvent = struct { +	SDL_CommonEvent, +}; + +// OS Specific event +export type SDL_OSEvent = struct { +	SDL_CommonEvent, +}; + +// A user-defined event type (event.user.*) +export type SDL_UserEvent = struct { +	SDL_CommonEvent, +	window_id: u32, +	code: i32, +	data1: *opaque, +	data2: *opaque, +}; + +// A video driver dependent system event (event.syswm.*) +// This event is disabled by default, you can enable it with [[eventstate]]. +export type SDL_SysWMEvent = struct { +	SDL_CommonEvent, +	msg: *opaque, // TODO +}; + +// General event structure +export type event = union { +	event_type: SDL_EventType, +	common: SDL_CommonEvent, +	display: SDL_DisplayEvent, +	window: SDL_WindowEvent, +	key: SDL_KeyboardEvent, +	edit: SDL_TextEditingEvent, +	text: SDL_TextInputEvent, +	motion: SDL_MouseMotionEvent, +	button: SDL_MouseButtonEvent, +	wheel: SDL_MouseWheelEvent, +	jaxis: SDL_JoyAxisEvent, +	jball: SDL_JoyBallEvent, +	jhat: SDL_JoyHatEvent, +	jbutton: SDL_JoyButtonEvent, +	jdevice: SDL_JoyDeviceEvent, +	caxis: SDL_ControllerAxisEvent, +	cbutton: SDL_ControllerButtonEvent, +	cdevice: SDL_ControllerDeviceEvent, +	adevice: SDL_AudioDeviceEvent, +	sensor: SDL_SensorEvent, +	quit: SDL_QuitEvent, +	user: SDL_UserEvent, +	syswm: SDL_SysWMEvent, +	tfinger: SDL_TouchFingerEvent, +	mgesture: SDL_MultiGestureEvent, +	dgestures: SDL_DollarGestureEvent, +	drop: SDL_DropEvent, + +	padding: [56]u8, +}; + +// Pumps the event loop, gathering events from the input devices. +// +// This function updates the event queue and internal input device state. +// +// This should only be run in the thread that sets the video mode. +export @symbol("SDL_PumpEvents") fn SDL_PumpEvents() void; + +export type eventaction = enum { +	ADDEVENT, +	PEEKEVENT, +	GETEVENT, +}; + +@symbol("SDL_PeepEvents") fn _peep_events(events: *event, numevents: int, +	action: eventaction, mintype: SDL_EventType, maxtype: SDL_EventType) int; + +// Checks the event queue for messages and optionally returns them. +// +// If 'action' is ADDEVENT, up to 'numevents' events will be added to the back +// of the event queue. +// +// If 'action' is PEEKEVENT, up to 'numevents' events at the front of the event +// queue, within the specified minimum and maximum type, will be returned and +// will not be removed from the queue. +// +// If 'action' is GETEVENT, up to 'numevents' events at the front of the event +// queue, within the specified minimum and maximum type, will be returned and +// will be removed from the queue. +// +// This function is thread-safe. +export fn SDL_PeepEvents( +	events: *event, +	numevents: int, +	action: eventaction, +	mintype: SDL_EventType, +	maxtype: SDL_EventType, +) (int | error) = { +	return wrapint(_peep_events(events, numevents, action, mintype, maxtype)); +}; + +// Checks to see if certain event types are in the event queue. +export @symbol("SDL_HasEvent") fn SDL_HasEvent(SDL_EventType: SDL_EventType) bool; + +// Checks to see if certain event types are in the event queue. +export @symbol("SDL_HasEvents") fn SDL_HasEvents(mintype: SDL_EventType, maxtype: SDL_EventType) bool; + +// This function clears events from the event queue +// This function only affects currently queued events. If you want to make +// sure that all pending OS events are flushed, you can call SDL_PumpEvents() +// on the main thread immediately before the flush call. +export @symbol("SDL_FlushEvent") fn flush_event(SDL_EventType: SDL_EventType) void; + +// This function clears events from the event queue +// This function only affects currently queued events. If you want to make +// sure that all pending OS events are flushed, you can call SDL_PumpEvents() +// on the main thread immediately before the flush call. +export @symbol("SDL_FlushEvents") fn SDL_FlushEvents(mintype: SDL_EventType, maxtype: SDL_EventType) void; + +@symbol("SDL_PollEvent") fn _poll_event(event: nullable *event) int; + +// Polls for currently pending events. +// +// Returns 1 if there are any pending events, or 0 if there are none available. +// +// If 'event' is not null, the next event is removed from the queue and stored +// in that area. +export fn SDL_PollEvent(event: nullable *event) (int | error) = { +	return wrapint(_poll_event(event)); +}; + +@symbol("SDL_WaitEvent") fn _wait_event(event: nullable *event) int; + +// Waits indefinitely for the next available event. +// +// If 'event' is not null, the next event is removed from the queue and stored +// in that area. +export fn SDL_WaitEvent(event: nullable *event) (void | error) = { +	return wrapvoid(_wait_event(event)); +}; + +@symbol("SDL_WaitEventTimeout") fn _wait_event_timeout( +	event: nullable *event, timeout: int) int; + +// Waits until the specified timeout (in milliseconds) for the next available event. +// +// If 'event' is not null, the next event is removed from the queue and stored +// in that area. The 'timeout' is the time (in milliseconds) to wait for next +// event. +export fn SDL_WaitEventTimeout( +	event: nullable *event, +	timeout: int, +) (void | error) = { +	return wrapvoid(_wait_event_timeout(event, timeout)); +}; + +@symbol("SDL_PushEvent") fn _push_event(event: *event) int; + +// Add an event to the event queue. +export fn SDL_PushEvent(event: *event) (void | error) = { +	return wrapvoid(_push_event(event)); +}; + +// TODO: Finish rigging up other SDL_events.h bits diff --git a/sdl2/gamecontroller.ha b/sdl2/gamecontroller.ha new file mode 100644 index 0000000..4cab9ce --- /dev/null +++ b/sdl2/gamecontroller.ha @@ -0,0 +1,99 @@ +// TODO: Flesh me out + +// The SDL_GameController structure used to identify an SDL game controller. +// (Opaque) +export type SDL_GameController = opaque; + +// The list of axes available from a controller +// +// Thumbstick axis values range from [[SDL_JOYSTICK_AXIS_MIN]] to +// [[SDL_JOYSTICK_AXIS_MAX]], and are centered within ~8000 of zero, though advanced +// UI will allow users to set or autodetect the dead zone, which varies between +// controllers. +// +// Trigger axis values range from 0 to [[SDL_JOYSTICK_AXIS_MAX]]. +export type SDL_GameControllerAxis = enum u8 { +	LEFTX, +	LEFTY, +	RIGHTX, +	RIGHTY, +	TRIGGERLEFT, +	TRIGGERRIGHT, +	INVALID = 255, +}; + +// The list of buttons available from a controller +export type SDL_GameControllerButton = enum u8 { +	INVALID = 255, +	A = 0, +	B, +	X, +	Y, +	BACK, +	GUIDE, +	START, +	LEFTSTICK, +	RIGHTSTICK, +	LEFTSHOULDER, +	RIGHTSHOULDER, +	DPAD_UP, +	DPAD_DOWN, +	DPAD_LEFT, +	DPAD_RIGHT, +	MISC1, +	PADDLE1, +	PADDLE2, +	PADDLE3, +	PADDLE4, +	TOUCHPAD, +}; + +// Check if the given joystick is supported by the game controller interface. +// +// 'joystick_index' is the same as the 'device_index' passed to +// [[joystick_open]]. +// +// Returns true if the given joystick is supported by the game controller +// interface, false if it isn't or it's an invalid index. +export @symbol("SDL_IsGameController") fn SDL_IsGameController( +	joystick_index: int) bool; + +@symbol("SDL_GameControllerOpen") fn _game_controller_open( +	joystick_index: int) nullable *SDL_GameController; + +// Get the SDL_GameController associated with an instance id. +export fn SDL_GameControllerOpen( +	joystick_index: int, +) (*SDL_GameController | error) = { +	return wrapptr(_game_controller_open(joystick_index))?: *SDL_GameController; +}; + +// Close a game controller previously opened with [[game_controller_open]]. +export @symbol("SDL_GameControllerClose") fn SDL_GameControllerClose( +	gamecontroller: *SDL_GameController) void; + +@symbol("SDL_GameControllerRumble") fn _SDL_GameControllerRumble( +	gamecontroller: *SDL_GameController, +	low_frequency_rumble: u16, +	high_frequency_rumble: u16, +	duration_ms: u32) int; + +// Start a rumble effect on a game controller. +// +// Each call to this function cancels any previous rumble effect, and calling +// it with 0 intensity stops any rumbling. +// +// The low-frequency motor is generally on the left, and the high-frequency +// motor is generally on the right. +export fn SDL_GameControllerRumble( +	gamecontroller: *SDL_GameController, +	low_frequency_rumble: u16, +	high_frequency_rumble: u16, +	duration_ms: u32, +) (void | error) = { +	return wrapvoid(_SDL_GameControllerRumble( +		gamecontroller, +		low_frequency_rumble, +		high_frequency_rumble, +		duration_ms)); +}; diff --git a/sdl2/gl.ha b/sdl2/gl.ha new file mode 100644 index 0000000..b609f6c --- /dev/null +++ b/sdl2/gl.ha @@ -0,0 +1,82 @@ +use types::c; + +export type SDL_GLContext = opaque; + +export type SDL_GLprofile = enum int { +	GL_CONTEXT_PROFILE_CORE = 0x0001, +	GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, +	GL_CONTEXT_PROFILE_ES = 0x0004, +}; + +export type SDL_GLcontextFlag = enum int { +	GL_CONTEXT_DEBUG_FLAG = 0x0001, +	GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, +	GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, +	GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008, +}; + +export type SDL_GLattr = enum { +	GL_RED_SIZE, +	GL_GREEN_SIZE, +	GL_BLUE_SIZE, +	GL_ALPHA_SIZE, +	GL_BUFFER_SIZE, +	GL_DOUBLEBUFFER, +	GL_DEPTH_SIZE, +	GL_STENCIL_SIZE, +	GL_ACCUM_RED_SIZE, +	GL_ACCUM_GREEN_SIZE, +	GL_ACCUM_BLUE_SIZE, +	GL_ACCUM_ALPHA_SIZE, +	GL_STEREO, +	GL_MULTISAMPLEBUFFERS, +	GL_MULTISAMPLESAMPLES, +	GL_ACCELERATED_VISUAL, +	GL_RETAINED_BACKING, +	GL_CONTEXT_MAJOR_VERSION, +	GL_CONTEXT_MINOR_VERSION, +	GL_CONTEXT_EGL, +	GL_CONTEXT_FLAGS, +	GL_CONTEXT_PROFILE_MASK, +	GL_SHARE_WITH_CURRENT_CONTEXT, +	GL_FRAMEBUFFER_SRGB_CAPABLE, +	GL_CONTEXT_RELEASE_BEHAVIOR, +	GL_CONTEXT_RESET_NOTIFICATION, +	GL_CONTEXT_NO_ERROR, +}; + +@symbol("SDL_GL_CreateContext") fn _SDL_GL_CreateContext( +	window: *SDL_Window) *SDL_GLContext; + +export fn SDL_GL_CreateContext(window: *SDL_Window) (*SDL_GLContext | error) = { +	return wrapptr(_SDL_GL_CreateContext(window))?: *SDL_GLContext; +}; + +export @symbol("SDL_GL_GetProcAddress") fn SDL_GL_GetProcAddress( +	proc: *const c::char) *opaque; + +@symbol("SDL_GL_SetAttribute") fn _SDL_GL_SetAttribute( +	attr: SDL_GLattr, value: int) int; +@symbol("SDL_GL_GetAttribute") fn _SDL_GL_GetAttribute( +	attr: SDL_GLattr, value: *int) int; + +export fn SDL_GL_SetAttribute(attr: SDL_GLattr, value: int) (void | error) = { +	return wrapvoid(_SDL_GL_SetAttribute(attr, value)); +}; + +export fn SDL_GL_GetAttribute(attr: SDL_GLattr) (int | error) = { +	let value = 0; +	wrapvoid(_SDL_GL_GetAttribute(attr, &value))?; +	return value; +}; + +export @symbol("SDL_GL_SwapWindow") fn SDL_GL_SwapWindow(window: *SDL_Window) void; +export @symbol("SDL_GL_GetSwapInterval") fn SDL_GL_GetSwapInterval() int; +export @symbol("SDL_GL_GetDrawableSize") fn SDL_GL_GetDrawableSize( +	window: *SDL_Window, w: *int, h: *int) void; + +@symbol("SDL_GL_SetSwapInterval") fn _SDL_GL_SetSwapInterval(interval: int) int; + +export fn SDL_GL_SetSwapInterval(interval: int) (void | error) = { +	return wrapvoid(_SDL_GL_SetSwapInterval(interval)); +}; diff --git a/sdl2/image/image.ha b/sdl2/image/image.ha new file mode 100644 index 0000000..32f8f3d --- /dev/null +++ b/sdl2/image/image.ha @@ -0,0 +1,46 @@ +// TODO: Flesh me out +// TODO: SDL_RWops +use sdl2; +use types::c; + +// Flags for [[IMG_Init]]. +export type IMG_InitFlags = enum int { +	NONE = 0, +	JPG = 0x00000001, +	PNG = 0x00000002, +	TIF = 0x00000004, +	WEBP = 0x00000008, +}; + +@symbol("IMG_Init") fn _IMG_Init(flags: IMG_InitFlags) int; + +// Loads dynamic libraries and prepares them for use. Flags should be one or +// more flags from [[IMG_InitFlags]] OR'd together. +export fn IMG_Init(flags: IMG_InitFlags) (void | sdl2::error) = { +	return sdl2::wrapvoid(_IMG_Init(flags)); +}; + +// Unloads libraries loaded with [[IMG_Init]] +export @symbol("IMG_Quit") fn IMG_Quit() void; + +@symbol("IMG_Load") fn _IMG_Load(file: const *c::char) nullable *sdl2::SDL_Surface; + +// Load an image from a file path. +export fn IMG_Load(file: str) (*sdl2::SDL_Surface | sdl2::error) = { +	const file = c::fromstr(file); +	defer free(file); +	return sdl2::wrapptr(_IMG_Load(file))?: *sdl2::SDL_Surface; +}; + +@symbol("IMG_LoadTexture") fn _IMG_LoadTexture(SDL_Renderer: *sdl2::SDL_Renderer, +	file: const *c::char) nullable *sdl2::SDL_Texture; + +// Load an image directly into a render texture. +export fn IMG_LoadTexture( +	SDL_Renderer: *sdl2::SDL_Renderer, +	file: str, +) (*sdl2::SDL_Texture | sdl2::error) = { +	const file = c::fromstr(file); +	defer free(file); +	return sdl2::wrapptr(_IMG_LoadTexture(SDL_Renderer, file))?: *sdl2::SDL_Texture; +}; diff --git a/sdl2/joystick.ha b/sdl2/joystick.ha new file mode 100644 index 0000000..2234aff --- /dev/null +++ b/sdl2/joystick.ha @@ -0,0 +1,12 @@ +// TODO: Flesh me out + +// Minimum value for a joystick axis. +export def SDL_JOYSTICK_AXIS_MIN: i16 = -32768; + +// Minimum value for a joystick axis. +export def SDL_JOYSTICK_AXIS_MAX: i16 = 32767; + +@symbol("SDL_NumJoysticks") fn _SDL_NumJoysticks() int; + +// Returns the number of joysticks attached to the system. +export fn SDL_NumJoysticks() (int | error) = wrapint(_SDL_NumJoysticks()); diff --git a/sdl2/keyboard.ha b/sdl2/keyboard.ha new file mode 100644 index 0000000..8c82184 --- /dev/null +++ b/sdl2/keyboard.ha @@ -0,0 +1,654 @@ +use types::c; + +export type SDL_Scancode = enum uint { +	UNKNOWN = 0, + +	// Usage page 0x07 +	// These values are from usage page 0x07 (USB keyboard page). + +	A = 4, +	B = 5, +	C = 6, +	D = 7, +	E = 8, +	F = 9, +	G = 10, +	H = 11, +	I = 12, +	J = 13, +	K = 14, +	L = 15, +	M = 16, +	N = 17, +	O = 18, +	P = 19, +	Q = 20, +	R = 21, +	S = 22, +	T = 23, +	U = 24, +	V = 25, +	W = 26, +	X = 27, +	Y = 28, +	Z = 29, + +	ONE = 30, +	TWO = 31, +	THREE = 32, +	FOUR = 33, +	FIVE = 34, +	SIX = 35, +	SEVEN = 36, +	EIGHT = 37, +	NINE = 38, +	ZERO = 39, + +	RETURN = 40, +	ESCAPE = 41, +	BACKSPACE = 42, +	TAB = 43, +	SPACE = 44, + +	MINUS = 45, +	EQUALS = 46, +	LEFTBRACKET = 47, +	RIGHTBRACKET = 48, +	// Located at the lower left of the return +	// key on ISO keyboards and at the right end +	// of the QWERTY row on ANSI keyboards. +	// Produces REVERSE SOLIDUS (backslash) and +	// VERTICAL LINE in a US layout, REVERSE +	// SOLIDUS and VERTICAL LINE in a UK Mac +	// layout, NUMBER SIGN and TILDE in a UK +	// Windows layout, DOLLAR SIGN and POUND SIGN +	// in a Swiss German layout, NUMBER SIGN and +	// APOSTROPHE in a German layout, GRAVE +	// ACCENT and POUND SIGN in a French Mac +	// layout, and ASTERISK and MICRO SIGN in a +	// French Windows layout. +	BACKSLASH = 49, +	NONUSHASH = 50, +	// ISO USB keyboards actually use this code +	// instead of 49 for the same key, but all +	// OSes I've seen treat the two codes +	// identically. So, as an implementor, unless +	// your keyboard generates both of those +	// codes and your OS treats them differently, +	// you should generate BACKSLASH +	// instead of this code. As a user, you +	// should not rely on this code because SDL +	// will never generate it with most (all?) +	// keyboards. +	SEMICOLON = 51, +	APOSTROPHE = 52, +	// Located in the top left corner (on both ANSI +	// and ISO keyboards). Produces GRAVE ACCENT and +	// TILDE in a US Windows layout and in US and UK +	// Mac layouts on ANSI keyboards, GRAVE ACCENT +	// and NOT SIGN in a UK Windows layout, SECTION +	// SIGN and PLUS-MINUS SIGN in US and UK Mac +	// layouts on ISO keyboards, SECTION SIGN and +	// DEGREE SIGN in a Swiss German layout (Mac: +	// only on ISO keyboards), CIRCUMFLEX ACCENT and +	// DEGREE SIGN in a German layout (Mac: only on +	// ISO keyboards), SUPERSCRIPT TWO and TILDE in a +	// French Windows layout, COMMERCIAL AT and +	// NUMBER SIGN in a French Mac layout on ISO +	// keyboards, and LESS-THAN SIGN and GREATER-THAN +	// SIGN in a Swiss German, German, or French Mac +	// layout on ANSI keyboards. +	GRAVE = 53, +	COMMA = 54, +	PERIOD = 55, +	SLASH = 56, + +	CAPSLOCK = 57, + +	F1 = 58, +	F2 = 59, +	F3 = 60, +	F4 = 61, +	F5 = 62, +	F6 = 63, +	F7 = 64, +	F8 = 65, +	F9 = 66, +	F10 = 67, +	F11 = 68, +	F12 = 69, + +	PRINTSCREEN = 70, +	SCROLLLOCK = 71, +	PAUSE = 72, +	// insert on PC, help on some Mac keyboards (but does send code 73, +	// not 117) +	INSERT = 73, +	HOME = 74, +	PAGEUP = 75, +	DELETE = 76, +	END = 77, +	PAGEDOWN = 78, +	RIGHT = 79, +	LEFT = 80, +	DOWN = 81, +	UP = 82, + +	NUMLOCKCLEAR = 83, // num lock on PC, clear on Mac keyboards +	KP_DIVIDE = 84, +	KP_MULTIPLY = 85, +	KP_MINUS = 86, +	KP_PLUS = 87, +	KP_ENTER = 88, +	KP_1 = 89, +	KP_2 = 90, +	KP_3 = 91, +	KP_4 = 92, +	KP_5 = 93, +	KP_6 = 94, +	KP_7 = 95, +	KP_8 = 96, +	KP_9 = 97, +	KP_0 = 98, +	KP_PERIOD = 99, + +	// This is the additional key that ISO +	// keyboards have over ANSI ones, +	// located between left shift and Y. +	// Produces GRAVE ACCENT and TILDE in a +	// US or UK Mac layout, REVERSE SOLIDUS +	// (backslash) and VERTICAL LINE in a +	// US or UK Windows layout, and +	// LESS-THAN SIGN and GREATER-THAN SIGN +	// in a Swiss German, German, or French +	// layout. */ +	NONUSBACKSLASH = 100, +	APPLICATION = 101, // windows contextual menu, compose +	// The USB document says this is a status flag, not a physical key - but +	// some Mac keyboards do have a power key. +	POWER = 102, +	KP_EQUALS = 103, +	F13 = 104, +	F14 = 105, +	F15 = 106, +	F16 = 107, +	F17 = 108, +	F18 = 109, +	F19 = 110, +	F20 = 111, +	F21 = 112, +	F22 = 113, +	F23 = 114, +	F24 = 115, +	EXECUTE = 116, +	HELP = 117, +	MENU = 118, +	SELECT = 119, +	STOP = 120, +	AGAIN = 121, // redo +	UNDO = 122, +	CUT = 123, +	COPY = 124, +	PASTE = 125, +	FIND = 126, +	MUTE = 127, +	VOLUMEUP = 128, +	VOLUMEDOWN = 129, +// not sure whether there's a reason to enable these +//	LOCKINGCAPSLOCK = 130, +//	LOCKINGNUMLOCK = 131, +//	LOCKINGSCROLLLOCK = 132, +	KP_COMMA = 133, +	KP_EQUALSAS400 = 134, + +	// used on Asian keyboards, see footnotes in USB doc +	INTERNATIONAL1 = 135, +	INTERNATIONAL2 = 136, +	INTERNATIONAL3 = 137, // Yen +	INTERNATIONAL4 = 138, +	INTERNATIONAL5 = 139, +	INTERNATIONAL6 = 140, +	INTERNATIONAL7 = 141, +	INTERNATIONAL8 = 142, +	INTERNATIONAL9 = 143, +	LANG1 = 144, // Hangul/English toggle +	LANG2 = 145, // Hanja conversion +	LANG3 = 146, // Katakana +	LANG4 = 147, // Hiragana +	LANG5 = 148, // Zenkaku/Hankaku +	LANG6 = 149, // reserved +	LANG7 = 150, // reserved +	LANG8 = 151, // reserved +	LANG9 = 152, // reserved + +	ALTERASE = 153, // Erase-Eaze +	SYSREQ = 154, +	CANCEL = 155, +	CLEAR = 156, +	PRIOR = 157, +	RETURN2 = 158, +	SEPARATOR = 159, +	OUT = 160, +	OPER = 161, +	CLEARAGAIN = 162, +	CRSEL = 163, +	EXSEL = 164, + +	KP_00 = 176, +	KP_000 = 177, +	THOUSANDSSEPARATOR = 178, +	DECIMALSEPARATOR = 179, +	CURRENCYUNIT = 180, +	CURRENCYSUBUNIT = 181, +	KP_LEFTPAREN = 182, +	KP_RIGHTPAREN = 183, +	KP_LEFTBRACE = 184, +	KP_RIGHTBRACE = 185, +	KP_TAB = 186, +	KP_BACKSPACE = 187, +	KP_A = 188, +	KP_B = 189, +	KP_C = 190, +	KP_D = 191, +	KP_E = 192, +	KP_F = 193, +	KP_XOR = 194, +	KP_POWER = 195, +	KP_PERCENT = 196, +	KP_LESS = 197, +	KP_GREATER = 198, +	KP_AMPERSAND = 199, +	KP_DBLAMPERSAND = 200, +	KP_VERTICALBAR = 201, +	KP_DBLVERTICALBAR = 202, +	KP_COLON = 203, +	KP_HASH = 204, +	KP_SPACE = 205, +	KP_AT = 206, +	KP_EXCLAM = 207, +	KP_MEMSTORE = 208, +	KP_MEMRECALL = 209, +	KP_MEMCLEAR = 210, +	KP_MEMADD = 211, +	KP_MEMSUBTRACT = 212, +	KP_MEMMULTIPLY = 213, +	KP_MEMDIVIDE = 214, +	KP_PLUSMINUS = 215, +	KP_CLEAR = 216, +	KP_CLEARENTRY = 217, +	KP_BINARY = 218, +	KP_OCTAL = 219, +	KP_DECIMAL = 220, +	KP_HEXADECIMAL = 221, + +	LCTRL = 224, +	LSHIFT = 225, +	LALT = 226, // alt, option +	LGUI = 227, // windows, command (apple), meta +	RCTRL = 228, +	RSHIFT = 229, +	RALT = 230, // alt gr, option +	RGUI = 231, // windows, command (apple), meta + +	// I'm not sure if this is really not covered by any of the above, but +	// since there's a special KMOD_MODE for it I'm adding it here +	MODE = 257, + +	// Usage page 0x0C +	// These values are mapped from usage page 0x0C (USB consumer page). + +	AUDIONEXT = 258, +	AUDIOPREV = 259, +	AUDIOSTOP = 260, +	AUDIOPLAY = 261, +	AUDIOMUTE = 262, +	MEDIASELECT = 263, +	WWW = 264, +	MAIL = 265, +	CALCULATOR = 266, +	COMPUTER = 267, +	AC_SEARCH = 268, +	AC_HOME = 269, +	AC_BACK = 270, +	AC_FORWARD = 271, +	AC_STOP = 272, +	AC_REFRESH = 273, +	AC_BOOKMARKS = 274, + +	// Walther keys +	// These are values that Christian Walther added (for mac keyboard?). + +	BRIGHTNESSDOWN = 275, +	BRIGHTNESSUP = 276, +	// display mirroring/dual display switch, video mode switch +	DISPLAYSWITCH = 277, +	KBDILLUMTOGGLE = 278, +	KBDILLUMDOWN = 279, +	KBDILLUMUP = 280, +	EJECT = 281, +	SLEEP = 282, + +	APP1 = 283, +	APP2 = 284, + +	// Usage page 0x0C (additional media keys) +	// These values are mapped from usage page 0x0C (USB consumer page). + +	AUDIOREWIND = 285, +	AUDIOFASTFORWARD = 286, + +	// Add any other keys here. + +	// not a key, just marks the number of scancodes for array bounds +	NUM_SCANCODES = 512, +}; + +export type SDL_Keycode = enum uint { +	UNKNOWN = 0, + +	RETURN = '\r', +	ESCAPE = '\x1B', +	BACKSPACE = '\b', +	TAB = '\t', +	SPACE = ' ', +	EXCLAIM = '!', +	QUOTEDBL = '"', +	HASH = '#', +	PERCENT = '%', +	DOLLAR = '$', +	AMPERSAND = '&', +	QUOTE = '\'', +	LEFTPAREN = '(', +	RIGHTPAREN = ')', +	ASTERISK = '*', +	PLUS = '+', +	COMMA = ',', +	MINUS = '-', +	PERIOD = '.', +	SLASH = '/', +	ZERO = '0', +	ONE = '1', +	TWO = '2', +	THREE = '3', +	FOUR = '4', +	FIVE = '5', +	SIX = '6', +	SEVEN = '7', +	EIGHT = '8', +	NINE = '9', +	COLON = ':', +	SEMICOLON = ';', +	LESS = '<', +	EQUALS = '=', +	GREATER = '>', +	QUESTION = '?', +	AT = '@', + +	// Skip uppercase letters + +	LEFTBRACKET = '[', +	BACKSLASH = '\\', +	RIGHTBRACKET = ']', +	CARET = '^', +	UNDERSCORE = '_', +	BACKQUOTE = '`', +	a = 'a', +	b = 'b', +	c = 'c', +	d = 'd', +	e = 'e', +	f = 'f', +	g = 'g', +	h = 'h', +	i = 'i', +	j = 'j', +	k = 'k', +	l = 'l', +	m = 'm', +	n = 'n', +	o = 'o', +	p = 'p', +	q = 'q', +	r = 'r', +	s = 's', +	t = 't', +	u = 'u', +	v = 'v', +	w = 'w', +	x = 'x', +	y = 'y', +	z = 'z', + +	CAPSLOCK = SDL_Scancode::CAPSLOCK | 1: SDL_Scancode << 30: SDL_Scancode, + +	F1 = SDL_Scancode::F1 | 1: SDL_Scancode << 30, +	F2 = SDL_Scancode::F2 | 1: SDL_Scancode << 30, +	F3 = SDL_Scancode::F3 | 1: SDL_Scancode << 30, +	F4 = SDL_Scancode::F4 | 1: SDL_Scancode << 30, +	F5 = SDL_Scancode::F5 | 1: SDL_Scancode << 30, +	F6 = SDL_Scancode::F6 | 1: SDL_Scancode << 30, +	F7 = SDL_Scancode::F7 | 1: SDL_Scancode << 30, +	F8 = SDL_Scancode::F8 | 1: SDL_Scancode << 30, +	F9 = SDL_Scancode::F9 | 1: SDL_Scancode << 30, +	F10 = SDL_Scancode::F10 | 1: SDL_Scancode << 30, +	F11 = SDL_Scancode::F11 | 1: SDL_Scancode << 30, +	F12 = SDL_Scancode::F12 | 1: SDL_Scancode << 30, + +	PRINTSCREEN = SDL_Scancode::PRINTSCREEN | 1: SDL_Scancode << 30, +	SCROLLLOCK = SDL_Scancode::SCROLLLOCK | 1: SDL_Scancode << 30, +	PAUSE = SDL_Scancode::PAUSE | 1: SDL_Scancode << 30, +	INSERT = SDL_Scancode::INSERT | 1: SDL_Scancode << 30, +	HOME = SDL_Scancode::HOME | 1: SDL_Scancode << 30, +	PAGEUP = SDL_Scancode::PAGEUP | 1: SDL_Scancode << 30, +	DELETE = '\x7F', +	END = SDL_Scancode::END | 1: SDL_Scancode << 30, +	PAGEDOWN = SDL_Scancode::PAGEDOWN | 1: SDL_Scancode << 30, +	RIGHT = SDL_Scancode::RIGHT | 1: SDL_Scancode << 30, +	LEFT = SDL_Scancode::LEFT | 1: SDL_Scancode << 30, +	DOWN = SDL_Scancode::DOWN | 1: SDL_Scancode << 30, +	UP = SDL_Scancode::UP | 1: SDL_Scancode << 30, + +	NUMLOCKCLEAR = SDL_Scancode::NUMLOCKCLEAR | 1: SDL_Scancode << 30, +	KP_DIVIDE = SDL_Scancode::KP_DIVIDE | 1: SDL_Scancode << 30, +	KP_MULTIPLY = SDL_Scancode::KP_MULTIPLY | 1: SDL_Scancode << 30, +	KP_MINUS = SDL_Scancode::KP_MINUS | 1: SDL_Scancode << 30, +	KP_PLUS = SDL_Scancode::KP_PLUS | 1: SDL_Scancode << 30, +	KP_ENTER = SDL_Scancode::KP_ENTER | 1: SDL_Scancode << 30, +	KP_1 = SDL_Scancode::KP_1 | 1: SDL_Scancode << 30, +	KP_2 = SDL_Scancode::KP_2 | 1: SDL_Scancode << 30, +	KP_3 = SDL_Scancode::KP_3 | 1: SDL_Scancode << 30, +	KP_4 = SDL_Scancode::KP_4 | 1: SDL_Scancode << 30, +	KP_5 = SDL_Scancode::KP_5 | 1: SDL_Scancode << 30, +	KP_6 = SDL_Scancode::KP_6 | 1: SDL_Scancode << 30, +	KP_7 = SDL_Scancode::KP_7 | 1: SDL_Scancode << 30, +	KP_8 = SDL_Scancode::KP_8 | 1: SDL_Scancode << 30, +	KP_9 = SDL_Scancode::KP_9 | 1: SDL_Scancode << 30, +	KP_0 = SDL_Scancode::KP_0 | 1: SDL_Scancode << 30, +	KP_PERIOD = SDL_Scancode::KP_PERIOD | 1: SDL_Scancode << 30, + +	APPLICATION = SDL_Scancode::APPLICATION | 1: SDL_Scancode << 30, +	POWER = SDL_Scancode::POWER | 1: SDL_Scancode << 30, +	KP_EQUALS = SDL_Scancode::KP_EQUALS | 1: SDL_Scancode << 30, +	F13 = SDL_Scancode::F13 | 1: SDL_Scancode << 30, +	F14 = SDL_Scancode::F14 | 1: SDL_Scancode << 30, +	F15 = SDL_Scancode::F15 | 1: SDL_Scancode << 30, +	F16 = SDL_Scancode::F16 | 1: SDL_Scancode << 30, +	F17 = SDL_Scancode::F17 | 1: SDL_Scancode << 30, +	F18 = SDL_Scancode::F18 | 1: SDL_Scancode << 30, +	F19 = SDL_Scancode::F19 | 1: SDL_Scancode << 30, +	F20 = SDL_Scancode::F20 | 1: SDL_Scancode << 30, +	F21 = SDL_Scancode::F21 | 1: SDL_Scancode << 30, +	F22 = SDL_Scancode::F22 | 1: SDL_Scancode << 30, +	F23 = SDL_Scancode::F23 | 1: SDL_Scancode << 30, +	F24 = SDL_Scancode::F24 | 1: SDL_Scancode << 30, +	EXECUTE = SDL_Scancode::EXECUTE | 1: SDL_Scancode << 30, +	HELP = SDL_Scancode::HELP | 1: SDL_Scancode << 30, +	MENU = SDL_Scancode::MENU | 1: SDL_Scancode << 30, +	SELECT = SDL_Scancode::SELECT | 1: SDL_Scancode << 30, +	STOP = SDL_Scancode::STOP | 1: SDL_Scancode << 30, +	AGAIN = SDL_Scancode::AGAIN | 1: SDL_Scancode << 30, +	UNDO = SDL_Scancode::UNDO | 1: SDL_Scancode << 30, +	CUT = SDL_Scancode::CUT | 1: SDL_Scancode << 30, +	COPY = SDL_Scancode::COPY | 1: SDL_Scancode << 30, +	PASTE = SDL_Scancode::PASTE | 1: SDL_Scancode << 30, +	FIND = SDL_Scancode::FIND | 1: SDL_Scancode << 30, +	MUTE = SDL_Scancode::MUTE | 1: SDL_Scancode << 30, +	VOLUMEUP = SDL_Scancode::VOLUMEUP | 1: SDL_Scancode << 30, +	VOLUMEDOWN = SDL_Scancode::VOLUMEDOWN | 1: SDL_Scancode << 30, +	KP_COMMA = SDL_Scancode::KP_COMMA | 1: SDL_Scancode << 30, +	KP_EQUALSAS400 = SDL_Scancode::KP_EQUALSAS400 | 1: SDL_Scancode << 30, + +	ALTERASE = SDL_Scancode::ALTERASE | 1: SDL_Scancode << 30, +	SYSREQ = SDL_Scancode::SYSREQ | 1: SDL_Scancode << 30, +	CANCEL = SDL_Scancode::CANCEL | 1: SDL_Scancode << 30, +	CLEAR = SDL_Scancode::CLEAR | 1: SDL_Scancode << 30, +	PRIOR = SDL_Scancode::PRIOR | 1: SDL_Scancode << 30, +	RETURN2 = SDL_Scancode::RETURN2 | 1: SDL_Scancode << 30, +	SEPARATOR = SDL_Scancode::SEPARATOR | 1: SDL_Scancode << 30, +	OUT = SDL_Scancode::OUT | 1: SDL_Scancode << 30, +	OPER = SDL_Scancode::OPER | 1: SDL_Scancode << 30, +	CLEARAGAIN = SDL_Scancode::CLEARAGAIN | 1: SDL_Scancode << 30, +	CRSEL = SDL_Scancode::CRSEL | 1: SDL_Scancode << 30, +	EXSEL = SDL_Scancode::EXSEL | 1: SDL_Scancode << 30, + +	KP_00 = SDL_Scancode::KP_00 | 1: SDL_Scancode << 30, +	KP_000 = SDL_Scancode::KP_000 | 1: SDL_Scancode << 30, +	THOUSANDSSEPARATOR = SDL_Scancode::THOUSANDSSEPARATOR | 1: SDL_Scancode << 30, +	DECIMALSEPARATOR = SDL_Scancode::DECIMALSEPARATOR | 1: SDL_Scancode << 30, +	CURRENCYUNIT = SDL_Scancode::CURRENCYUNIT | 1: SDL_Scancode << 30, +	CURRENCYSUBUNIT = SDL_Scancode::CURRENCYSUBUNIT | 1: SDL_Scancode << 30, +	KP_LEFTPAREN = SDL_Scancode::KP_LEFTPAREN | 1: SDL_Scancode << 30, +	KP_RIGHTPAREN = SDL_Scancode::KP_RIGHTPAREN | 1: SDL_Scancode << 30, +	KP_LEFTBRACE = SDL_Scancode::KP_LEFTBRACE | 1: SDL_Scancode << 30, +	KP_RIGHTBRACE = SDL_Scancode::KP_RIGHTBRACE | 1: SDL_Scancode << 30, +	KP_TAB = SDL_Scancode::KP_TAB | 1: SDL_Scancode << 30, +	KP_BACKSPACE = SDL_Scancode::KP_BACKSPACE | 1: SDL_Scancode << 30, +	KP_A = SDL_Scancode::KP_A | 1: SDL_Scancode << 30, +	KP_B = SDL_Scancode::KP_B | 1: SDL_Scancode << 30, +	KP_C = SDL_Scancode::KP_C | 1: SDL_Scancode << 30, +	KP_D = SDL_Scancode::KP_D | 1: SDL_Scancode << 30, +	KP_E = SDL_Scancode::KP_E | 1: SDL_Scancode << 30, +	KP_F = SDL_Scancode::KP_F | 1: SDL_Scancode << 30, +	KP_XOR = SDL_Scancode::KP_XOR | 1: SDL_Scancode << 30, +	KP_POWER = SDL_Scancode::KP_POWER | 1: SDL_Scancode << 30, +	KP_PERCENT = SDL_Scancode::KP_PERCENT | 1: SDL_Scancode << 30, +	KP_LESS = SDL_Scancode::KP_LESS | 1: SDL_Scancode << 30, +	KP_GREATER = SDL_Scancode::KP_GREATER | 1: SDL_Scancode << 30, +	KP_AMPERSAND = SDL_Scancode::KP_AMPERSAND | 1: SDL_Scancode << 30, +	KP_DBLAMPERSAND = SDL_Scancode::KP_DBLAMPERSAND | 1: SDL_Scancode << 30, +	KP_VERTICALBAR = SDL_Scancode::KP_VERTICALBAR | 1: SDL_Scancode << 30, +	KP_DBLVERTICALBAR = SDL_Scancode::KP_DBLVERTICALBAR | 1: SDL_Scancode << 30, +	KP_COLON = SDL_Scancode::KP_COLON | 1: SDL_Scancode << 30, +	KP_HASH = SDL_Scancode::KP_HASH | 1: SDL_Scancode << 30, +	KP_SPACE = SDL_Scancode::KP_SPACE | 1: SDL_Scancode << 30, +	KP_AT = SDL_Scancode::KP_AT | 1: SDL_Scancode << 30, +	KP_EXCLAM = SDL_Scancode::KP_EXCLAM | 1: SDL_Scancode << 30, +	KP_MEMSTORE = SDL_Scancode::KP_MEMSTORE | 1: SDL_Scancode << 30, +	KP_MEMRECALL = SDL_Scancode::KP_MEMRECALL | 1: SDL_Scancode << 30, +	KP_MEMCLEAR = SDL_Scancode::KP_MEMCLEAR | 1: SDL_Scancode << 30, +	KP_MEMADD = SDL_Scancode::KP_MEMADD | 1: SDL_Scancode << 30, +	KP_MEMSUBTRACT = SDL_Scancode::KP_MEMSUBTRACT | 1: SDL_Scancode << 30, +	KP_MEMMULTIPLY = SDL_Scancode::KP_MEMMULTIPLY | 1: SDL_Scancode << 30, +	KP_MEMDIVIDE = SDL_Scancode::KP_MEMDIVIDE | 1: SDL_Scancode << 30, +	KP_PLUSMINUS = SDL_Scancode::KP_PLUSMINUS | 1: SDL_Scancode << 30, +	KP_CLEAR = SDL_Scancode::KP_CLEAR | 1: SDL_Scancode << 30, +	KP_CLEARENTRY = SDL_Scancode::KP_CLEARENTRY | 1: SDL_Scancode << 30, +	KP_BINARY = SDL_Scancode::KP_BINARY | 1: SDL_Scancode << 30, +	KP_OCTAL = SDL_Scancode::KP_OCTAL | 1: SDL_Scancode << 30, +	KP_DECIMAL = SDL_Scancode::KP_DECIMAL | 1: SDL_Scancode << 30, +	KP_HEXADECIMAL = SDL_Scancode::KP_HEXADECIMAL | 1: SDL_Scancode << 30, + +	LCTRL = SDL_Scancode::LCTRL | 1: SDL_Scancode << 30, +	LSHIFT = SDL_Scancode::LSHIFT | 1: SDL_Scancode << 30, +	LALT = SDL_Scancode::LALT | 1: SDL_Scancode << 30, +	LGUI = SDL_Scancode::LGUI | 1: SDL_Scancode << 30, +	RCTRL = SDL_Scancode::RCTRL | 1: SDL_Scancode << 30, +	RSHIFT = SDL_Scancode::RSHIFT | 1: SDL_Scancode << 30, +	RALT = SDL_Scancode::RALT | 1: SDL_Scancode << 30, +	RGUI = SDL_Scancode::RGUI | 1: SDL_Scancode << 30, + +	MODE = SDL_Scancode::MODE | 1: SDL_Scancode << 30, + +	AUDIONEXT = SDL_Scancode::AUDIONEXT | 1: SDL_Scancode << 30, +	AUDIOPREV = SDL_Scancode::AUDIOPREV | 1: SDL_Scancode << 30, +	AUDIOSTOP = SDL_Scancode::AUDIOSTOP | 1: SDL_Scancode << 30, +	AUDIOPLAY = SDL_Scancode::AUDIOPLAY | 1: SDL_Scancode << 30, +	AUDIOMUTE = SDL_Scancode::AUDIOMUTE | 1: SDL_Scancode << 30, +	MEDIASELECT = SDL_Scancode::MEDIASELECT | 1: SDL_Scancode << 30, +	WWW = SDL_Scancode::WWW | 1: SDL_Scancode << 30, +	MAIL = SDL_Scancode::MAIL | 1: SDL_Scancode << 30, +	CALCULATOR = SDL_Scancode::CALCULATOR | 1: SDL_Scancode << 30, +	COMPUTER = SDL_Scancode::COMPUTER | 1: SDL_Scancode << 30, +	AC_SEARCH = SDL_Scancode::AC_SEARCH | 1: SDL_Scancode << 30, +	AC_HOME = SDL_Scancode::AC_HOME | 1: SDL_Scancode << 30, +	AC_BACK = SDL_Scancode::AC_BACK | 1: SDL_Scancode << 30, +	AC_FORWARD = SDL_Scancode::AC_FORWARD | 1: SDL_Scancode << 30, +	AC_STOP = SDL_Scancode::AC_STOP | 1: SDL_Scancode << 30, +	AC_REFRESH = SDL_Scancode::AC_REFRESH | 1: SDL_Scancode << 30, +	AC_BOOKMARKS = SDL_Scancode::AC_BOOKMARKS | 1: SDL_Scancode << 30, + +	BRIGHTNESSDOWN = SDL_Scancode::BRIGHTNESSDOWN | 1: SDL_Scancode << 30, +	BRIGHTNESSUP = SDL_Scancode::BRIGHTNESSUP | 1: SDL_Scancode << 30, +	DISPLAYSWITCH = SDL_Scancode::DISPLAYSWITCH | 1: SDL_Scancode << 30, +	KBDILLUMTOGGLE = SDL_Scancode::KBDILLUMTOGGLE | 1: SDL_Scancode << 30, +	KBDILLUMDOWN = SDL_Scancode::KBDILLUMDOWN | 1: SDL_Scancode << 30, +	KBDILLUMUP = SDL_Scancode::KBDILLUMUP | 1: SDL_Scancode << 30, +	EJECT = SDL_Scancode::EJECT | 1: SDL_Scancode << 30, +	SLEEP = SDL_Scancode::SLEEP | 1: SDL_Scancode << 30, +	APP1 = SDL_Scancode::APP1 | 1: SDL_Scancode << 30, +	APP2 = SDL_Scancode::APP2 | 1: SDL_Scancode << 30, + +	AUDIOREWIND = SDL_Scancode::AUDIOREWIND | 1: SDL_Scancode << 30, +	AUDIOFASTFORWARD = SDL_Scancode::AUDIOFASTFORWARD | 1: SDL_Scancode << 30 +}; + +export type SDL_Keymod = enum u16 { +	NONE = 0x0000, +	LSHIFT = 0x0001, +	RSHIFT = 0x0002, +	LCTRL = 0x0040, +	RCTRL = 0x0080, +	LALT = 0x0100, +	RALT = 0x0200, +	LGUI = 0x0400, +	RGUI = 0x0800, +	NUM = 0x1000, +	CAPS = 0x2000, +	MODE = 0x4000, +	SCROLL = 0x8000, + +	CTRL = LCTRL | RCTRL, +	SHIFT = LSHIFT | RSHIFT, +	ALT = LALT | RALT, +	GUI = LGUI | RGUI, + +	RESERVED = SCROLL, +}; + +export type SDL_Keysym = struct { +	scancode: SDL_Scancode, +	sym: SDL_Keycode, +	mod: SDL_Keymod, +	unused: u32, +}; + +@symbol("SDL_GetKeyFromName") fn _SDL_GetKeyFromName(name: *const c::char) SDL_Keycode; + +export fn SDL_GetKeyFromName(name: str) (SDL_Keycode | error) = { +	const name = c::fromstr(name); +	defer free(name); +	const sym = _SDL_GetKeyFromName(name); +	if (sym == SDL_Keycode::UNKNOWN) { +		return c::tostr(SDL_GetError()): error; +	}; +	return sym; +}; + +@symbol("SDL_GetKeyboardState") fn _SDL_GetKeyboardState(numkeys: *int) *[*]bool; + +export fn SDL_GetKeyboardState() []bool = { +	let numkeys: int = 0; +	let arr = _SDL_GetKeyboardState(&numkeys); +	let arr = arr[..numkeys]; +	return arr; +}; diff --git a/sdl2/mixer/channels.ha b/sdl2/mixer/channels.ha new file mode 100644 index 0000000..fffccd0 --- /dev/null +++ b/sdl2/mixer/channels.ha @@ -0,0 +1,20 @@ +use sdl2; + +@symbol("Mix_PlayChannelTimed") fn _Mix_PlayChannelTimed( +	channel: int, +	sample: *Mix_Chunk, +	loops: int, +	ticks: int, +) int; + +// Play chunk on channel, or if channel is -1, pick the first free unreserved +// channel. The sample will play for loops+1 number of times, unless stopped by +// halt, or fade out, or setting a new expiration time of less time than it +// would have originally taken to play the loops, or closing the mixer. +export fn Mix_PlayChannelTimed( +	channel: int, +	sample: *Mix_Chunk, +	loops: int, +) (void | sdl2::error) = { +	return sdl2::wrapvoid(_Mix_PlayChannelTimed(channel, sample, loops, -1)); +}; diff --git a/sdl2/mixer/general.ha b/sdl2/mixer/general.ha new file mode 100644 index 0000000..87a729f --- /dev/null +++ b/sdl2/mixer/general.ha @@ -0,0 +1,54 @@ +use sdl2; + +// Flags for [[init]]. +export type MIX_InitFlags = enum { +	FLAC = 0x00000001, +	MOD = 0x00000002, +	MP3 = 0x00000008, +	OGG = 0x00000010, +	MID = 0x00000020, +	OPUS = 0x00000040 +}; + +// The default mixer has 8 simultaneous mixing channels +export def MIX_CHANNELS: int = 8; + +// Good default frequency for a PC soundcard +export def MIX_DEFAULT_FREQUENCY: int = 22050; + +// Good default channels for a PC soundcard +export def MIX_DEFAULT_CHANNELS: int = 2; + +// XXX: This should choose MSB on a big-endian system: + +// Good default format for a PC soundcard +export def MIX_DEFAULT_FORMAT: sdl2::SDL_AudioFormat = sdl2::AUDIO_S16LSB; + +@symbol("Mix_Init") fn _Mix_Init(flags: int) int; + +// Loads dynamic libraries and prepares them for use.  Flags should be +// one or more flags from [[MIX_InitFlags]] OR'd together. +export fn Mix_Init(flags: MIX_InitFlags) (void | sdl2::error) = { +	if (flags & _Mix_Init(flags) != flags) { +		return "Mixer flags not initialized": sdl2::error; +	}; +}; + +// Unloads libraries loaded with [[Mix_Init]]. +export @symbol("Mix_Quit") fn Mix_Quit() void; + +@symbol("Mix_OpenAudio") fn _Mix_OpenAudio(frequency: int, +	format: u16, channels: int, chunksize: int) int; + +// Open the mixer with a certain audio format +export fn Mix_OpenAudio( +	frequency: int, +	format: sdl2::SDL_AudioFormat, +	channels: int, +	chunksize: int, +) (void | sdl2::error) = { +	return sdl2::wrapvoid(_Mix_OpenAudio(frequency, format, channels, chunksize)); +}; + +// Close the mixer, halting all playing audio +export @symbol("Mix_CloseAudio") fn Mix_CloseAudio() void; diff --git a/sdl2/mixer/samples.ha b/sdl2/mixer/samples.ha new file mode 100644 index 0000000..ad1ecc1 --- /dev/null +++ b/sdl2/mixer/samples.ha @@ -0,0 +1,38 @@ +use fs; +use io; +use os; +use sdl2; + +// The internal format for an audio Mix_Chunk +export type Mix_Chunk = struct { +	allocated: int, +	abuf: *u8, +	alen: u32, +	volume: u8, +}; + +@symbol("Mix_LoadWAV_RW") fn _Mix_LoadWAV_RW(src: *sdl2::SDL_RWops, freesrc: int) nullable *Mix_Chunk; + +// Loads a sample from an [[io::handle]]. +export fn Mix_LoadWAV_RW(src: io::handle) (*Mix_Chunk | sdl2::error) = { +	const rw = sdl2::rw_from_handle(src); +	return sdl2::wrapptr(_Mix_LoadWAV_RW(rw, 0))?: *Mix_Chunk; +}; + +// Loads a sample from a file path. +export fn load_file(src: str) (*Mix_Chunk | fs::error | sdl2::error) = { +	const file = os::open(src)?; +	defer io::close(file)!; +	return Mix_LoadWAV_RW(file); +}; + +// Free the memory used in Mix_Chunk, and free Mix_Chunk itself as well. Do not use +// Mix_Chunk after this without loading a new sample to it. Note: It's a bad idea to +// free a Mix_Chunk that is still being played... +export @symbol("Mix_FreeChunk") fn Mix_FreeChunk(Mix_Chunk: *Mix_Chunk) void; + +// Maximum volume for a Mix_Chunk. +export def MIX_MAX_VOLUME: int = 128; // XXX: SDL_mixer derives this from SDL_MIX_MAXVOLUME + +// Sets the Mix_Chunk volume as specified, returning the previous value. +export @symbol("Mix_VolumeChunk") fn Mix_VolumeChunk(Mix_Chunk: *Mix_Chunk, volume: int) int; diff --git a/sdl2/mouse.ha b/sdl2/mouse.ha new file mode 100644 index 0000000..78ceb4d --- /dev/null +++ b/sdl2/mouse.ha @@ -0,0 +1,58 @@ +export type SDL_Cursor = opaque; + +// Cursor types for [[SDL_CreateSystemCursor]] +export type SDL_SystemCursor = enum uint { +	ARROW,     // Arrow +	IBEAM,     // I-beam +	WAIT,      // Wait +	CROSSHAIR, // Crosshair +	WAITARROW, // Small wait cursor (or Wait if not available) +	SIZENWSE,  // Double arrow pointing northwest and southeast +	SIZENESW,  // Double arrow pointing northeast and southwest +	SIZEWE,    // Double arrow pointing west and east +	SIZENS,    // Double arrow pointing north and south +	SIZEALL,   // Four pointed arrow pointing north, south, east, and west +	NO,        // Slashed circle or crossbones +	HAND,      // Hand +}; + +// Scroll direction types for the Scroll event +export type SDL_MouseWheelDirection = enum uint { +	NORMAL,    // The scroll direction is normal +	FLIPPED    // The scroll direction is flipped / natural +}; + +// Get the window which currently has mouse focus. +export @symbol("SDL_GetMouseFocus") fn SDL_GetMouseFocus() nullable *SDL_Window; + +// Retrieve the current state of the mouse. +export @symbol("SDL_GetMouseState") fn SDL_GetMouseState(x: *int, y: *int) u32; + +@symbol("SDL_SetRelativeMouseMode") fn _SDL_SetRelativeMouseMode( +	enabled: bool) int; + +// Set relative mouse mode. +export fn SDL_SetRelativeMouseMode(enabled: bool) (void | error) = { +	return wrapvoid(_SDL_SetRelativeMouseMode(enabled)); +}; + +export @symbol("SDL_GetRelativeMouseState") fn SDL_GetRelativeMouseState( +	x: *int, y: *int) u32; + + +// Capture the mouse and to track input outside an SDL window. +export @symbol("SDL_CaptureMouse") fn SDL_CaptureMouse(enabled: bool) int; + +// Toggle whether or not the cursor is shown. +export @symbol("SDL_ShowCursor") fn SDL_ShowCursor(toggle: int) int; + +export def SDL_BUTTON_LEFT	= 1; +export def SDL_BUTTON_MIDDLE	= 2; +export def SDL_BUTTON_RIGHT	= 3; +export def SDL_BUTTON_X1	= 4; +export def SDL_BUTTON_X2	= 5; +export def SDL_BUTTON_LMASK	= 1 << 0; +export def SDL_BUTTON_MMASK	= 1 << 1; +export def SDL_BUTTON_RMASK	= 1 << 2; +export def SDL_BUTTON_X1MASK	= 1 << 3; +export def SDL_BUTTON_X2MASK	= 1 << 4; diff --git a/sdl2/pixels.ha b/sdl2/pixels.ha new file mode 100644 index 0000000..7aa8733 --- /dev/null +++ b/sdl2/pixels.ha @@ -0,0 +1,55 @@ +// TODO: Flesh me out +use types::c; + +export type SDL_Color = struct { +	r: u8, +	g: u8, +	b: u8, +	a: u8, +}; + +export type SDL_Palette = struct { +	ncolors: int, +	colors: *SDL_Color, +	version: u32, +	refcount: int, +}; + +// Note: Everything in the pixel format structure is read-only. +export type SDL_PixelFormat = struct { +	format: u32, // TODO +	palette: *SDL_Palette, +	bitsperpixel: u8, +	bytesperpixel: u8, +	padding: [2]u8, +	rmask: u32, +	gmask: u32, +	bmask: u32, +	amask: u32, +	rloss: u8, +	gloss: u8, +	bloss: u8, +	aloss: u8, +	rshift: u8, +	gshift: u8, +	bshift: u8, +	ashift: u8, +	refcount: int, +	next: nullable *SDL_PixelFormat, +}; + +export def SDL_PIXELFORMAT_ARGB8888: u32 = 0x16362004; + +@symbol("SDL_GetPixelFormatName") fn _SDL_GetPixelFormatName(format: u32) +	const *c::char; + +// Get the human readable name of a pixel format. +export fn SDL_GetPixelFormatName(format: u32) str = { +	return c::tostr(_SDL_GetPixelFormatName(format))!; +}; + +// Map an RGB triple to an opaque pixel value for a given pixel format. +export @symbol("SDL_MapRGB") fn SDL_MapRGB(format: *SDL_PixelFormat, r: u8, g: u8, b: u8) u32; + +// Map an RGBA quadruple to a pixel value for a given pixel format. +export @symbol("SDL_MapRGBA") fn SDL_MapRGBA(format: *SDL_PixelFormat, r: u8, g: u8, b: u8, a: u8) u32; diff --git a/sdl2/rect.ha b/sdl2/rect.ha new file mode 100644 index 0000000..012088e --- /dev/null +++ b/sdl2/rect.ha @@ -0,0 +1,29 @@ +// TODO: Flesh me out + +// The structure that defines a point (integer) +export type SDL_Point = struct { +	x: int, +	y: int, +}; + +// The structure that defines a point (floating point) +export type SDL_FPoint = struct { +	x: f32, +	y: f32, +}; + +// A rectangle, with the origin at the upper left (integer). +export type SDL_Rect = struct { +	x: int, +	y: int, +	w: int, +	h: int, +}; + +// A rectangle, with the origin at the upper left (floating point). +export type SDL_FRect = struct { +	x: f32, +	y: f32, +	w: f32, +	h: f32, +}; diff --git a/sdl2/render.ha b/sdl2/render.ha new file mode 100644 index 0000000..192d608 --- /dev/null +++ b/sdl2/render.ha @@ -0,0 +1,371 @@ +// TODO: Flesh me out + +// A structure representing rendering state. (Opaque) +export type SDL_Renderer = opaque; + +// An efficient driver-specific representation of pixel data. (Opaque) +export type SDL_Texture = opaque; + +export type SDLPixelFormatValues = enum u32 { +    SDL_PIXELFORMAT_UNKNOWN, +    SDL_PIXELFORMAT_INDEX1LSB, +    SDL_PIXELFORMAT_INDEX1MSB, +    SDL_PIXELFORMAT_INDEX4LSB, +    SDL_PIXELFORMAT_INDEX4MSB, +    SDL_PIXELFORMAT_INDEX8, +    SDL_PIXELFORMAT_RGB332, +    SDL_PIXELFORMAT_RGB444, +    SDL_PIXELFORMAT_RGB555, +    SDL_PIXELFORMAT_BGR555, +    SDL_PIXELFORMAT_ARGB4444, +    SDL_PIXELFORMAT_RGBA4444, +    SDL_PIXELFORMAT_ABGR4444, +    SDL_PIXELFORMAT_BGRA4444, +    SDL_PIXELFORMAT_ARGB1555, +    SDL_PIXELFORMAT_RGBA5551, +    SDL_PIXELFORMAT_ABGR1555, +    SDL_PIXELFORMAT_BGRA5551, +    SDL_PIXELFORMAT_RGB565, +    SDL_PIXELFORMAT_BGR565, +    SDL_PIXELFORMAT_RGB24, +    SDL_PIXELFORMAT_BGR24, +    SDL_PIXELFORMAT_RGB888, +    SDL_PIXELFORMAT_RGBX8888, +    SDL_PIXELFORMAT_BGR888, +    SDL_PIXELFORMAT_BGRX8888, +    SDL_PIXELFORMAT_ARGB8888, +    SDL_PIXELFORMAT_RGBA8888, +    SDL_PIXELFORMAT_ABGR8888, +    SDL_PIXELFORMAT_BGRA8888, +}; + +// Flags used when creating a rendering context. +export type SDL_RendererFlags = enum u32 { +	NONE = 0, +	SOFTWARE = 0x00000001, +	ACCELERATED = 0x00000002, +	PRESENTVSYNC = 0x00000004, +	TARGETTEXTURE = 0x00000008, +}; + +export type SDL_RendererFlip = enum u32 { +    SDL_FLIP_NONE, +    SDL_FLIP_HORIZONTAL, +    SDL_FLIP_VERTICAL, +    SDL_FLIP_BOTH, +}; + +export type SDL_TextureAccess = enum { +    SDL_TEXTUREACCESS_STATIC, +    SDL_TEXTUREACCESS_STREAMING, +	SDL_TEXTUREACCESS_TARGET, +}; + +@symbol("SDL_CreateWindowAndRenderer") fn _SDL_CreateWindowAndRenderer( +	width: int, height: int, SDL_WindowFlags: SDL_WindowFlags, +	window: nullable **SDL_Window, renderer: nullable **SDL_Renderer) int; + +// Create a window and default renderer. +// +// 'width' and 'height' set the width and height of the window, in screen +// coordinates. 'SDL_WindowFlags' configure additional window parameters. +// +// 'window' and 'renderer' are out parameters, or null, which are filled in with +// the created window and renderer respectively. +export fn SDL_CreateWindowAndRenderer( +	width: int, +	height: int, +	SDL_WindowFlags: SDL_WindowFlags, +	window: nullable **SDL_Window, +	renderer: nullable **SDL_Renderer, +) (void | error) = wrapvoid(_SDL_CreateWindowAndRenderer(width, height, +	SDL_WindowFlags, window, renderer)); + +@symbol("SDL_CreateRenderer") fn _SDL_CreateRenderer(window: *SDL_Window, +	index: int, flags: SDL_RendererFlags) nullable *SDL_Renderer; + +// Create a 2D rendering context for a window. +// +// 'window' is the window where rendering is displayed. 'index' is the index of +// the rendering driver to initialize, or -1 to initialize the first one +// supporting the requested flags. +// +// See also: [[create_software_renderer]], [[get_renderer_info]], +// [[SDL_DestroyRenderer]]. +export fn SDL_CreateRenderer( +	window: *SDL_Window, +	index: int, +	flags: SDL_RendererFlags, +) (*SDL_Renderer | error) = +	wrapptr(_SDL_CreateRenderer(window, index, flags))?: *SDL_Renderer; + +// Destroy the rendering context for a window and free associated textures. +// +// See also: [[SDL_CreateRenderer]]. +export @symbol("SDL_DestroyRenderer") fn SDL_DestroyRenderer(renderer: *SDL_Renderer) void; + +@symbol("SDL_GetRendererOutputSize") fn _SDL_GetRendererOutputSize(renderer: *SDL_Renderer, +	w: *int, h: *int) int; + +// Get the output size in pixels of a rendering context. +export fn SDL_GetRendererOutputSize( +	renderer: *SDL_Renderer, +	w: *int, h: *int, +) (void | error) = wrapvoid(_SDL_GetRendererOutputSize(renderer, w, h)); + +// Opaque value for the alpha channel (255). +export def ALPHA_OPAQUE: u8 = 255; + +@symbol("SDL_SetRenderDrawColor") fn _SDL_SetRenderDrawColor(renderer: *SDL_Renderer, +	r: u8, g: u8, b: u8, a: u8) int; + +// Set the color used for drawing operations (Rect, Line and Clear). +// +// 'renderer' is the renderer for which drawing color should be set. 'r', 'g', +// 'b', and 'a' respectively set the red, gree, blue, and alpha channels. +export fn SDL_SetRenderDrawColor( +	renderer: *SDL_Renderer, +	r: u8, g: u8, b: u8, a: u8, +) (void | error) = wrapvoid(_SDL_SetRenderDrawColor(renderer, r, g, b, a)); + +@symbol("SDL_RenderClear") fn _SDL_RenderClear(renderer: *SDL_Renderer) int; + +// Clear the current rendering target with the drawing color +// +// This function clears the entire rendering target, ignoring the viewport and +// the clip rectangle. +export fn SDL_RenderClear(renderer: *SDL_Renderer) (void | error) = { +	return wrapvoid(_SDL_RenderClear(renderer)); +}; + +// Update the screen with rendering performed. +export @symbol("SDL_RenderPresent") fn SDL_RenderPresent(renderer: *SDL_Renderer) void; + +// Destroy the specified texture. +export @symbol("SDL_DestroyTexture") fn SDL_DestroyTexture(texture: *SDL_Texture) void; + +@symbol("SDL_QueryTexture") fn _SDL_QueryTexture(texture: *SDL_Texture, +	format: nullable *u32, access: nullable *int, +	w: nullable *int, h: nullable *int) int; + +// Query the attributes of a texture +export fn SDL_QueryTexture( +	texture: *SDL_Texture, +	format: nullable *u32, +	access: nullable *int, +	w: nullable *int, h: nullable *int, +) (void | error) = { +	return wrapvoid(_SDL_QueryTexture(texture, format, access, w, h)); +}; + +@symbol("SDL_SetTextureColorMod") fn _SDL_SetTextureColorMod( +	texture: *SDL_Texture, r: u8, g: u8, b: u8) int; + +// Set an additional color value multiplied into render copy operations. +// +// When this texture is rendered, during the copy operation each source color +// channel is modulated by the appropriate color value according to the +// following formula: +// +// 	srcC = srcC * (color / 255) +// +// Color modulation is not always supported by the renderer; it will return -1 +// if color modulation is not supported. +export fn SDL_SetTextureColorMod( +	texture: *SDL_Texture, +	r: u8, g: u8, b: u8, +) (void | error) = { +	return wrapvoid(_SDL_SetTextureColorMod(texture, r, g, b)); +}; + +@symbol("SDL_SetTextureAlphaMod") fn _SDL_SetTextureAlphaMod(texture: *SDL_Texture, a: u8) int; + +// Set an additional alpha value multiplied into render copy operations. +// +// When this texture is rendered, during the copy operation the source alpha +// value is modulated by this alpha value according to the following formula: +// +// `srcA = srcA * (alpha / 255)` +// +// Alpha modulation is not always supported by the renderer; it will return an +// error if alpha modulation is not supported. +export fn SDL_SetTextureAlphaMod(texture: *SDL_Texture, a: u8) (void | error) = { +	// TODO: Double check errors +	return wrapvoid(_SDL_SetTextureAlphaMod(texture, a)); +}; + +@symbol("SDL_SetTextureBlendMode") fn _SDL_SetTextureBlendMode( +	texture: *SDL_Texture, mode: SDL_BlendMode) int; + +// Set the blend mode for a texture, used by SDL_RenderCopy(). +export fn SDL_SetTextureBlendMode( +	texture: *SDL_Texture, +	mode: SDL_BlendMode, +) (void | error) = { +	return wrapvoid(_SDL_SetTextureBlendMode(texture, mode)); +}; + +@symbol("SDL_SetRenderDrawBlendMode") fn _SDL_SetRenderDrawBlendMode( +	renderer: *SDL_Renderer, mode: SDL_BlendMode) int; + +// Set the blend mode used for drawing operations (fill and line). +export fn SDL_SetRenderDrawBlendMode( +	renderer: *SDL_Renderer, +	mode: SDL_BlendMode, +) (void | error) = { +	return wrapvoid(_SDL_SetRenderDrawBlendMode(renderer, mode)); +}; + +@symbol("SDL_RenderDrawPoint") fn _SDL_RenderDrawPoint( +    renderer: *SDL_Renderer, +    x: int, +    y: int, +) int; + +// Draws a point (pixel) at the given coordinates +export fn SDL_RenderDrawPoint( +    renderer: *SDL_Renderer, +    x: int, +    y: int, +) (void | error) = { +	return wrapvoid(_SDL_RenderDrawPoint(renderer, x, y)); +}; + +@symbol("SDL_RenderCopy") fn _SDL_RenderCopy(renderer: *SDL_Renderer, +	texture: *SDL_Texture, srcrect: nullable *SDL_Rect, dstrect: nullable *SDL_Rect) int; + +// Copy a portion of the texture to the current rendering target. +export fn SDL_RenderCopy( +	renderer: *SDL_Renderer, +	texture: *SDL_Texture, +	srcrect: nullable *SDL_Rect, +	dstrect: nullable *SDL_Rect, +) (void | error) = { +	return wrapvoid(_SDL_RenderCopy(renderer, texture, srcrect, dstrect)); +}; + +@symbol("SDL_RenderCopyEx") fn _SDL_RenderCopyEx( +    renderer: *SDL_Renderer, +    texture: *SDL_Texture, +    srcrect: nullable *SDL_Rect, +    dstrect: nullable *SDL_Rect, +    angle  : f64, +    center: nullable *SDL_Point, +    flip: SDL_RendererFlip, +) int; + +// Sets the rendering pixel scale +export fn SDL_RenderCopyEx( +    renderer: *SDL_Renderer, +    texture: *SDL_Texture, +    srcrect: nullable *SDL_Rect, +    dstrect: nullable *SDL_Rect, +    angle  : f64, +    center: nullable *SDL_Point, +    flip: SDL_RendererFlip, +) (void | error) = { +	return wrapvoid(_SDL_RenderCopyEx( +        renderer, texture, srcrect, dstrect, angle, center, flip) +    ); +}; + +@symbol("SDL_RenderDrawRect") fn _SDL_RenderDrawRect( +	renderer: *SDL_Renderer, rect: const nullable *SDL_Rect) int; + +// Draw a rectangle on the current rendering target. +export fn SDL_RenderDrawRect( +	renderer: *SDL_Renderer, +	rect: const nullable *SDL_Rect, +) (void | error) = { +	return wrapvoid(_SDL_RenderDrawRect(renderer, rect)); +}; + +@symbol("SDL_RenderFillRect") fn _SDL_RenderFillRect( +	renderer: *SDL_Renderer, rect: const nullable *SDL_Rect) int; + +// Fills a rectangle on the current rendering target. +export fn SDL_RenderFillRect( +	renderer: *SDL_Renderer, +	rect: const nullable *SDL_Rect, +) (void | error) = { +	return wrapvoid(_SDL_RenderFillRect(renderer, rect)); +}; + +@symbol("SDL_RenderSetLogicalSize") fn _SDL_RenderSetLogicalSize( +    renderer: *SDL_Renderer, w: int, h: int) int; + +// Sets the rendering pixel scale +export fn SDL_RenderSetLogicalSize( +    renderer: *SDL_Renderer,  +    w: int,  +    h: int, +) (void | error) = { +	return wrapvoid(_SDL_RenderSetLogicalSize( +        renderer, w, h) +    ); +}; + +@symbol("SDL_CreateTexture") fn _SDL_CreateTexture( +    renderer: *SDL_Renderer, +    format: u32, +    access: int, +    w: int, +    h: int) nullable *SDL_Texture; + +export fn SDL_CreateTexture( +    renderer: *SDL_Renderer, +    format: u32, +    access: int, +    w: int, +    h: int +) (*SDL_Texture | error) = { +    return wrapptr(_SDL_CreateTexture( +        renderer, format, access, w, h) +    )?: *SDL_Texture; +}; + +@symbol("SDL_CreateTextureFromSurface") fn _SDL_CreateTextureFromSurface( +    renderer: *SDL_Renderer, +    surface: *SDL_Surface) nullable *SDL_Texture; + +export fn SDL_CreateTextureFromSurface( +    renderer: *SDL_Renderer, +    surface: *SDL_Surface +) (*SDL_Texture | error) = { +    return wrapptr(_SDL_CreateTextureFromSurface(renderer, surface))?: *SDL_Texture; +}; + +@symbol("SDL_UpdateTexture") fn _SDL_UpdateTexture(texture: *SDL_Texture, +	rect: const nullable *SDL_Rect, pixels: const nullable *opaque, pitch: int) int; + +// Update the given texture rectangle with new pixel data. +export fn SDL_UpdateTexture(texture: *SDL_Texture, +	rect: const nullable *SDL_Rect, pixels: const nullable *opaque, pitch: int) +	(int | error) = { +	return wrapint(_SDL_UpdateTexture(texture, rect, pixels, pitch))?: int; +}; + +@symbol("SDL_LockTexture") fn _SDL_LockTexture(texture: *SDL_Texture, +	rect: const nullable *SDL_Rect, pixels: nullable * nullable *opaque, pitch: *int) int; + +// Lock a portion of the texture for write-only pixel access. +export fn SDL_LockTexture(texture: *SDL_Texture, +	rect: const nullable *SDL_Rect, pixels: nullable * nullable *opaque, pitch: *int) +	(int | error) = { +	return wrapint(_SDL_LockTexture(texture, rect, pixels, pitch))?: int; +}; + +// Unlock a texture, uploading the changes to video memory, if needed. +export @symbol("SDL_UnlockTexture") fn SDL_UnlockTexture(texture: *SDL_Texture) void; + +@symbol("SDL_RenderSetScale") fn _SDL_RenderSetScale( +    renderer: *SDL_Renderer, scaleX: f32, scaleY: f32) int; + +// Sets the rendering pixel scale +export fn SDL_RenderSetScale( +    renderer: *SDL_Renderer,  +    scaleX: f32,  +    scaleY: f32, +) (void | error) = { +	return wrapvoid(_SDL_RenderSetScale(renderer, scaleX, scaleY)); +}; diff --git a/sdl2/rwops.ha b/sdl2/rwops.ha new file mode 100644 index 0000000..4605a3a --- /dev/null +++ b/sdl2/rwops.ha @@ -0,0 +1,134 @@ +use io; +use types::c; + +// RWops types +export type rwops_type = enum u32 { +	UNKNOWN = 0, +	WINFILE = 1, +	STDFILE = 2, +	JNIFILE = 3, +	MEMORY = 4, +	MEMORY_RO = 5, +}; + +// The read/write operation structure -- very basic. +export type SDL_RWops = struct { +	sz: *fn(ctx: *SDL_RWops) i64, +	seek: *fn(ctx: *SDL_RWops, offs: i64, whence: int) i64, +	read: *fn(ctx: *SDL_RWops, ptr: *opaque, sz: size, maxnum: size) size, +	write: *fn(ctx: *SDL_RWops, ptr: *const opaque, sz: size, num: size) size, +	close: *fn(ctx: *SDL_RWops) int, + +	type_: rwops_type, +	// XXX: This union is platform-specific +	hidden: union { +		stdio: struct { +			autoclose: bool, +			fp: nullable *opaque, // FILE * +		}, +		mem: struct { +			base: nullable *u8, +			here: nullable *u8, +			stop: nullable *u8, +		}, +		unknown: struct { +			data1: nullable *opaque, +			data2: nullable *opaque, +		}, +	}, +}; + +@symbol("SDL_RWFromFile") fn _rw_from_file( +	file: const *c::char, +	mode: const *c::char, +) *SDL_RWops; + +// Returns the size of an [[SDL_RWops]], or 0 if unknown or error. +// +// See [[stream_from_rw]] for a more idiomatic Hare interface to SDL_RWops. +export @symbol("SDL_RWsize") fn SDL_RWsize(ctx: *SDL_RWops) i64; + +// Closes an [[SDL_RWops]], returning 1 on success or 0 on error. +// +// See [[stream_from_rw]] for a more idiomatic Hare interface to SDL_RWops. +export @symbol("SDL_RWclose") fn SDL_RWclose(ctx: *SDL_RWops) int; + +// TODO: Other RWops wrappers + +// Creates an [[SDL_RWops]] from an [[io::handle]]. Closing the rwops does not close +// the underlying stream. +export fn rw_from_handle(in: io::handle) *SDL_RWops = { +	// TODO: Add stream_from_rw +	let rw = alloc(SDL_RWops { +		sz = &stream_size, +		seek = &stream_seek, +		read = &stream_read, +		write = &stream_write, +		close = &stream_close, +		type_ = rwops_type::UNKNOWN, +		... +	}); +	// Assert that we can cram an io::handle into the SDL_RWops struct +	static assert(size(io::handle) <= size(nullable *u8) * 2); +	let ptr = &rw.hidden.unknown.data1: *io::handle; +	*ptr = in; +	return rw; +}; + +fn stream_size(ctx: *SDL_RWops) i64 = { +	const handle = *(&ctx.hidden.unknown.data1: *io::handle); +	const old = match (io::tell(handle)) { +	case let o: io::off => +		yield o; +	case io::error => +		return -1; +	}; +	io::seek(handle, 0, io::whence::END)!; +	const sz = io::tell(handle)!; +	io::seek(handle, old, io::whence::SET)!; +	return sz; +}; + +fn stream_seek(ctx: *SDL_RWops, offs: i64, whence: int) i64 = { +	const handle = *(&ctx.hidden.unknown.data1: *io::handle); +	// Note: whence values in stdio.h match io::whence +	match (io::seek(handle, offs: io::off, whence: io::whence)) { +	case let o: io::off => +		return o; +	case io::error => +		return -1; +	}; +}; + +fn stream_read(ctx: *SDL_RWops, ptr: *opaque, sz: size, maxnum: size) size = { +	const handle = *(&ctx.hidden.unknown.data1: *io::handle); +	let buf = ptr: *[*]u8; +	match (io::readall(handle, buf[..sz * maxnum])) { +	case let n: size => +		return n / sz; +	case io::EOF => +		return 0; +	case io::error => +		return 0; +	}; +}; + +fn stream_write(ctx: *SDL_RWops, ptr: *const opaque, sz: size, num: size) size = { +	const handle = *(&ctx.hidden.unknown.data1: *io::handle); +	let buf = ptr: *[*]const u8; +	match (io::writeall(handle, buf[..sz * num])) { +	case let n: size => +		return n / sz; +	case io::error => +		return 0; +	}; +}; + +fn stream_close(ctx: *SDL_RWops) int = { +	const handle = *(&ctx.hidden.unknown.data1: *io::handle); +	free(ctx); +	match (io::close(handle)) { +	case void => return 0; +	case io::error => return -1; +	}; +}; diff --git a/sdl2/sdl2.ha b/sdl2/sdl2.ha new file mode 100644 index 0000000..7035e04 --- /dev/null +++ b/sdl2/sdl2.ha @@ -0,0 +1,23 @@ +export def SDL_INIT_TIMER: uint = 0x00000001u; +export def SDL_INIT_AUDIO: uint = 0x00000010u; +export def SDL_INIT_VIDEO: uint = 0x00000020u; +export def SDL_INIT_JOYSTICK: uint = 0x00000200u; +export def SDL_INIT_HAPTIC: uint = 0x00001000u; +export def SDL_INIT_GAMECONTROLLER: uint = 0x00002000u; +export def SDL_INIT_EVENTS: uint = 0x00004000u; +export def SDL_INIT_SENSOR: uint = 0x00008000u; +export def SDL_INIT_NOPARACHUTE: uint = 0x00100000u; +export def SDL_INIT_EVERYTHING: uint = SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO +	| SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC +	| SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR; + +@symbol("SDL_Init") fn _SDL_Init(flags: uint) int; + +// This function initializes the subsystems specified by 'flags'. +export fn SDL_Init(flags: uint) (void | error) = { +	return wrapvoid(_SDL_Init(flags)); +}; + +// This function cleans up all initialized subsystems. You should call it upon +// all exit conditions. +export @symbol("SDL_Quit") fn SDL_Quit() void; diff --git a/sdl2/surface.ha b/sdl2/surface.ha new file mode 100644 index 0000000..afca40c --- /dev/null +++ b/sdl2/surface.ha @@ -0,0 +1,53 @@ +// A collection of pixels used in software blitting. +// +// This structure should be treated as read-only, except for 'pixels', which, if +// not null, contains the raw pixel data for the surface. +export type SDL_Surface = struct { +	flags: u32, +	format: *SDL_PixelFormat, +	w: int, +	h: int, +	pitch: int, +	pixels: nullable *opaque, + +	userdata: *opaque, + +	locked: int, +	lock_data: *opaque, + +	clip_rect: SDL_Rect, + +	map: *SDL_BlitMap, + +	refcount: int, +}; + +export type SDL_BlitMap = opaque; + +@symbol("SDL_CreateRGBSurface") fn _SDL_CreateRGBSurface(flags: u32, +	width: int, height: int, depth: int, Rmask: u32, Gmask: u32, Bmask: u32, +	Amask: u32) *SDL_Surface; + +// Allocate a new RGB surface. +export fn SDL_CreateRGBSurface(flags: u32, +	width: int, height: int, depth: int, Rmask: u32, Gmask: u32, Bmask: u32, +	Amask: u32) (*SDL_Surface | error) = { +	return wrapptr(_SDL_CreateRGBSurface(flags, width, height, depth, Rmask, +	Gmask, Bmask, Amask))?: *SDL_Surface; +}; + +@symbol("SDL_FreeSurface") fn _SDL_FreeSurface(surface: nullable *SDL_Surface) void; + +// Free an RGB surface. +export fn SDL_FreeSurface(surface: nullable *SDL_Surface) void = { +	_SDL_FreeSurface(surface); +}; + +// NB SDL_BlitSurface is aliased to SDL_UpperBlit via a macro in the SDL header +@symbol("SDL_UpperBlit") fn _SDL_BlitSurface(src: *SDL_Surface, +	srcrect: nullable *SDL_Rect, dst: *SDL_Surface, dstrect: nullable *SDL_Rect) int; + +// Perform a fast surface copy to a destination surface. +export fn SDL_BlitSurface(src: *SDL_Surface, srcrect: nullable *SDL_Rect, dst: *SDL_Surface, dstrect: nullable *SDL_Rect) (void | error) = { +	return wrapvoid(_SDL_BlitSurface(src, srcrect, dst, dstrect)); +}; diff --git a/sdl2/timer.ha b/sdl2/timer.ha new file mode 100644 index 0000000..d90511a --- /dev/null +++ b/sdl2/timer.ha @@ -0,0 +1,32 @@ +// Get the number of milliseconds since SDL library initialization. +// +// This value wraps if the program runs for more than ~49 days. +// +// Returns an unsigned 32-bit value representing the number of milliseconds +// since the SDL library initialized. +export @symbol("SDL_GetTicks") fn SDL_GetTicks() u32; + +// Get the current value of the high resolution counter. +// +// This function is typically used for profiling. +// +// The counter values are only meaningful relative to each other. Differences +// between values can be converted to times by using +// [[SDL_GetPerformanceFrequency]]. +// +// Returns the current counter value. +export @symbol("SDL_GetPerformanceCounter") fn SDL_GetPerformanceCounter() u64; + +// Get the count per second of the high resolution counter. +// +// Returns a platform-specific count per second. +export @symbol("SDL_GetPerformanceFrequency") fn SDL_GetPerformanceFrequency() u64; + +// Wait a specified number of milliseconds before returning. +// +// This function waits a specified number of milliseconds before returning. It +// waits at least the specified time, but possibly longer due to OS +// scheduling. +export @symbol("SDL_Delay") fn SDL_Delay(ms: u32) void; + +// TODO: Timers diff --git a/sdl2/video.ha b/sdl2/video.ha new file mode 100644 index 0000000..c786122 --- /dev/null +++ b/sdl2/video.ha @@ -0,0 +1,141 @@ +// TODO: Flesh me out +use types::c; + +// The type used to identify a window. (Opaque) +export type SDL_Window = opaque; + +// The flags on a window +export type SDL_WindowFlags = enum u32 { +	NONE = 0, +	FULLSCREEN = 0x00000001, +	OPENGL = 0x00000002, +	SHOWN = 0x00000004, +	HIDDEN = 0x00000008, +	BORDERLESS = 0x00000010, +	RESIZABLE = 0x00000020, +	MINIMIZED = 0x00000040, +	MAXIMIZED = 0x00000080, +	INPUT_GRABBED = 0x00000100, +	INPUT_FOCUS = 0x00000200, +	MOUSE_FOCUS = 0x00000400, +	FULLSCREEN_DESKTOP = 0x00001001, +	FOREIGN = 0x00000800, +	ALLOW_HIGHDPI = 0x00002000, +	MOUSE_CAPTURE = 0x00004000, +	ALWAYS_ON_TOP = 0x00008000, +	SKIP_TASKBAR = 0x00010000, +	UTILITY = 0x00020000, +	TOOLTIP = 0x00040000, +	POPUP_MENU = 0x00080000, +	VULKAN = 0x10000000 +}; + +export def SDL_WINDOWPOS_UNDEFINED: int = 0x1FFF0000; +export def SDL_WINDOWPOS_CENTERED: int = 0x2FFF0000; + +@symbol("SDL_CreateWindow") fn _SDL_CreateWindow(title: const *c::char, +	x: int, y: int, w: int, h: int, flags: SDL_WindowFlags) nullable *SDL_Window; + +// Create a window with the specified position, dimensions, and flags. +// +// 'title' is the title of the window, in UTF-8 encoding. See [[types::c::fromstr]] +// to prepare a suitable string. +// +// 'x' and 'y' set the position of the window, or use [[SDL_WINDOWPOS_CENTERED]] or +// [[SDL_WINDOWPOS_UNDEFINED]]. +// +// 'w' and 'h' set the width and height of the window, in screen coordinates. +// +// 'flags' configure additional window parameters. +// +// Returns the created window, or null if window creation failed. +// +// If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size +// in pixels may differ from its size in screen coordinates on platforms with +// high-DPI support (e.g. iOS and Mac OS X). Use SDL_GetWindowSize() to query +// the client area's size in screen coordinates, and SDL_GL_GetDrawableSize(), +// SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to query the +// drawable size in pixels. +// +// If the window is created with any of the SDL_WINDOW_OPENGL or +// SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function +// (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the +// corresponding UnloadLibrary function is called by SDL_DestroyWindow(). +// +// If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver, +// SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail. +// +// Note: On non-Apple devices, SDL requires you to either not link to the +// Vulkan loader or link to a dynamic library version. This limitation may be +// removed in a future version of SDL. +// +// See also: [[SDL_DestroyWindow]] [[gl_loadlibrary]], [[vulkan_loadlibrary]]. +export fn SDL_CreateWindow( +	title: str, +	x: int, +	y: int, +	w: int, +	h: int, +	flags: SDL_WindowFlags, +) (*SDL_Window | error) = { +	let title = c::fromstr(title); +	defer free(title); +	return wrapptr(_SDL_CreateWindow(title, x, y, w, h, flags))?: *SDL_Window; +}; + +// Destroy a window. +export @symbol("SDL_DestroyWindow") fn SDL_DestroyWindow(window: *SDL_Window) void; + +// Get the size of a window's client area. +// +// Null may safely be passed as the 'w' or 'h' parameter if the width or +// height value is not desired. +// +// The window size in screen coordinates may differ from the size in pixels, if +// the window was created with `ALLOW_HIGHDPI` on a platform with high-dpi +// support (e.g. iOS or macOS). Use [[gl_getdrawablesize]], +// [[vulkan_getdrawablesize]], or [[getrendereroutputsize]] to get the real +// client area size in pixels. +export @symbol("SDL_GetWindowSize") fn SDL_GetWindowSize(window: *SDL_Window, +	w: nullable *int, h: nullable *int) void; + +@symbol("SDL_GetWindowSurface") fn _SDL_GetWindowSurface(window: *SDL_Window) +	*SDL_Surface; + +// Get the SDL surface associated with the window. +export fn SDL_GetWindowSurface(window: *SDL_Window) (*SDL_Surface | error) = { +	return wrapptr(_SDL_GetWindowSurface(window))?: *SDL_Surface; +}; + +// Copy the window surface to the screen. +@symbol("SDL_UpdateWindowSurface") fn _SDL_UpdateWindowSurface(window: *SDL_Window) +	int; + +export fn SDL_UpdateWindowSurface(window: *SDL_Window) (void | error) = { +	return wrapvoid(_SDL_UpdateWindowSurface(window)); +}; + +@symbol("SDL_GetCurrentVideoDriver") fn _SDL_GetCurrentVideoDriver() +	nullable *const c::char; + +export fn SDL_GetCurrentVideoDriver() str = { +	match (_SDL_GetCurrentVideoDriver()) { +	case null => +		return ""; +	case let s: *const c::char => +		return c::tostr(s)!; +	}; +}; + +@symbol("SDL_SetWindowFullscreen") fn _SDL_SetWindowFullscreen( +	window: *SDL_Window, flags: SDL_WindowFlags) int; + +export fn SDL_SetWindowFullscreen( +	window: *SDL_Window, +	flags: SDL_WindowFlags, +) (void | error) = { +	return wrapvoid(_SDL_SetWindowFullscreen(window, flags)); +}; + +export @symbol("SDL_GetWindowFlags") fn SDL_GetWindowFlags(window: *SDL_Window) +	SDL_WindowFlags; diff --git a/section_geometry.ha b/section_geometry.ha new file mode 100644 index 0000000..c39780e --- /dev/null +++ b/section_geometry.ha @@ -0,0 +1,164 @@ +use comparray; + +fn section_build_geometry(pos: SectionPos) []Vertex = { +	const section = getsection(pos) as *Section; + +	if (section.bstates.palette_size == 1 +			&& section.bstates.data_constant == 0) { +		return []; +	}; + +	const neighbors = [ +		getsection(SectionPos { x = pos.x - 1, y = pos.y, z = pos.z }), +		getsection(SectionPos { x = pos.x + 1, y = pos.y, z = pos.z }), +		getsection(SectionPos { x = pos.x, y = pos.y - 1, z = pos.z }), +		getsection(SectionPos { x = pos.x, y = pos.y + 1, z = pos.z }), +		getsection(SectionPos { x = pos.x, y = pos.y, z = pos.z - 1 }), +		getsection(SectionPos { x = pos.x, y = pos.y, z = pos.z + 1 }), +	]; + +	let vertices: []Vertex = alloc([], 1024); + +	for (let y = 0u8; y < 16; y += 1) +	for (let z = 0u8; z < 16; z += 1) +	for (let x = 0u8; x < 16; x += 1) { +		const i = x | z << 4 | y: size << 8; +		const bstate = comparray::lookup(§ion.bstates, comparray::get(§ion.bstates, i)); + +		if (bstate == 0) continue; + +		const render_bstate = &BSTATES_RENDER[bstate]; +		for (let i = 0z; i < len(render_bstate.parts); i += 1) { +			const part = &render_bstate.parts[i]; +			const geom = part.model.geom as *ModelGeom; + +			for (let j = 0z; j < len(geom.faces); j += 1) { +				const face = &geom.faces[j]; + +				if (face.cull_face != CullFace::NONE) { +					let axis = 0u8; +					for (true; axis += 1) { +						if (part.swizzle >> axis >> axis & 3 +							== face.cull_face >> 1) break; +					}; +					const flip = part.flags: u8 >> axis; +					const sign = (face.cull_face: u8 ^ flip) & 1; +					const cull_face = axis << 1 | sign; + +					let neighbor = [x, y, z]; +					const coord = &neighbor[axis]; +					*coord += (sign << 1) - 1; +					const section_ = if (*coord & 0xf0 != 0) +						neighbors[cull_face] else section; +					*coord &= 0x0f; + +					match (section_) { +					case let section_: *Section => +						const k = neighbor[0] | neighbor[2] << 4 +							| neighbor[1]: size << 8; +						const bstate_ = comparray::lookup(§ion_.bstates, comparray::get(§ion_.bstates, k)); +						if ((bstate >= 77 && bstate <= 92 || !(bstate_ >= 77 && bstate_ <= 92)) +							&& len((BSTATES_RENDER[bstate_].parts[0].model.geom as *ModelGeom).faces) != 0) continue; +					case null => +						if (axis != 1) continue; +					}; +				}; + +				let face_vertices: [4][3]u16 = [[0...]...]; +				for (let k = 0z; k < 4; k += 1) { +					const vert = &face.vertices[k]; +					let vx = vert[part.swizzle & 3]; +					if (part.flags & BstateRenderPartFlags::FLIP_X != 0) +						vx = 6144 - vx; +					vx += x: u16 * 2048; +					let vy = vert[part.swizzle >> 2 & 3]; +					if (part.flags & BstateRenderPartFlags::FLIP_Y != 0) +						vy = 6144 - vy; +					vy += y: u16 * 2048; +					let vz = vert[part.swizzle >> 4]; +					if (part.flags & BstateRenderPartFlags::FLIP_Z != 0) +						vz = 6144 - vz; +					vz += z: u16 * 2048; +					face_vertices[k] = [vx, vy, vz]; +				}; + +				let normal = [ +					face.normal[part.swizzle & 3], +					face.normal[part.swizzle >> 2 & 3], +					face.normal[part.swizzle >> 4], +				]; +				if (part.flags & BstateRenderPartFlags::FLIP_X != 0) +					normal[0] = -normal[0]; +				if (part.flags & BstateRenderPartFlags::FLIP_Y != 0) +					normal[1] = -normal[1]; +				if (part.flags & BstateRenderPartFlags::FLIP_Z != 0) +					normal[2] = -normal[2]; + +				const sprite = part.model.textures[face.texture]; + +				const tex_left = face.texcoord[0]; +				const tex_top = face.texcoord[1]; +				const tex_right = face.texcoord[2]; +				const tex_bottom = face.texcoord[3]; +				const flags_left: VertexFlags = if (tex_left < tex_right) 0 else VertexFlags::U_EXCL; +				const flags_top: VertexFlags = if (tex_top < tex_bottom) 0 else VertexFlags::V_EXCL; +				const flags_right = flags_left ^ VertexFlags::U_EXCL; +				const flags_bottom = flags_top ^ VertexFlags::V_EXCL; +				let texcoord: [4][2]u16 = [ +					[tex_left, tex_top], +					[tex_left, tex_bottom], +					[tex_right, tex_bottom], +					[tex_right, tex_top], +				]; +				let flags = [ +					flags_left | flags_top, +					flags_left | flags_bottom, +					flags_right | flags_bottom, +					flags_right | flags_top, +				]; +				const mask = 1 << face.dir; +				const flip_u = part.flip_u & mask != 0; +				const flip_v = part.flip_v & mask != 0; +				const swap_uv = part.swap_uv & mask != 0; +				const tex_flipped = tex_left < tex_right +					!= tex_top < tex_bottom; +				// flipping the texture reverses the apparent +				// rotation wrt. the rotation applied to the +				// texcoords, so we need to compensate. +				const (flip_u, flip_v) = if (tex_flipped) +					(flip_v, flip_u) else (flip_u, flip_v); +				for (let k = 0u8; k < 4; k += 1) { +					const uv = &texcoord[k]; +					const f = &flags[k]; +					if (swap_uv) { +						*uv = [uv[1], uv[0]]; +						const u_excl = *f & VertexFlags::U_EXCL; +						const v_excl = *f & VertexFlags::V_EXCL; +						*f = u_excl << 1 | v_excl >> 1; +					}; +					if (flip_u) { +						uv[0] = 128 - uv[0]; +						*f ^= VertexFlags::U_EXCL; +					}; +					if (flip_v) { +						uv[1] = 128 - uv[1]; +						*f ^= VertexFlags::V_EXCL; +					}; +					uv[0] = sprite.x: u16 + (sprite.width * uv[0] >> 7): u16; +					uv[1] = sprite.y: u16 + (sprite.height * uv[1] >> 7): u16; +				}; + +				append(vertices, [ +					Vertex { position = face_vertices[0], normal = normal, texcoord = texcoord[face.rotation & 3], flags = flags[face.rotation & 3] }, +					Vertex { position = face_vertices[1], normal = normal, texcoord = texcoord[1 + face.rotation & 3], flags = flags[1 + face.rotation & 3] }, +					Vertex { position = face_vertices[2], normal = normal, texcoord = texcoord[2 + face.rotation & 3], flags = flags[2 + face.rotation & 3] }, +					Vertex { position = face_vertices[2], normal = normal, texcoord = texcoord[2 + face.rotation & 3], flags = flags[2 + face.rotation & 3] }, +					Vertex { position = face_vertices[3], normal = normal, texcoord = texcoord[3 + face.rotation & 3], flags = flags[3 + face.rotation & 3] }, +					Vertex { position = face_vertices[0], normal = normal, texcoord = texcoord[face.rotation & 3], flags = flags[face.rotation & 3] }, +				]...); +			}; +		}; +	}; + +	return vertices; +}; diff --git a/shaders.ha b/shaders.ha new file mode 100644 index 0000000..624892b --- /dev/null +++ b/shaders.ha @@ -0,0 +1,183 @@ +use gl::*; +use glw; +use trace; + +let VAO_BLOCKS: uint = 0; +let SHADER_BLOCKS: uint = 0; + +let VAO_GUI: uint = 0; +let SHADER_GUI: uint = 0; + +fn shaders_init() void = { +	trace::info(&trace::root, "loading shaders..."); + +	glGenVertexArrays(1, &VAO_BLOCKS); +	glBindVertexArray(VAO_BLOCKS); +	glEnableVertexAttribArray(0); +	glVertexAttribBinding(0, 0); +	glVertexAttribFormat(0, 3, GL_UNSIGNED_SHORT, 0, +		offset(Vertex { ... }.position): uint); +	glEnableVertexAttribArray(1); +	glVertexAttribBinding(1, 0); +	glVertexAttribFormat(1, 3, GL_BYTE, 1, +		offset(Vertex { ... }.normal): uint); +	glEnableVertexAttribArray(2); +	glVertexAttribBinding(2, 0); +	glVertexAttribFormat(2, 2, GL_UNSIGNED_SHORT, 0, +		offset(Vertex { ... }.texcoord): uint); +	glEnableVertexAttribArray(3); +	glVertexAttribBinding(3, 0); +	glVertexAttribIFormat(3, 1, GL_UNSIGNED_BYTE, +		offset(Vertex { ... }.flags): uint); +	glBindVertexArray(0); + +	SHADER_BLOCKS = glCreateProgram(); +	glAttachShader(SHADER_BLOCKS, glw::compile_shader_src( +		GL_VERTEX_SHADER, +		"#version 310 es + +		layout(location = 0) uniform mat4 u_transform; +		layout(location = 1) uniform vec3 u_position; +		layout(location = 2) uniform float u_texcoord_scale; + +		layout(location = 0) in vec3 a_position; +		layout(location = 1) in lowp vec3 a_normal; +		layout(location = 2) in vec2 a_texcoord; +		layout(location = 3) in lowp uint a_flags; + +		const lowp uint U_EXCL = 1u << 0u; +		const lowp uint V_EXCL = 1u << 1u; +		// the smallest value such that 1.0 - EPSILON < 1.0 +		const float EPSILON = 1.0 / float(1 << 24); + +		out lowp vec3 v_normal; +		out vec2 v_texcoord; + +		void main() { +			vec3 position = a_position * (1.0 / 2048.0) - 1.0 + u_position; +			gl_Position = u_transform * vec4(position, 1.0); +			v_normal = a_normal; +			v_texcoord = u_texcoord_scale * a_texcoord; +			// XXX: This fixes an issue with occassional texture +			// bleeding at the scale of individual pixels on the +			// bottom and right edges of a sprite, caused by the +			// interpolated texture coordinate coming out as equal +			// to the upper limit for that quad, which under +			// GL_NEAREST filtering actually belongs to a texel on +			// the wrong side of the sprite boundary. +			// +			// For whatever reason Mesa llvmpipe exhibits more +			// severe rounding errors on all sprite edges, where +			// v_texcoord in the fragment shader can be _below_ the +			// supposed lower bound. An EPSILON of 2^-16 applied +			// to all edges seems to be necessary in that case. +			// I assume this to be a numerical compromise in favor +			// of acceptable software rendering performance, but +			// wasn't able to find a mention of it anywhere +			// (I didn't look at the code, though), and the GL spec +			// doesn't seem to explicitly permit it, though I well +			// might be wrong about that. +			// +			// (2024 note): I am very tempted to remove all that and +			// replace it with 'Removes Herobrine. Do not touch.'. +			if ((a_flags & U_EXCL) != 0u) { +				v_texcoord.x -= EPSILON; +			} +			if ((a_flags & V_EXCL) != 0u) { +				v_texcoord.y -= EPSILON; +			} +		} +		", +	)); +	glAttachShader(SHADER_BLOCKS, glw::compile_shader_src( +		GL_FRAGMENT_SHADER, +		"#version 310 es + +		precision mediump float; + +		layout(location = 3) uniform mediump sampler2D tex_albedo; + +		in lowp vec3 v_normal; +		in highp vec2 v_texcoord; + +		layout(location = 0) out vec4 f_color; + +		void main() { +			vec4 albedo = texture(tex_albedo, v_texcoord); +			if (albedo.a < 0.1) { +				discard; +			} +			float light = 0.7 +				+ dot(vec3(0, 0.2, 0), v_normal) +				+ abs(dot(vec3(0.1, 0, 0), v_normal)); +			f_color = vec4(light * albedo.rgb, albedo.a); +		} +		", +	)); +	glw::link_program(SHADER_BLOCKS); +	glUseProgram(SHADER_BLOCKS); +	glUniform1f(2, 1.0 / ATLAS_BLOCKS.width: f32); +	glUniform1i(3, 0); + +	glGenVertexArrays(1, &VAO_GUI); +	glBindVertexArray(VAO_GUI); +	glEnableVertexAttribArray(0); +	glVertexAttribBinding(0, 0); +	glVertexAttribFormat(0, 2, GL_FLOAT, 0, +		offset(GuiVertex { ... }.position): uint); +	glEnableVertexAttribArray(1); +	glVertexAttribBinding(1, 0); +	glVertexAttribFormat(1, 2, GL_FLOAT, 0, +		offset(GuiVertex { ... }.texcoord): uint); +	glEnableVertexAttribArray(2); +	glVertexAttribBinding(2, 0); +	glVertexAttribFormat(2, 3, GL_UNSIGNED_BYTE, 1, +		offset(GuiVertex { ... }.color): uint); +	glBindVertexArray(0); + +	SHADER_GUI = glCreateProgram(); +	glAttachShader(SHADER_GUI, glw::compile_shader_src( +		GL_VERTEX_SHADER, +		"#version 310 es + +		layout(location = 0) uniform mat4 u_transform; + +		layout(location = 0) in vec2 a_position; +		layout(location = 1) in vec2 a_texcoord; +		layout(location = 2) in vec4 a_color; + +		out vec2 v_texcoord; +		out vec4 v_color; + +		void main() { +			gl_Position = u_transform * vec4(a_position, 0.0, 1.0); +			v_texcoord = a_texcoord; +			// XXX: crude srgb for now... +			v_color = vec4(pow(a_color.rgb, vec3(2.2)), a_color.a); +		} +		", +	)); +	glAttachShader(SHADER_GUI, glw::compile_shader_src( +		GL_FRAGMENT_SHADER, +		"#version 310 es + +		precision mediump float; + +		layout(location = 1) uniform sampler2D tex_color; + +		in vec2 v_texcoord; +		in vec4 v_color; + +		layout(location = 0) out vec4 f_color; + +		void main() { +			f_color = v_color * texture(tex_color, v_texcoord); +		} +		", +	)); +	glw::link_program(SHADER_GUI); +	glUseProgram(SHADER_GUI); +	glUniform1i(1, 0); + +	glUseProgram(0); +}; diff --git a/textures.ha b/textures.ha new file mode 100644 index 0000000..4045c85 --- /dev/null +++ b/textures.ha @@ -0,0 +1,375 @@ +use bufio; +use gl::*; +use io; +use os; +use image::png; +use math; +use strings; +use trace; + +type Texture = struct { +	Object, +	width: u32, +	height: u32, +	pack: nullable *Pack, +	gl_texture: uint, +}; + +let TEXTURES = OBJREG_EMPTY; +let TEXTURES_MAX_WIDTH = 0u16; + +fn textures_find(name: str) nullable *Texture = +	objreg_find(&TEXTURES, name): nullable *Texture; + +fn textures_register(tex: *Texture) void = +	objreg_register(&TEXTURES, tex); + +type TexturesIterator = struct { +	inner: ObjectRegistryIterator, +}; + +fn textures_iter() TexturesIterator = +	TexturesIterator { +		inner = objreg_iter(&TEXTURES), +	}; + +fn textures_next(it: *TexturesIterator) nullable *Texture = +	objreg_next(it): nullable *Texture; + +fn load_textures(assets: *Pack) void = { +	const tr = &trace::root; +	trace::info(tr, "loading textures..."); + +	let max_width = 0i32; +	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_width); +	assert(max_width > 0); +	// highest power of 2 representable in 16 bits +	if (max_width > 1 << 15) { +		max_width = 1 << 15; +	}; +	TEXTURES_MAX_WIDTH = max_width: u16; + +	textures_register_missingno(MISSINGNO); + +	const results = resource_search(assets, "textures", ".png"); +	for (let i = 0z; i < len(results); i += 1) { +		const (ident, ext) = results[i]; +		defer free(ident); +		const tr = trace::ctx(tr, "load texture info for {}", ident); + +		// TODO: better error handling, obviously +		match (load_texture_info(assets, ident, &tr)) { +		case void => void; +		case trace::failed => +			textures_register_missingno(ident); +		}; +	}; + +	let ntextures = 0z; +	let npixels = 0z; +	let it = textures_iter(); +	for (true) match (textures_next(&it)) { +	case let tex: *Texture => +		ntextures += 1; +		npixels += tex.width * tex.height; +	case null => break; +	}; +	trace::debug(tr, "loaded {} textures / {} pixels / {} bytes", +		ntextures, npixels, npixels * 4); +}; + +fn textures_register_missingno(name: str) void = { +	textures_register(alloc(Texture { +		name = strings::dup(name), +		width = 16, +		height = 16, +		pack = null, +		gl_texture = 0, +	})); +}; + +fn load_texture_info( +	assets: *Pack, +	ident: str, +	tr: *trace::tracer, +) (void | trace::failed) = { +	const f = resource_open(assets, "textures", ident, ".png", tr)?; +	let fclosed = false; +	defer if (!fclosed) io::close(f): void; + +	const reader = match (png::newreader(f)) { +	case let reader: png::reader => +		yield reader; +	case let err: png::error => +		return trace::error(tr, "png error: {}", png::strerror(err)); +	}; + +	match (png::nextchunk(&reader)) { +	case let ctype: u32 => +		if (ctype != png::IHDR) { +			return trace::error(tr, "Expected IHDR"); +		}; +	case io::EOF => +		return trace::error(tr, "Expected IHDR"); +	case let err: png::error => +		return trace::error(tr, "png error: {}", png::strerror(err)); +	}; + +	const ihdr = match (png::ihdr_read(&reader)) { +	case let ihdr: png::ihdr => +		yield ihdr; +	case let err: png::error => +		return trace::error(tr, "png error: {}", png::strerror(err)); +	}; + +	const res = io::close(f); +	fclosed = true; +	match (res) { +	case void => void; +	case let err: io::error => +		return trace::error(tr, "close: {}", io::strerror(err)); +	}; + +	match (textures_find(ident)) { +	case let tex: *Texture => +		abort("todo stacked assets"); +	case null => +		textures_register(alloc(Texture { +			name = strings::dup(ident), +			width = ihdr.width, +			height = ihdr.height, +			pack = assets, +			gl_texture = 0, +		})); +	}; +}; + +fn finish_textures() void = { +	let it = textures_iter(); +	for (true) match (textures_next(&it)) { +	case let tex: *Texture => +		free(tex.name); +	case null => break; +	}; +	objreg_clear(&TEXTURES); +}; + +fn texture_upload(tex: *Texture, tr: *trace::tracer) uint = { +	const tr = trace::ctx(tr, "upload texture {}", tex.name); + +	if (tex.gl_texture != 0) { +		return tex.gl_texture; +	}; + +	glGenTextures(1, &tex.gl_texture); +	glBindTexture(GL_TEXTURE_2D, tex.gl_texture); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, +		GL_NEAREST_MIPMAP_LINEAR: i32); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, +		GL_NEAREST: i32); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); +	const po2width = 1 << math::bit_size_u32(tex.width - 1): i32; +	const po2height = 1 << math::bit_size_u32(tex.height - 1): i32; +	glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8: i32, +		po2width, po2height, 0, +		GL_RGBA, GL_UNSIGNED_BYTE, null); + +	let pbo = 0u; +	glGenBuffers(1, &pbo); +	defer glDeleteBuffers(1, &pbo); +	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + +	const bufsize = tex.width * tex.height * 4; + +	for (true) { +		glBufferData(GL_PIXEL_UNPACK_BUFFER, +			bufsize: uintptr, null, GL_STREAM_DRAW); +		const pixels = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, +			0, bufsize: uintptr, GL_MAP_WRITE_BIT) as *opaque; +		texture_load(tex, pixels: *[*]u8, tex.width * 4, &tr); +		if (glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER) == GL_TRUE) { +			break; +		}; +		trace::warn(&tr, +			"glUnmapBuffer returned false; retrying upload"); +	}; + +	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, +		tex.width: i32, tex.height: i32, +		GL_RGBA, GL_UNSIGNED_BYTE, null); +	glGenerateMipmap(GL_TEXTURE_2D); + +	return tex.gl_texture; +}; + +fn texture_load(tex: *Texture, out: *[*]u8, stride: size, tr: *trace::tracer) void = { +	match (texture_try_load(tex, out, stride, tr)) { +	case void => void; +	case trace::failed => +		texture_load_missingno(tex.width, tex.height, out, stride); +	}; +}; + +fn texture_try_load( +	tex: *Texture, +	out: *[*]u8, +	stride: size, +	tr: *trace::tracer, +) (void | trace::failed) = { +	const assets = match (tex.pack) { +	case let assets: *Pack => +		yield assets; +	case null => +		return trace::failed; +	}; + +	const f = resource_open(assets, "textures", tex.name, ".png", tr)?; +	let fclosed = false; +	defer if (!fclosed) io::close(f): void; + +	let rbuf: [os::BUFSZ]u8 = [0...]; +	let buf = bufio::init(f, rbuf, []); + +	// TODO: write directly to output buffer. +	const png = match (png::load(&buf)) { +	case let image: png::image => +		yield image; +	case let err: png::error => +		return trace::error(tr, "png::load: {}", png::strerror(err)); +	}; +	defer png::image_finish(&png); + +	const width = png.ihdr.width; +	const height = png.ihdr.height; + +	if (width != tex.width || height != tex.height) { +		return trace::error(tr, "Header changed while loading"); +	}; + +	const end = stride * height; +	const rowpad = stride - (width << 2); +	const irowpad = 8 - width * png.ihdr.bitdepth & 7; + +	switch (png.ihdr.colortype) { +	case png::colortype::GRAYSCALE => +		if (png.ihdr.bitdepth != 8) { +			return trace::error(tr, +				"Bit depths other than 8 are not supported"); +		}; +		let i = 0z; +		let o = 0z; +		for (o < end) { +			const rowend = o + (width << 2); +			for (o < rowend) { +				// TODO: out[o + n] (...) o += 4; might actually +				// be faster due to pipelining weirdness... +				const v = png.pixels[i]; +				i += 1; +				out[o] = v; o += 1; +				out[o] = v; o += 1; +				out[o] = v; o += 1; +				out[o] = 255; o += 1; +			}; +			o += rowpad; +		}; +	case png::colortype::RGB => +		if (png.ihdr.bitdepth != 8) { +			return trace::error(tr, +				"Bit depths other than 8 are not supported"); +		}; +		let i = 0z; +		let o = 0z; +		for (o < end) { +			const rowend = o + (width << 2); +			for (o < rowend) { +				out[o] = png.pixels[i]; i += 1; o += 1; +				out[o] = png.pixels[i]; i += 1; o += 1; +				out[o] = png.pixels[i]; i += 1; o += 1; +				out[o] = 255; o += 1; +			}; +			o += rowpad; +		}; +	case png::colortype::PLTE => +		const mask = (1 << png.ihdr.bitdepth) - 1; +		let i = 0z; +		let o = 0z; +		for (o < end) { +			const rowend = o + (width << 2); +			for (o < rowend) { +				const index = png.pixels[i >> 3] +					>> (i & 7) & mask; +				const p = png.palette[index]; +				i += png.ihdr.bitdepth; +				out[o] = (p >> 24): u8; o += 1; +				out[o] = (p >> 16): u8; o += 1; +				out[o] = (p >> 8): u8; o += 1; +				out[o] = 255; o += 1; +			}; +			i += irowpad; +			o += rowpad; +		}; +	case png::colortype::GRAYALPHA => +		if (png.ihdr.bitdepth != 8) { +			return trace::error(tr, +				"Bit depths other than 8 are not supported"); +		}; +		let i = 0z; +		let o = 0z; +		for (o < end) { +			const rowend = o + (width << 2); +			for (o < rowend) { +				const v = png.pixels[i]; +				i += 1; +				out[o] = v; o += 1; +				out[o] = v; o += 1; +				out[o] = v; o += 1; +				out[o] = png.pixels[i]; i += 1; o += 1; +			}; +			o += rowpad; +		}; +	case png::colortype::RGBA => +		if (png.ihdr.bitdepth != 8) { +			return trace::error(tr, +				"Bit depths other than 8 are not supported"); +		}; +		let i = 0z; +		let o = 0z; +		for (o < end) { +			out[o..o + (width << 2)] = +				png.pixels[i..i + (width << 2)]; +			i += width << 2; +			o += stride; +		}; +	case => +		return trace::error(tr, "Unknown color type {}", +			png.ihdr.colortype: u8); +	}; + +	const res = io::close(f); +	fclosed = true; +	match (res) { +	case void => void; +	case let err: io::error => +		return trace::error(tr, "close: {}", io::strerror(err)); +	}; + +	return; +}; + +fn texture_load_missingno(width: u32, height: u32, out: *[*]u8, stride: size) +		void = { +	for (let y = 0u32; y < height; y += 1) +	for (let x = 0u32; x < width; x += 1) { +		const i = (x: size << 2) + y * stride; +		if (x < width >> 1 == y < height >> 1) { +			out[i] = 0; +			out[i + 1] = 0; +			out[i + 2] = 0; +		} else { +			out[i] = 255; +			out[i + 1] = 0; +			out[i + 2] = 255; +		}; +		out[i + 3] = 255; +	}; +}; diff --git a/trace/ctx.ha b/trace/ctx.ha new file mode 100644 index 0000000..26a1ce6 --- /dev/null +++ b/trace/ctx.ha @@ -0,0 +1,33 @@ +use fmt; + +export type ctxtracer = struct { +	tracer, +	sink: *tracer, +	fmt: str, +	fields: []fmt::field, +}; + +export fn ctx(sink: *tracer, fmt: str, fields: fmt::field...) ctxtracer = { +	return ctxtracer { +		log = &ctx_log, +		sink = sink, +		fmt = fmt, +		fields = fields, +	}; +}; + +fn ctx_log( +	tr: *tracer, +	ctx: nullable *context, +	lvl: level, +	fmt: str, +	fields: fmt::field... +) void = { +	const tr = tr: *ctxtracer; +	const ctx_ = context { +		fmt = tr.fmt, +		fields = tr.fields, +		next = ctx, +	}; +	log(tr.sink, &ctx_, lvl, fmt, fields...); +}; diff --git a/trace/root.ha b/trace/root.ha new file mode 100644 index 0000000..dbae0d1 --- /dev/null +++ b/trace/root.ha @@ -0,0 +1,21 @@ +use fmt; + +export let root = tracer { +	log = &root_log, +}; + +let cur_root = &silent; + +export fn setroot(tr: *tracer) void = { +	cur_root = tr; +}; + +fn root_log( +	tr: *tracer, +	ctx: nullable *context, +	lvl: level, +	fmt: str, +	fields: fmt::field... +) void = { +	log(cur_root, ctx, lvl, fmt, fields...); +}; diff --git a/trace/silent.ha b/trace/silent.ha new file mode 100644 index 0000000..4fdcde3 --- /dev/null +++ b/trace/silent.ha @@ -0,0 +1,15 @@ +use fmt; + +export const silent = tracer { +	log = &silent_log, +}; + +fn silent_log( +	tr: *tracer, +	ctx: nullable *context, +	lvl: level, +	fmt: str, +	fields: fmt::field... +) void = { +	void; +}; diff --git a/trace/tee.ha b/trace/tee.ha new file mode 100644 index 0000000..53bd9ea --- /dev/null +++ b/trace/tee.ha @@ -0,0 +1,26 @@ +use fmt; + +export type teetracer = struct { +	tracer, +	sinks: []*tracer, +}; + +export fn tee(sinks: *tracer...) teetracer = { +	return teetracer { +		log = &tee_log, +		sinks = sinks, +	}; +}; + +export fn tee_log( +	tr: *tracer, +	ctx: nullable *context, +	lvl: level, +	fmt: str, +	fields: fmt::field... +) void = { +	const tr = tr: *teetracer; +	for (let i = 0z; i < len(tr.sinks); i += 1) { +		log(tr.sinks[i], ctx, lvl, fmt, fields...); +	}; +}; diff --git a/trace/trace.ha b/trace/trace.ha new file mode 100644 index 0000000..a096bd3 --- /dev/null +++ b/trace/trace.ha @@ -0,0 +1,60 @@ +use fmt; + +export type failed = !void; + +export type level = enum u8 { +	ERROR, +	WARN, +	INFO, +	DEBUG, +	TRACE, +}; + +export type context = struct { +	fmt: str, +	fields: []fmt::field, +	next: nullable *context, +}; + +export type tracer = struct { +	log: *logfunc, +}; + +export type logfunc = fn( +	tr: *tracer, +	ctx: nullable *context, +	lvl: level, +	fmt: str, +	fields: fmt::field... +) void; + +export fn log( +	tr: *tracer, +	ctx: nullable *context, +	lvl: level, +	fmt: str, +	fields: fmt::field... +) void = { +	tr.log(tr, ctx, lvl, fmt, fields...); +}; + +export fn error(tr: *tracer, fmt: str, fields: fmt::field...) failed = { +	log(tr, null, level::ERROR, fmt, fields...); +	return failed; +}; + +export fn warn(tr :*tracer, fmt: str, fields: fmt::field...) void = { +	log(tr, null, level::WARN, fmt, fields...); +}; + +export fn info(tr: *tracer, fmt: str, fields: fmt::field...) void = { +	log(tr, null, level::INFO, fmt, fields...); +}; + +export fn debug(tr: *tracer, fmt: str, fields: fmt::field...) void = { +	log(tr, null, level::DEBUG, fmt, fields...); +}; + +export fn trace(tr: *tracer, fmt: str, fields: fmt::field...) void = { +	log(tr, null, level::TRACE, fmt, fields...); +}; diff --git a/tracer+android.ha b/tracer+android.ha new file mode 100644 index 0000000..2e69527 --- /dev/null +++ b/tracer+android.ha @@ -0,0 +1,43 @@ +use fmt; +use io; +use memio; +use strings; +use trace; + +type Tracer = struct { +	trace::tracer, +}; + +fn newtracer() Tracer = +	Tracer { +		log = &tracer_log, +	}; + +fn tracer_log( +	tr: *trace::tracer, +	ctx: nullable *trace::context, +	lvl: trace::level, +	fmt: str, +	fields: fmt::field... +) void = { +	// XXX: ideally there would be a statically allocated buffer for +	// reasonably short messages and allocation would only happen for +	// messages longer than that. ideally ideally there would be locking so +	// we wouldn't need to allocate at all. +	const buf = memio::dynamic_from(alloc([], 256)); +	defer io::close(&buf)!; + +	let ctx_ = ctx; +	for (true) match (ctx_) { +	case let ctx__: *trace::context => +		fmt::fprintf(&buf, ctx__.fmt, ctx__.fields...)!; +		io::write(&buf, [0x3a, 0x20])!; // ": " +		ctx_ = ctx__.next; +	case null => break; +	}; + +	fmt::fprintfln(&buf, fmt, fields...)!; + +	const prio = 6 - lvl: int; +	androlog(prio, memio::string(&buf)!); +}; diff --git a/tracer.ha b/tracer.ha new file mode 100644 index 0000000..99f4189 --- /dev/null +++ b/tracer.ha @@ -0,0 +1,66 @@ +use memio; +use time::date; +use fmt; +use io; +use strings; +use trace; + +type Tracer = struct { +	trace::tracer, +	sink: io::handle, +}; + +fn newtracer(sink: io::handle) Tracer = +	Tracer { +		log = &tracer_log, +		sink = sink, +	}; + +fn tracer_log( +	tr: *trace::tracer, +	ctx: nullable *trace::context, +	lvl: trace::level, +	fmt: str, +	fields: fmt::field... +) void = { +	const tr = tr: *Tracer; + +	// XXX: ideally there would be a statically allocated buffer for +	// reasonably short messages and allocation would only happen for +	// messages longer than that. ideally ideally there would be locking so +	// we wouldn't need to allocate at all. +	const buf = memio::dynamic_from(alloc([], 256)); +	defer io::close(&buf)!; + +	const now = date::now(); +	io::write(&buf, [0x5b])!; // "[" +	date::format(&buf, date::STAMP, &now)!; +	io::write(&buf, [0x5d, 0x20])!; // "] " + +	const lvlstr = switch (lvl) { +	case trace::level::ERROR => +		yield "error: "; +	case trace::level::WARN => +		yield "warning: "; +	case trace::level::INFO => +		yield "info: "; +	case trace::level::DEBUG => +		yield "debug: "; +	case trace::level::TRACE => +		yield "trace: "; +	}; +	io::write(&buf, strings::toutf8(lvlstr))!; + +	let ctx_ = ctx; +	for (true) match (ctx_) { +	case let ctx__: *trace::context => +		fmt::fprintf(&buf, ctx__.fmt, ctx__.fields...)!; +		io::write(&buf, [0x3a, 0x20])!; // ": " +		ctx_ = ctx__.next; +	case null => break; +	}; + +	fmt::fprintfln(&buf, fmt, fields...)!; + +	io::write(tr.sink, memio::buffer(&buf)): void; +}; diff --git a/window.ha b/window.ha new file mode 100644 index 0000000..9d3d129 --- /dev/null +++ b/window.ha @@ -0,0 +1,333 @@ +use fs; +use gl; +use gl::*; +use glm; +use glw; +use math; +use net; +use os; +use sdl2; +use sdl2::*; +use time; +use trace; +use types::c; + +type Window = struct { +	timestamp: time::instant, + +	scale: u16, +	gui_proj: glm::m4, + +	mouse_x: f32, +	mouse_y: f32, +	held_keys: []Key, +	held_mouse_buttons: [5]bool, +	input_bottom: size, + +	window: *SDL_Window, +}; + +let WINDOW: (Window | void) = void; + +// XXX: hack to get around a temporary limitation of tagged unions. +// this will actually stop working once that's resolved... +fn get_WINDOW() *Window = { +	WINDOW as Window; + +	return (&WINDOW: uintptr +		+ offset(struct { +			tag: int = 0, +			w: Window = Window { window = null: *SDL_Window, ... }, +		}.w): uintptr): *Window; +}; + +fn gl_get_proc_address(procname: *const c::char) *opaque = +	SDL_GL_GetProcAddress(procname); + +fn window_run(addr: str, username: str) void = { +	match (SDL_Init(SDL_INIT_VIDEO)) { +	case void => void; +	case let err: sdl2::error => +		die("failed to initialize sdl: {}", err); +	}; +	defer SDL_Quit(); + +	trace::info(&trace::root, "using video {}", +		SDL_GetCurrentVideoDriver()); + +	match (window_init_gl_attrs()) { +	case void => void; +	case let err: sdl2::error => +		die("failed to set gl attributes: {}", err); +	}; + +	const window = match (SDL_CreateWindow( +		"hacraft", +		SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, +		640, 480, +		SDL_WindowFlags::RESIZABLE +		| SDL_WindowFlags::ALLOW_HIGHDPI +		| SDL_WindowFlags::OPENGL)) { +	case let window: *SDL_Window => +		yield window; +	case let err: sdl2::error => +		die("failed to create window: {}", err); +	}; +	defer SDL_DestroyWindow(window); + +	match (SDL_GL_CreateContext(window)) { +	case *SDL_GLContext => void; +	case let err: sdl2::error => +		die("failed to create gl context: {}", err); +	}; +	gl::load_with_fn(&gl_get_proc_address); + +	trace::info(&trace::root, "using opengl {} / glsl {} / on {} {}", +		glw::get_string(GL_VERSION), +		glw::get_string(GL_SHADING_LANGUAGE_VERSION), +		glw::get_string(GL_VENDOR), +		glw::get_string(GL_RENDERER)); +	glw::init_debug_logging(); + +	match (SDL_SetRelativeMouseMode(true)) { +	case void => void; +	case let err: sdl2::error => +		trace::error(&trace::root, +			"Failed to enable relative mouse: {}", +			err): void; +	}; + +	match (SDL_GL_SetSwapInterval(0)) { +	case void => void; +	case let err: sdl2::error => +		trace::error(&trace::root, +			"Failed to set swap interval: {}", +			err): void; +	}; + +	WINDOW = Window { +		timestamp = time::now(time::clock::MONOTONIC), + +		scale = 1, +		gui_proj = glm::m4_new_ident(), + +		mouse_x = 0.0, +		mouse_y = 0.0, +		held_keys = [], +		held_mouse_buttons = [false...], +		input_bottom = 0, + +		window = window, +	}; +	defer WINDOW = void; + +	register_blocks(); +	defer destroy_blocks(); + +	init_bstates(); +	defer destroy_bstates(); + +	const assets = os::diropen("resources")!; +	defer fs::close(assets); +	const assets = Pack { +		fs = assets, +		kind = "assets", +	}; +	render_init(&assets); +	defer render_destroy(); + +	client_connect(addr, username); +	defer client_destroy(); + +	for (window_frame()) void; +}; + +fn window_init_gl_attrs() (void | sdl2::error) = { +	SDL_GL_SetAttribute(SDL_GLattr::GL_CONTEXT_PROFILE_MASK, +		SDL_GLprofile::GL_CONTEXT_PROFILE_ES)?; +	SDL_GL_SetAttribute(SDL_GLattr::GL_CONTEXT_MAJOR_VERSION, 3)?; +	SDL_GL_SetAttribute(SDL_GLattr::GL_CONTEXT_MINOR_VERSION, 2)?; +	SDL_GL_SetAttribute(SDL_GLattr::GL_DEPTH_SIZE, 24)?; +	SDL_GL_SetAttribute(SDL_GLattr::GL_CONTEXT_FLAGS, SDL_GLcontextFlag::GL_CONTEXT_DEBUG_FLAG)?; +	SDL_GL_SetAttribute(SDL_GLattr::GL_FRAMEBUFFER_SRGB_CAPABLE, 1)?; +}; + +fn drawable_size() (u16, u16) = { +	const WINDOW = get_WINDOW(); +	let width = 0, height = 0; +	SDL_GL_GetDrawableSize(WINDOW.window, &width, &height); +	assert(width == width: u16: int +		&& height == height: u16: int, "the fuck?"); +	return (width: u16, height: u16); +}; + +fn frame_timestamp() time::instant = { +	const WINDOW = get_WINDOW(); +	return WINDOW.timestamp; +}; + +fn gui_scale() u16 = { +	const WINDOW = get_WINDOW(); +	return WINDOW.scale; +}; + +fn gui_proj() *glm::m4 = { +	const WINDOW = get_WINDOW(); +	return &WINDOW.gui_proj; +}; + +fn window_frame() bool = { +	const WINDOW = get_WINDOW(); + +	window_update_layer_input(); + +	for (true) { +		let event = sdl2::event { ... }; +		match (SDL_PollEvent(&event)) { +		case let pending: int => +			if (pending == 0) break; +		case let err: sdl2::error => +			trace::error(&trace::root, "SDL error: {}", err): void; +			return false; +		}; + +		if (event.event_type == SDL_EventType::QUIT) { +			return false; +		}; + +		window_event(&event); +	}; + +	const (width, height) = drawable_size(); +	const xscale = width / 320; +	const yscale = height / 240; +	WINDOW.scale = if (xscale < yscale) xscale else yscale; +	if (WINDOW.scale == 0) { +		WINDOW.scale = 1; +	}; + +	glm::m4_set_ident(&WINDOW.gui_proj); +	glm::scale(&WINDOW.gui_proj, +		&[gui_scale(): f32, gui_scale(): f32, 1.0]); +	glm::scale(&WINDOW.gui_proj, +		&[2.0 / width: f32, -2.0 / height: f32, 1.0]); +	glm::translate(&WINDOW.gui_proj, &[-1.0f32, 1.0, 0.0]); + +	client_frame(); +	layers_render(); + +	SDL_GL_SwapWindow(WINDOW.window); + +	const then = WINDOW.timestamp; +	WINDOW.timestamp = time::now(time::clock::MONOTONIC); + +	const dt = time::diff(then, WINDOW.timestamp); +	const dt = (dt: f64 / 1000000000.0): f32; +	const (sec, subsec) = math::modfracf32(dt); +//	trace::debug(&trace::root, "frame took {}.{:03} s / fps {}", +//		sec, (subsec * 1000.0): i32, 1.0 / dt); + +	return true; +}; + +fn window_event(event: *sdl2::event) void = { +	const WINDOW = get_WINDOW(); + +	switch (event.event_type) { +	case SDL_EventType::KEYDOWN => +		const key_event = KeyEvent { +			status = ButtonStatus::DOWN, +			key = event.key.keysym.scancode: Key, +		}; +		if (event.key.repeat == 0) { +			append(WINDOW.held_keys, key_event.key); +		}; +		layers_input(key_event, len(LAYERS), false); +		window_update_layer_input(); +	case SDL_EventType::KEYUP => +		let key_event = KeyEvent { +			status = ButtonStatus::UP, +			key = event.key.keysym.scancode: Key, +		}; +		for (let i = 0z; i < len(WINDOW.held_keys)) { +			if (WINDOW.held_keys[i] != key_event.key) { +				i += 1; +				continue; +			}; +			delete(WINDOW.held_keys[i]); +		}; +		layers_input(key_event, len(LAYERS), false); +		window_update_layer_input(); +	case SDL_EventType::MOUSEBUTTONDOWN => +		WINDOW.held_mouse_buttons[event.button.button] = true; +		layers_input(MouseButtonEvent { +			status = ButtonStatus::DOWN, +			button = event.button.button: MouseButton, +		}, len(LAYERS), false); +		window_update_layer_input(); +	case SDL_EventType::MOUSEBUTTONUP => +		WINDOW.held_mouse_buttons[event.button.button] = false; +		layers_input(MouseButtonEvent { +			status = ButtonStatus::UP, +			button = event.button.button: MouseButton, +		}, len(LAYERS), false); +		window_update_layer_input(); +	case SDL_EventType::MOUSEMOTION => +		WINDOW.mouse_x = event.motion.x: f32 / gui_scale(): f32; +		WINDOW.mouse_y = event.motion.y: f32 / gui_scale(): f32; +		window_update_mouse_over(); +	case => void; +	}; +}; + +fn window_update_layer_input() void = { +	const WINDOW = get_WINDOW(); + +	let bottom = len(LAYERS); +	for (bottom != 0) { +		bottom -= 1; +		if (LAYERS[bottom].blocks_input()) { +			break; +		}; +	}; + +	if (bottom > WINDOW.input_bottom) { +		layers_input(CancelEvent, bottom, true); +		WINDOW.input_bottom = bottom; +	} else if (bottom < WINDOW.input_bottom) { +		const old_bottom = WINDOW.input_bottom; +		WINDOW.input_bottom = bottom; +		window_uncancel(old_bottom); +	}; + +	window_update_mouse_over(); +}; + +fn window_uncancel(top: size) void = { +	const WINDOW = get_WINDOW(); + +	window_update_mouse_over(); + +	for (let i = 0z; i < len(WINDOW.held_keys); i += 1) { +		layers_input(KeyEvent { +			status = ButtonStatus::HELD, +			key = WINDOW.held_keys[i], +		}, top, true); +	}; + +	for (let i = 0z; i < len(WINDOW.held_mouse_buttons); i += 1) { +		if (!WINDOW.held_mouse_buttons[i]) { +			continue; +		}; +		layers_input(MouseButtonEvent { +			status = ButtonStatus::HELD, +			button = i: MouseButton, +		}, top, true); +	}; +}; + +fn window_update_mouse_over() void = { +	const i = layers_input(MouseOverEvent { covered = false }, +		len(LAYERS), false); +	layers_input(MouseOverEvent { covered = true }, i, true); +};  | 
