summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLassi Pulkkinen <lassi@pulk.fi>2024-10-31 03:11:21 +0200
committerLassi Pulkkinen <lassi@pulk.fi>2024-10-31 03:51:35 +0200
commitae44478b30d890fe0fb04022f44d474dcdcc3f9d (patch)
tree5f462459ae4b47d22114eed717d1382d08cf4dfe
Initial commit (import old repo)HEADmain
-rw-r--r--+android.ha13
-rw-r--r--.gitignore2
-rw-r--r--COPYING674
-rw-r--r--Makefile15
-rw-r--r--README83
-rw-r--r--android/build.gradle43
-rw-r--r--android/jni/CMakeLists.txt35
-rwxr-xr-xandroid/jni/as11
-rw-r--r--android/jni/dummy.c1
-rw-r--r--android/jni/main.c7
-rw-r--r--android/settings.gradle13
-rw-r--r--android/src/main/AndroidManifest.xml64
-rw-r--r--android/src/main/java/fi/pulk/hacraft/MainActivity.java5
-rw-r--r--android/src/main/res/values/colors.xml6
-rw-r--r--android/src/main/res/values/strings.xml3
-rw-r--r--android/src/main/res/values/styles.xml8
-rw-r--r--atlas.ha337
-rw-r--r--blocks.ha18
-rw-r--r--bstates.ha107
-rw-r--r--chunks.ha221
-rw-r--r--client.ha239
-rw-r--r--comparray/+test.ha52
-rw-r--r--comparray/array.ha210
-rw-r--r--content_blocks.ha3557
-rw-r--r--control.ha71
-rw-r--r--death.ha163
-rw-r--r--dejson/dejson.ha286
-rw-r--r--encoding/json/+test/lexer.ha62
-rw-r--r--encoding/json/+test/test_load.ha164
-rw-r--r--encoding/json/+test/test_value.ha49
-rw-r--r--encoding/json/COPYING367
-rw-r--r--encoding/json/README15
-rw-r--r--encoding/json/dump.ha81
-rw-r--r--encoding/json/lex.ha417
-rw-r--r--encoding/json/load.ha148
-rw-r--r--encoding/json/path/path.ha26
-rw-r--r--encoding/json/types.ha50
-rw-r--r--encoding/json/value.ha217
-rw-r--r--fonts.ha491
-rw-r--r--game.ha238
-rw-r--r--gl/gl.ha6059
-rw-r--r--glm/LICENSE8
-rw-r--r--glm/affine.ha80
-rw-r--r--glm/camera.ha71
-rw-r--r--glm/m4.ha105
-rw-r--r--glm/types.ha7
-rw-r--r--glm/util.ha9
-rw-r--r--glm/v2.ha10
-rw-r--r--glm/v3.ha127
-rw-r--r--glm/v4.ha105
-rw-r--r--glw/debug.ha34
-rw-r--r--glw/glw.ha91
-rw-r--r--htab/+test.ha61
-rw-r--r--htab/README8
-rw-r--r--htab/table.ha254
-rw-r--r--hud.ha258
-rw-r--r--ident.ha19
-rw-r--r--idreg.ha72
-rw-r--r--image/README0
-rw-r--r--image/png/COPYING367
-rw-r--r--image/png/README8
-rw-r--r--image/png/decoder.ha171
-rw-r--r--image/png/errors.ha35
-rw-r--r--image/png/filter.ha75
-rw-r--r--image/png/idat.ha82
-rw-r--r--image/png/iend.ha27
-rw-r--r--image/png/ihdr.ha114
-rw-r--r--image/png/load.ha88
-rw-r--r--image/png/paeth.ha30
-rw-r--r--image/png/plte.ha95
-rw-r--r--image/png/reader.ha175
-rw-r--r--image/png/test_data.ha638
-rw-r--r--image/png/types.ha69
-rw-r--r--keys.ha214
-rw-r--r--layers.ha73
-rw-r--r--login.ha64
-rw-r--r--main+android.ha38
-rw-r--r--main.ha60
-rw-r--r--mcproto/+test.ha47
-rw-r--r--mcproto/decode.ha193
-rw-r--r--mcproto/encode.ha51
-rw-r--r--mcproto/error.ha1
-rw-r--r--mcproto/frame.ha22
-rw-r--r--mcproto/handshake.ha46
-rw-r--r--mcproto/packet.ha13
-rw-r--r--mcproto/status/ids.ha5
-rw-r--r--mcproto/status/ping.ha9
-rw-r--r--mcproto/status/response.ha111
-rw-r--r--models.ha653
-rw-r--r--nbt/load.ha152
-rw-r--r--nbt/value.ha141
-rw-r--r--objreg.ha64
-rw-r--r--player.ha67
-rw-r--r--position.ha49
-rw-r--r--proto.ha715
-rw-r--r--recv.ha105
-rw-r--r--render.ha94
-rw-r--r--render_bstates.ha559
-rw-r--r--render_chunks.ha113
-rw-r--r--render_gui.ha73
-rw-r--r--resource.ha191
-rwxr-xr-xscripts/gen_blocks55
-rw-r--r--sdl2/COPYING371
-rw-r--r--sdl2/audio.ha31
-rw-r--r--sdl2/blendmode.ha11
-rw-r--r--sdl2/errors.ha31
-rw-r--r--sdl2/events.ha494
-rw-r--r--sdl2/gamecontroller.ha99
-rw-r--r--sdl2/gl.ha82
-rw-r--r--sdl2/image/image.ha46
-rw-r--r--sdl2/joystick.ha12
-rw-r--r--sdl2/keyboard.ha654
-rw-r--r--sdl2/mixer/channels.ha20
-rw-r--r--sdl2/mixer/general.ha54
-rw-r--r--sdl2/mixer/samples.ha38
-rw-r--r--sdl2/mouse.ha58
-rw-r--r--sdl2/pixels.ha55
-rw-r--r--sdl2/rect.ha29
-rw-r--r--sdl2/render.ha371
-rw-r--r--sdl2/rwops.ha134
-rw-r--r--sdl2/sdl2.ha23
-rw-r--r--sdl2/surface.ha53
-rw-r--r--sdl2/timer.ha32
-rw-r--r--sdl2/video.ha141
-rw-r--r--section_geometry.ha164
-rw-r--r--shaders.ha183
-rw-r--r--textures.ha375
-rw-r--r--trace/ctx.ha33
-rw-r--r--trace/root.ha21
-rw-r--r--trace/silent.ha15
-rw-r--r--trace/tee.ha26
-rw-r--r--trace/trace.ha60
-rw-r--r--tracer+android.ha43
-rw-r--r--tracer.ha66
-rw-r--r--window.ha333
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
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/COPYING
@@ -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)
diff --git a/README b/README
new file mode 100644
index 0000000..f5a8735
--- /dev/null
+++ b/README
@@ -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(&section.bstates);
+ for (let i = 0u8; i < len(palette); i += 1) {
+ if (palette[i] == bstate)
+ yield :ref, i: u16;
+ };
+
+ comparray::grow_palette(&section.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(&section.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(&section.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 &sections[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(&sections[i]);
+ };
+
+ free(sections);
+ chunk.sections = null;
+};
+
+fn section_destroy(section: *Section) void = {
+ render_chunks_section_destroy(section);
+ comparray::clear(&section.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,
+ };
+};
diff --git a/game.ha b/game.ha
new file mode 100644
index 0000000..c44ef89
--- /dev/null
+++ b/game.ha
@@ -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;
+};
diff --git a/hud.ha b/hud.ha
new file mode 100644
index 0000000..d39dc3d
--- /dev/null
+++ b/hud.ha
@@ -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(&reg.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(&reg.nametoid, hash, size(u32));
+ *(entry: *u32) = id;
+
+ return id;
+};
+
+fn idreg_clear(reg: *IdRegistry) void = {
+ strings::freeall(reg.idtoname);
+ htab::finish(&reg.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);
+};
diff --git a/keys.ha b/keys.ha
new file mode 100644
index 0000000..c536251
--- /dev/null
+++ b/keys.ha
@@ -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);
+};
diff --git a/main.ha b/main.ha
new file mode 100644
index 0000000..0b1737c
--- /dev/null
+++ b/main.ha
@@ -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(&reg.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(&reg.table, hash, size(*Object));
+ *(entry: **Object) = obj;
+};
+
+fn objreg_count(reg: *ObjectRegistry) size =
+ htab::count(&reg.table);
+
+fn objreg_clear(reg: *ObjectRegistry) void =
+ htab::clear(&reg.table, size(*Object));
+
+type ObjectRegistryIterator = struct {
+ inner: htab::iterator,
+};
+
+fn objreg_iter(reg: *ObjectRegistry) ObjectRegistryIterator =
+ ObjectRegistryIterator {
+ inner = htab::iter(&reg.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(&registry, "minecraft:dimension_type")) {
+ case let reg: nbt::Object =>
+ match (nbt_get(&reg, "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;
+ };
+};
diff --git a/recv.ha b/recv.ha
new file mode 100644
index 0000000..d1efe59
--- /dev/null
+++ b/recv.ha
@@ -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, &section.vertexbuf);
+ section.vertexbuf = 0;
+ };
+ return true;
+ };
+
+ if (section.vertexbuf == 0) {
+ glGenBuffers(1, &section.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, &section.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(&section.bstates, comparray::get(&section.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(&section_.bstates, comparray::get(&section_.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);
+};