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); +}; |