From 156021347f8d9a7f67b59161d60fd784189be2a9 Mon Sep 17 00:00:00 2001 From: IllusionMan1212 Date: Fri, 19 Jan 2024 23:55:07 +0200 Subject: [PATCH] initial --- .gitignore | 2 + assets/fonts/Roboto/LICENSE.txt | 202 +++ assets/fonts/Roboto/Roboto-Bold.ttf | Bin 0 -> 167336 bytes assets/fonts/Rubik/OFL.txt | 93 ++ .../fonts/Rubik/Rubik-VariableFont_wght.ttf | Bin 0 -> 356080 bytes assets/icon-128x128.png | Bin 0 -> 2832 bytes assets/icons/close.png | Bin 0 -> 581 bytes assets/icons/help.png | Bin 0 -> 2469 bytes assets/icons/settings.png | Bin 0 -> 1302 bytes freetype/types.odin | 314 +++++ freetype/wrapper.odin | 18 + game.odin | 1177 ++++++++++++++++ glx/constants.odin | 11 + glx/wrappers.odin | 97 ++ main.odin | 18 + shaders/color_chooser.frag | 32 + shaders/font.frag | 21 + shaders/font.vert | 21 + shaders/ui.frag | 40 + shaders/ui.vert | 11 + xcursor/wrapper.odin | 9 + zephr/audio.odin | 3 + zephr/shader.odin | 57 + zephr/text.odin | 419 ++++++ zephr/texture.odin | 45 + zephr/timer.odin | 35 + zephr/ui.odin | 938 +++++++++++++ zephr/zephr.odin | 1250 +++++++++++++++++ zephr/zephr_math.odin | 147 ++ 29 files changed, 4960 insertions(+) create mode 100644 .gitignore create mode 100644 assets/fonts/Roboto/LICENSE.txt create mode 100644 assets/fonts/Roboto/Roboto-Bold.ttf create mode 100644 assets/fonts/Rubik/OFL.txt create mode 100644 assets/fonts/Rubik/Rubik-VariableFont_wght.ttf create mode 100644 assets/icon-128x128.png create mode 100644 assets/icons/close.png create mode 100644 assets/icons/help.png create mode 100644 assets/icons/settings.png create mode 100644 freetype/types.odin create mode 100644 freetype/wrapper.odin create mode 100644 game.odin create mode 100644 glx/constants.odin create mode 100644 glx/wrappers.odin create mode 100644 main.odin create mode 100644 shaders/color_chooser.frag create mode 100644 shaders/font.frag create mode 100644 shaders/font.vert create mode 100644 shaders/ui.frag create mode 100644 shaders/ui.vert create mode 100644 xcursor/wrapper.odin create mode 100644 zephr/audio.odin create mode 100644 zephr/shader.odin create mode 100644 zephr/text.odin create mode 100644 zephr/texture.odin create mode 100644 zephr/timer.odin create mode 100644 zephr/ui.odin create mode 100644 zephr/zephr.odin create mode 100644 zephr/zephr_math.odin diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..37bc568 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +o2048 +ols.json diff --git a/assets/fonts/Roboto/LICENSE.txt b/assets/fonts/Roboto/LICENSE.txt new file mode 100644 index 0000000..75b5248 --- /dev/null +++ b/assets/fonts/Roboto/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/assets/fonts/Roboto/Roboto-Bold.ttf b/assets/fonts/Roboto/Roboto-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..43da14d84ecb949ca5f5e8ecca3a514aa7fe1c7d GIT binary patch literal 167336 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 z�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�V}K%6%7hd{g;|Y$lt_7P6&` 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 literal 0 HcmV?d00001 diff --git a/assets/icon-128x128.png b/assets/icon-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..39cbc6e21490572b7570bb2bbc17f4e0d46e6f66 GIT binary patch literal 2832 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 PCJzQrS3j3^P6t6pl6rR~4x zv8yXO044Wv}#c+uJ|rwD(t6S05L~R$Bfn32?B#w-Y>Zpx4rAz8nMr@4WBq z_2wK&IU52DbR_y`>wx{J0C43i5c0;)#OwqZ_`jS9@Q0+|5n&{}oKqTRBfx;iw*PJ&TYt_C z-|)xU0OE+41Am{ z&aGv8Z<8UB07D|`ZbEYc3(*S#}T z&$zFhj1sMANLa;DY zTBENFpEn_)ngBZh<%D0=UHdrFe!h1$&CUS{S#79}j;aXoNCUgCHf%jo-_*gXi$~+^ zJUHpC^^9+LT%*Os1h@?a{8e-?{~YkwrJEg9PS?IB@&4fONtA~CU}x`(E1WJ=%%PI7 zx3Q2=XbN}$pJ{;jvZSWtkrG;}`UUP6Hkr*0V~YrIQ2rDb zMDibH!LI=Ra9c%0I0{4nE?vjnKp&toB}l0@Q=S-_8tFA)y>f#Q@?S|AgUl>Ss~oOJ3f z2w;ws(@g9!r3D!RHnwTX%uy?muF@i2w3n&R-$@Se^^kFG|A&z9K$qH5L4sR>e}u_pawP)%fH>c%r4tgH8!&&0CbrK%0B{s* zyQyH#Z-qH~?iXjgkM^Jvpcbm6MTbo#Bnt3J=A?Ar=f!D8B&6&$`%Va>-!jv=ixyfy!n>EP{g#;v|G-XfyAP^QMIq8sgq+v?vSVF+Y z)=&bH2a(n)1SlYVvW1l7>dX(HSHu5 zJ|JzQdpqI8{2z^g2gL-a4%ik6i98`i_>KL9ElnqO4i585w{@j^_jMHEoOHyKz=>gE zag-uxLE1d{p4F$Yi+tB0Otu!n6XhC{8r*__(9T6B%r8E0$m2U+E>H*~!{*5merjWV z(&ipaR%G5r1nlg6Y;LPue1kzHbC5S$U*b%}nP1kpM;I zrwC{U{#+*LtemhYai<7qVs;KpkW!AQa>8p{FnR#1It-0$#_)L|0on^Y?5R3@QSB(Z564BhaSQKB!Xlbz=ZebFg$JL~f^_Yu zWDicjY~^U>LcXe~l?7o`JHkiNaE6#2UT0~x2PFb(av`JG-LURG3o0`%Vg%qDqifhu zBNY=QIbz#PxY&&NbY058-`E0Ck&->sU&_0^Q=TrE)eLn-IG9{CKhix(r~yuZ;s+S| zaE|bAVenVBzVeiylzFQJsEanOwM+qRQpkf*pD%EXcz)ubdlT;fWMPyDNSGm>l|c)5 z?b7@{fTs}Nc>704G7Y89F4M%aa$8UQd1QM2u@e#iaTLtR}!W zzqMB-MIRpy^Th#nnG?4j>lrTKtM-1_LX%{#2>}%(@KwwS@pHEV-Z9b)_?7)XS^cJf z)F$AwZZiU$1m)u9*m(gT69N(Y0zl-iR07XB#Szc3O*SQ>i^ zZZQX-nKig$=I3#`MrU0$;J_qdiy`9NwE?LQf0ro3P)p0L&Kk|b zWeOQO`0z=eQ?5m jSQvqYm%nJh!UX&aml;f*_c)x}00000NkvXXu0mjfF*uNp literal 0 HcmV?d00001 diff --git a/assets/icons/settings.png b/assets/icons/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..997741a191cf4dd9f54041cdd3dd04860c418cdd GIT binary patch literal 1302 zcmV+x1?l>UP)Z0A~T1k=qb$Nwz&TB>Vn|MgN|=^6*)1 z0YNVz_LnSMQ+!{O0z$&yS>+H1@a%`L@FL1TWz5P!ng;*{h~fo6im`_!T*q9fX#ix# z8>3G-H_8&41wht&VwK;WPuHYc1|WsK*aepbat~K@!JOPA0Nk|n6Qta{{Gqlo*qUNwjmEh_U61dJ?hJU8;yUUYq1o z$JbwqSh7n+#_@9jJiz_PTBDAXu60V7nvxGJmRERBOPI799F0OEGGa}}(D8MbqjPns z$dEJ^fEs!pU$8g}$gLDIqh%rdfa?*K+`wZJ8{%4K<=XMZt4q{27t*f z=K`4QQU&;XTwE)#_2o;yK+4wZ-j-5IXc!jfuLKBD{Eb#_)@DmF77&>nRnesqI3)pK z$^%t(sfqy*5tCQdr78&k6NOaQr78))4qv9ZE>-Fp*VKYPS&ASRqH4NSOV+r?AZP%X zrxL5^QduQ^8h|axRo|t`RpT160<{`idzUJAjjIoV0Z?t1%Bse741obq?S@$ZFspHO z5L5smCT4bs2R3ykO zC6-wLj%K7R&a3NERRbVc!w#=n#Z+|*n$Jopi_Ctr)VNNvfRswf41f)*7jHB*2_Q@y zrq#OmPVANe6j9@989)&=u4Vz0QsZhJ0J|77F+%?ws>ancfD&q4%>%HmaXEnCIErk_ zGmei;>x;^S$L`BwC$?L_0F9hGu^qsOIpnfz2jBphmFD@JT(dH#EVlr+0Ji{M1H%ym zvs+?T54bOmY^1D8Rtgs+{bB79R;n(d%>;5Q;i_bv3?M96Q?+&K*GV+xcgK|tRjZSg z3V{4Z&mMpM-~7D8d-ANVbe56~0H{h<5&%cDQ`}MayFJp>p7oG4Ln^qV)yql>fKi;E z^HKv2z<5SD00&^K0b}uQ0S>@e1IFUr0vv#`28_kK1vmg>4H%362Nn_vti6(CP5=M^ M07*qoM6N<$g86zrX#fBK literal 0 HcmV?d00001 diff --git a/freetype/types.odin b/freetype/types.odin new file mode 100644 index 0000000..f8a2d20 --- /dev/null +++ b/freetype/types.odin @@ -0,0 +1,314 @@ +package freetype + +FT_Error :: i32 +@private +FT_Short :: i16 +@private +FT_UShort :: u16 +@private +FT_Int :: i32 +@private +FT_UInt :: u32 +@private +FT_Long :: i64 +@private +FT_ULong :: u64 +@private +FT_String :: u8 + +@private +FT_Pos :: i64 +@private +FT_Fixed :: i64 +@private +FT_SubGlyph :: ^u32 // internal object +@private +FT_Slot_Internal :: ^u32 // opaque handle to internal slot structure +@private +FT_Size_Internal :: ^u32 // opaque handle to internal size structure +@private +FT_Driver :: ^u32 // a handle to a given FreeType font driver object +@private +FT_Memory :: ^u32 // a handle to a given memory manager object + +Library :: ^u32 // handle to a library object + +@private +FT_Render_Mode_ :: enum { + NORMAL = 0, + LIGHT, + MONO, + LCD, + LCD_V, + SDF, + + MAX +} + +LoadFlags :: enum { + DEFAULT = 0x0, + NO_SCALE = 1 << 0, + NO_HINTING = 1 << 1, + RENDER = 1 << 2, + NO_BITMAP = 1 << 3, + VERTICAL_LAYOUT = 1 << 4, + FORCE_AUTOHINT = 1 << 5, + CROP_BITMAP = 1 << 6, + PEDANTIC = 1 << 7, + IGNORE_GLOBAL_ADVANCE_WIDTH = 1 << 9, + NO_RECURSE = 1 << 10, + IGNORE_TRANSFORM = 1 << 11, + MONOCHROME = 1 << 12, + LINEAR_DESIGN = 1 << 13, + NO_AUTOHINT = 1 << 15, + // Bits 16-19 are used by `FT_LOAD_TARGET_` + COLOR = 1 << 20, + COMPUTE_METRICS = 1 << 21, + BITMAP_METRICS_ONLY = 1 << 22, + + /* used internally only by certain font drivers */ + ADVANCE_ONLY = 1 << 8, + SBITS_ONLY = 1 << 14, + + FT_LOAD_TARGET_NORMAL = (int(FT_Render_Mode_.NORMAL) & 15) << 16, + FT_LOAD_TARGET_LIGHT = (int(FT_Render_Mode_.LIGHT) & 15) << 16, + FT_LOAD_TARGET_MONO = (int(FT_Render_Mode_.MONO) & 15) << 16, + FT_LOAD_TARGET_LCD = (int(FT_Render_Mode_.LCD) & 15) << 16, + FT_LOAD_TARGET_LCD_V = (int(FT_Render_Mode_.LCD_V) & 15) << 16, +} + +@private +FT_Encoding :: enum { + // TODO: fill this out +} + +@private +FT_CharMapRec_ :: struct { + face: Face, + encoding: FT_Encoding, + platform_id: FT_UShort, + encoding_id: FT_UShort, +} + +FT_CharMap :: ^FT_CharMapRec_ + +@private +FT_Bitmap_Size :: struct { + height: FT_Short, + width: FT_Short, + + size: FT_Pos, + + x_ppem: FT_Pos, + y_ppem: FT_Pos, +} + +@private +FT_Generic :: struct { + data: rawptr, + finalizer: ^proc(object: rawptr), +} + +@private +FT_BBox :: struct { + xMin, yMin: FT_Pos, + xMax, yMax: FT_Pos, +} + +@private +FT_Vector :: struct { + x, y: FT_Pos, +} + +@private +FT_Glyph_Metrics :: struct { + width: FT_Pos, + height: FT_Pos, + + horiBearingX: FT_Pos, + horiBearingY: FT_Pos, + horiAdvance: FT_Pos, + + vertBearingX: FT_Pos, + vertBearingY: FT_Pos, + vertAdvance: FT_Pos, +} + +@private +FT_Outline :: struct { + n_contours: i16, + n_points: i16, + + points: ^FT_Vector, + tags: ^u8, + contours: ^i16, + + flags: i32, +} + +@private +FT_GlyphSlotRec_ :: struct { + library: Library, + face: Face, + next: FT_GlyphSlot, + glyph_index: FT_UInt, /* new in 2.10; was reserved previously */ + generic: FT_Generic, + + metrics: FT_Glyph_Metrics, + linearHoriAdvance: FT_Fixed, + linearVertAdvance: FT_Fixed, + advance: FT_Vector, + + format: u32 /*FT_Glyph_Format*/, // stub this to u32 for now since I can't be bothered to define the enum + + bitmap: Bitmap, + bitmap_left: FT_Int, + bitmap_top: FT_Int, + + outline: FT_Outline, + + num_subglyphs: FT_UInt, + subglyphs: FT_SubGlyph, + + control_data: rawptr, + control_len: i64, + + lsb_delta: FT_Pos, + rsb_delta: FT_Pos, + + other: rawptr, + + internal: FT_Slot_Internal, +} + +FT_GlyphSlot :: ^FT_GlyphSlotRec_ + +@private +FT_Size_Metrics :: struct { + x_ppem: FT_UShort, /* horizontal pixels per EM */ + y_ppem: FT_UShort, /* vertical pixels per EM */ + + x_scale: FT_Fixed, /* scaling values used to convert font */ + y_scale: FT_Fixed, /* units to 26.6 fractional pixels */ + + ascender: FT_Pos, /* ascender in 26.6 frac. pixels */ + descender: FT_Pos, /* descender in 26.6 frac. pixels */ + height: FT_Pos, /* text height in 26.6 frac. pixels */ + max_advance: FT_Pos, /* max horizontal advance, in 26.6 pixels */ +} + +@private +FT_SizeRec :: struct { + face: Face, + generic: FT_Generic, + metrics: FT_Size_Metrics, + internal: FT_Size_Internal, +} + +@private +FT_Size :: ^FT_SizeRec + +//@private +//FT_StreamRec_ :: struct { +// unsigned char* base, +// size: u64, +// pos: u64, +// +// FT_StreamDesc descriptor, +// FT_StreamDesc pathname, +// FT_Stream_IoFunc read, +// FT_Stream_CloseFunc close, +// +// FT_Memory memory, +// unsigned char* cursor, +// unsigned char* limit, +//} + +@private +FT_ListNodeRec_ :: struct { + prev: FT_ListNode, + next: FT_ListNode, + data: rawptr, +} + +@private +FT_ListNode :: ^FT_ListNodeRec_ + +@private +FT_ListRec :: struct { + head: FT_ListNode, + tail: FT_ListNode, +} + +@private +FT_FaceRec_ :: struct { + num_faces: FT_Long, + face_index: FT_Long, + + face_flags: FT_Long, + style_flags: FT_Long, + + num_glyphs: FT_Long, + + family_name: ^FT_String, + style_name: ^FT_String, + + num_fixed_sizes: FT_Int, + available_sizes: ^FT_Bitmap_Size, + + num_charmaps: FT_Int, + charmaps: ^FT_CharMap, + + generic: FT_Generic, + + /*# The following member variables (down to `underline_thickness`) */ + /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ + /*# for bitmap fonts. */ + bbox: FT_BBox, + + units_per_EM: FT_UShort, + ascender: FT_Short, + descender: FT_Short, + height: FT_Short, + + max_advance_width: FT_Short, + max_advance_height: FT_Short, + + underline_position: FT_Short, + underline_thickness: FT_Short, + + glyph: FT_GlyphSlot, + size: FT_Size, + charmap: FT_CharMap, + + /*@private begin */ + driver: FT_Driver, + memory: FT_Memory, + stream: /*FT_Stream*/ ^u32, // TODO: stub it out for now + + sizes_list: FT_ListRec, + + autohint: FT_Generic, // face-specific auto-hinter data + extensions: rawptr, // unused + + internal: /*FT_Face_Internal*/ ^u32, // TODO: stub it out for now + + /*@private end */ + + //@private + //@packed + //@align(8) +} + +Bitmap :: struct { + rows: u32, + width: u32, + pitch: i32, + buffer: [^]u8, + num_grays: u16, + pixel_mode: u8, + palette_mode: u8, + palette: rawptr, +} + +Face :: ^FT_FaceRec_ diff --git a/freetype/wrapper.odin b/freetype/wrapper.odin new file mode 100644 index 0000000..d92f0a1 --- /dev/null +++ b/freetype/wrapper.odin @@ -0,0 +1,18 @@ +package freetype + +foreign import freetype "system:freetype" + +foreign freetype { + @(link_name = "FT_Init_FreeType") + Init_FreeType :: proc(lib: ^Library) -> FT_Error --- + @(link_name = "FT_New_Face") + New_Face :: proc(lib: Library, file_pathname: cstring, face_index: FT_Long, face: ^Face) -> FT_Error --- + @(link_name = "FT_Set_Pixel_Sizes") + Set_Pixel_Sizes :: proc(face: Face, pixel_width: FT_UInt, pixel_height: FT_UInt) -> FT_Error --- + @(link_name = "FT_Load_Char") + Load_Char :: proc(face: Face, char_code: FT_ULong, load_flags: LoadFlags) -> FT_Error --- + @(link_name = "FT_Done_Face") + Done_Face :: proc(face: Face) -> FT_Error --- + @(link_name = "FT_Done_FreeType") + Done_FreeType :: proc(lib: Library) -> FT_Error --- +} diff --git a/game.odin b/game.odin new file mode 100644 index 0000000..4d1b6f3 --- /dev/null +++ b/game.odin @@ -0,0 +1,1177 @@ +package main + +import "core:fmt" +import "core:math" +import "core:math/rand" +import "core:time" + +import "zephr" + +Icon :: enum { + HELP_ICON, + SETTINGS_ICON, + CLOSE_ICON, +} + +MoveDir :: enum { + UP, + DOWN, + LEFT, + RIGHT, +} + +ColorPalette :: struct { + bg_color: zephr.Color, + board_bg_color: zephr.Color, + tile_colors: [11]zephr.Color, +} + +Tile :: struct { + value: u16, + new_value: u16, + merged: bool, + + anim_x_offset_relative: f64, + anim_y_offset_relative: f64, + tiles_to_move: u8, +} + +Game :: struct { + board: [4][4]Tile, + score: u32, + last_move_dir: MoveDir, + animating: bool, + spawning_new_tile: bool, + has_lost: bool, + game_over_bg_opacity: f32, + game_over_opacity: f32, + spawning_tile_scale: f32, + spawning_tile_coords: zephr.Vec2, + spawning_tile_value: u16, + + quit_dialog: bool, + settings_dialog: bool, + help_dialog: bool, + + icon_textures: [Icon]zephr.TextureId, + palette: ColorPalette, +} + +@private +TILE_ANIM_SPEED :: 2.5 +@private +TILE_SPAWN_SPEED :: 6.0 +@private +GAMEOVER_ANIM_DURATION :: time.Millisecond * 300 + +@private +neighbors := [4]zephr.Vec2 { + {-1, 0}, // left + {1, 0}, // right + {0, -1}, // up + {0, 1}, // down +} + +// nocheckin +timeElapsed: time.Duration = 0 + +@private +game : Game + +get_tile_color :: proc(value: u16) -> zephr.Color { + switch (value) { + case 2: + return game.palette.tile_colors[0]; + case 4: + return game.palette.tile_colors[1]; + case 8: + return game.palette.tile_colors[2]; + case 16: + return game.palette.tile_colors[3]; + case 32: + return game.palette.tile_colors[4]; + case 64: + return game.palette.tile_colors[5]; + case 128: + return game.palette.tile_colors[6]; + case 256: + return game.palette.tile_colors[7]; + case 512: + return game.palette.tile_colors[8]; + case 1024: + return game.palette.tile_colors[9]; + case 2048: + return game.palette.tile_colors[10]; + case: + return game.palette.tile_colors[10]; + } +} + +get_tile_font_size :: proc(value: u16) -> u32 { + switch (value) { + case 2: fallthrough + case 4: fallthrough + case 8: + return 60; + case 16: fallthrough + case 32: fallthrough + case 64: + return 55; + case 128: fallthrough + case 256: fallthrough + case 512: + return 50; + case 1024: fallthrough + case 2048: + return 45; + case: + return 40; + } +} + +///////////////////////////// +// +// +// Game Logic +// +// +///////////////////////////// + + +move_right :: proc() { + game.last_move_dir = .RIGHT; + + for i in 0..<4 { + for j := 2; j >= 0; j -= 1 { + if (game.board[i][j].value == 0) { + continue; + } + tiles_to_move := 0; + x := j; + + src := &game.board[i][j]; + + loop: for { + if (x >= 3) do break loop + x += 1 + + // next tile is empty so we can move there + if (game.board[i][x].new_value == 0) { + tiles_to_move += 1; + continue; + } + + // next tile has the same value so we can merge and move + if (game.board[i][x].new_value == src.new_value && !game.board[i][x].merged) { + tiles_to_move += 1; + game.board[i][x].merged = true; + break; + } else { + // next tile has a different value so we can't move there + x -= 1; + break; + } + } + + src.tiles_to_move = auto_cast tiles_to_move; + + if (tiles_to_move > 0) { + if (game.board[i][x].merged) { + game.board[i][x].new_value *= 2; + game.score += auto_cast game.board[i][x].new_value; + } else { + game.board[i][x].new_value = src.new_value; + } + src.new_value = 0; + game.animating = true; + game.spawning_tile_coords = get_random_available_tile_coords(); + game.spawning_tile_value = get_spawned_tile_value(); + } + } + } +} + +// TODO: ideas for refactoring the animation logic and separating game state from rendering +// the board is just a state that we keep in memory but never use it for rendering +// and a tile is an enitity that has a position (in the board or on the screen??) that we can animate using lerp +// we draw the tile entities and not the board state. the tile entities update their positions according to the board state at the end of the frame?? +move_left :: proc() { + game.last_move_dir = .LEFT; + + for i in 0..<4 { + for j in 1..<4 { + if (game.board[i][j].value == 0) { + continue; + } + tiles_to_move := 0; + x := j; + + src := &game.board[i][j]; + + loop: for { + if (x <= 0) do break loop + x -= 1; + + // next tile is empty so we can move there + if (game.board[i][x].new_value == 0) { + tiles_to_move += 1; + continue; + } + + // next tile has the same value so we can merge and move + if (game.board[i][x].new_value == src.new_value && !game.board[i][x].merged) { + tiles_to_move += 1; + game.board[i][x].merged = true; + break; + } else { + // next tile has a different value so we can't move there + x += 1 + break; + } + } + + src.tiles_to_move = auto_cast tiles_to_move; + + if (tiles_to_move > 0) { + if (game.board[i][x].merged) { + game.board[i][x].new_value *= 2; + game.score += auto_cast game.board[i][x].new_value; + } else { + game.board[i][x].new_value = src.new_value; + } + src.new_value = 0; + game.animating = true; + game.spawning_tile_coords = get_random_available_tile_coords(); + game.spawning_tile_value = get_spawned_tile_value(); + } + } + } +} + +print_board :: proc() { + for i in 0..<4 { + for j in 0..<4 { + fmt.print(game.board[i][j].value, " "); + } + fmt.println(); + } + fmt.println(); +} + +print_new_board :: proc() { + for i in 0..<4 { + for j in 0..<4 { + fmt.print(game.board[i][j].new_value, " "); + } + fmt.println(); + } + fmt.println(); +} + +move_down :: proc() { + game.last_move_dir = .DOWN; + + for i := 2; i >= 0; i -= 1 { + for j in 0..<4 { + if (game.board[i][j].value == 0) { + continue; + } + tiles_to_move := 0; + y := i; + + src := &game.board[i][j]; + + loop: for { + if (y >= 3) do break loop + y += 1; + + if (game.board[y][j].new_value == 0) { + tiles_to_move += 1; + continue; + } + + if (game.board[y][j].new_value == src.new_value && !game.board[y][j].merged) { + tiles_to_move += 1; + game.board[y][j].merged = true; + break; + } else { + y -= 1; + break; + } + } + + src.tiles_to_move = auto_cast tiles_to_move; + + if (tiles_to_move > 0) { + if (game.board[y][j].merged) { + game.board[y][j].new_value *= 2; + game.score += auto_cast game.board[y][j].new_value; + } else { + game.board[y][j].new_value = src.new_value; + } + src.new_value = 0; + game.animating = true; + game.spawning_tile_coords = get_random_available_tile_coords(); + game.spawning_tile_value = get_spawned_tile_value(); + } + } + } +} + +move_up :: proc() { + game.last_move_dir = .UP; + + for i in 1..<4 { + for j in 0..<4 { + if (game.board[i][j].new_value == 0) { + continue; + } + tiles_to_move := 0; + y := i; + + src := &game.board[i][j]; + + loop: for { + if (y <= 0) do break loop + y -= 1; + + if (game.board[y][j].new_value == 0) { + tiles_to_move += 1; + continue; + } + + if (game.board[y][j].new_value == src.new_value && !game.board[y][j].merged) { + tiles_to_move += 1; + game.board[y][j].merged = true; + break; + } else { + y += 1; + break; + } + } + + src.tiles_to_move = auto_cast tiles_to_move; + + if (tiles_to_move > 0) { + if (game.board[y][j].merged) { + game.board[y][j].new_value *= 2; + game.score += auto_cast game.board[y][j].new_value; + } else { + game.board[y][j].new_value = src.new_value; + } + src.new_value = 0; + game.animating = true; + game.spawning_tile_coords = get_random_available_tile_coords(); + game.spawning_tile_value = get_spawned_tile_value(); + } + } + } +} + +reset_palette :: proc() { + game.palette = ColorPalette{ + bg_color = zephr.Color{248, 250, 230, 255}, + board_bg_color = zephr.Color{140, 154, 147, 255}, + + tile_colors = [11]zephr.Color{ + zephr.Color{238, 228, 218, 255}, // 2 + zephr.Color{237, 224, 200, 255}, // 4 + zephr.Color{242, 177, 121, 255}, // 8 + zephr.Color{245, 149, 99, 255}, // 16 + zephr.Color{246, 124, 95, 255}, // 32 + zephr.Color{246, 94, 59, 255}, // 64 + zephr.Color{237, 207, 114, 255}, // 128 + zephr.Color{237, 204, 97, 255}, // 256 + zephr.Color{237, 200, 80, 255}, // 512 + zephr.Color{237, 197, 63, 255}, // 1024 + zephr.Color{237, 194, 46, 255}, // 2048 + }, + } +} + +reset_game :: proc() { + timeElapsed = 0 + + game.score = 0; + game.animating = false; + game.spawning_new_tile = false; + game.quit_dialog = false; + game.help_dialog = false; + game.settings_dialog = false; + game.has_lost = false; + game.game_over_bg_opacity = 0; + game.game_over_opacity = 0; + + for y in 0..<4 { + for x in 0..<4 { + game.board[y][x].value = 0; + game.board[y][x].new_value = 0; + game.board[y][x].merged = false; + game.board[y][x].tiles_to_move = 0; + game.board[y][x].anim_x_offset_relative = 0; + game.board[y][x].anim_y_offset_relative = 0; + } + } + + for i in 0..<2 { + spawn_random_tile(); + } +} + +game_attempt_quit :: proc() { + game.help_dialog = false; + game.settings_dialog = false; + game.quit_dialog = true; +} + +game_init :: proc() { + game.icon_textures[.HELP_ICON] = zephr.load_texture("assets/icons/help.png") + game.icon_textures[.SETTINGS_ICON] = zephr.load_texture("assets/icons/settings.png") + game.icon_textures[.CLOSE_ICON] = zephr.load_texture("assets/icons/close.png") + + reset_palette() + + for i in 0..<2 { + spawn_random_tile() + } +} + +get_spawned_tile_value :: proc() -> u16 { + // 90% chance of spawning a 2, 10% chance of spawning a 4 + if (rand.int_max(11) < 9) { + return 2; + } else { + return 4; + } +} + +spawn_new_tile_with_value :: proc(x, y: u8, value: u16) { + game.board[x][y].value = value; + game.board[x][y].new_value = value; +} + +spawn_new_tile :: proc(x, y: u8) { + val := get_spawned_tile_value(); + + game.board[x][y].value = val; + game.board[x][y].new_value = val; +} + +get_random_available_tile_coords :: proc() -> zephr.Vec2 { + available_tiles_count := 0; + available_tiles: [16]int + + for i in 0..<4 { + for j in 0..<4 { + if (game.board[i][j].new_value == 0 && !game.board[i][j].merged) { + available_tiles[available_tiles_count] = i * 4 + j; + available_tiles_count += 1; + } + } + } + + rand_idx := rand.int_max(available_tiles_count) + + x := available_tiles[rand_idx] / 4; + y := available_tiles[rand_idx] % 4; + + return zephr.Vec2{cast(f32)x, cast(f32)y}; +} + +spawn_random_tile :: proc() { + coords := get_random_available_tile_coords(); + spawn_new_tile(cast(u8)coords.x, cast(u8)coords.y); +} + +gameover :: proc() -> bool { + if (game.has_lost) do return false + + for y in 0..<4 { + for x in 0..<4 { + if (game.board[y][x].value == 0) { + return false; + } + + for i in 0..<4 { + new_y := cast(int)clamp(cast(f32)y + neighbors[i].y, 0, 3); + new_x := cast(int)clamp(cast(f32)x + neighbors[i].x, 0, 3); + + if ((new_y != y || new_x != x) && game.board[y][x].value == game.board[new_y][new_x].value) { + return false; + } + } + } + } + + + return true; +} + +handle_keyboard_input :: proc(e: zephr.Event) { + can_move := !game.quit_dialog && !game.help_dialog && !game.settings_dialog && !game.animating; + + if (.LEFT_CTRL in e.key.mods && e.key.scancode == .Q) { + game_attempt_quit(); + } else if (e.key.scancode == .ESCAPE) { + game.quit_dialog = false; + game.help_dialog = false; + game.settings_dialog = false; + } else if (e.key.scancode == .F11) { + zephr.toggle_fullscreen(); + } else if (e.key.scancode == .UP) { + if (can_move) do move_up() + } else if (e.key.scancode == .DOWN) { + if (can_move) do move_down() + } else if (e.key.scancode == .LEFT) { + if (can_move) do move_left() + } else if (e.key.scancode == .RIGHT) { + if (can_move) do move_right() + } +} + +game_loop :: proc() { + game_init() + + last_frame: time.Duration = 0 + + for (!zephr.should_quit()) { + e: zephr.Event + + for (zephr.iter_events(&e)) { + #partial switch (e.type) { + case .WINDOW_CLOSED: + if (game.quit_dialog) { + zephr.quit(); + } else { + game_attempt_quit(); + } + case .KEY_PRESSED: + handle_keyboard_input(e); + } + } + + now := zephr.get_time() + delta_t := now - last_frame + last_frame = now; + + update_positions(delta_t) + + draw_bg(); + draw_board(); + draw_ui(); + + zephr.swap_buffers() + } +} + +update_positions :: proc(delta_t: time.Duration) { + // TODO: lerp the positions and use delta_t for it + delta_t_f := time.duration_seconds(delta_t) + // TODO: experiment; I think I can lerp the tile positions instead of doing this + + if (game.animating) { + switch (game.last_move_dir) { + case .LEFT: + for i in 0..<4 { + for j in 1..<4 { + tiles_to_move := game.board[i][j].tiles_to_move; + speed := TILE_ANIM_SPEED * cast(f64)tiles_to_move; + src := &game.board[i][j]; + dest := &game.board[i][j - cast(int)tiles_to_move]; + + if (src.tiles_to_move != 0) { + src.anim_x_offset_relative -= speed * delta_t_f; + + if (src.anim_x_offset_relative <= -0.240 * (cast(f64)tiles_to_move + (cast(f64)tiles_to_move * 0.02))) { + if (dest.new_value == src.value * 2) { + dest.merged = false; + } + + src.value = src.new_value; + dest.value = dest.new_value; + + src.tiles_to_move = 0; + src.anim_x_offset_relative = 0; + game.spawning_new_tile = true; + } + } + } + } + case .RIGHT: + for i in 0..<4 { + for j := 2; j >= 0; j -= 1 { + tiles_to_move := game.board[i][j].tiles_to_move; + speed := TILE_ANIM_SPEED * cast(f64)tiles_to_move; + src := &game.board[i][j]; + dest := &game.board[i][j + cast(int)tiles_to_move]; + + if (src.tiles_to_move != 0) { + src.anim_x_offset_relative += speed * delta_t_f; + + if (src.anim_x_offset_relative >= 0.240 * (cast(f64)tiles_to_move + (cast(f64)tiles_to_move * 0.02))) { + if (dest.new_value == src.value * 2) { + dest.merged = false; + } + + src.value = src.new_value; + dest.value = dest.new_value; + + src.tiles_to_move = 0; + src.anim_x_offset_relative = 0; + game.spawning_new_tile = true; + } + } + } + } + case .UP: + for i in 1..<4 { + for j in 0..<4 { + tiles_to_move := game.board[i][j].tiles_to_move; + speed := TILE_ANIM_SPEED * cast(f64)tiles_to_move; + src := &game.board[i][j]; + dest := &game.board[i - cast(int)tiles_to_move][j]; + + if (src.tiles_to_move != 0) { + src.anim_y_offset_relative -= speed * delta_t_f; + + if (src.anim_y_offset_relative <= -0.240 * (cast(f64)tiles_to_move + (cast(f64)tiles_to_move * 0.02))) { + if (dest.new_value == src.value * 2) { + dest.merged = false; + } + + src.value = src.new_value; + dest.value = dest.new_value; + + src.tiles_to_move = 0; + src.anim_y_offset_relative = 0; + game.spawning_new_tile = true; + } + } + } + } + case .DOWN: + for i := 2; i >= 0; i -= 1 { + for j in 0..<4 { + tiles_to_move := game.board[i][j].tiles_to_move; + speed := TILE_ANIM_SPEED * cast(f64)tiles_to_move; + src := &game.board[i][j]; + dest := &game.board[i + cast(int)tiles_to_move][j]; + + if (src.tiles_to_move != 0) { + src.anim_y_offset_relative += speed * delta_t_f; + + if (src.anim_y_offset_relative >= 0.240 * (cast(f64)tiles_to_move + (cast(f64)tiles_to_move * 0.02))) { + if (dest.new_value == src.value * 2) { + dest.merged = false; + } + + src.value = src.new_value; + dest.value = dest.new_value; + + src.tiles_to_move = 0; + src.anim_y_offset_relative = 0; + game.spawning_new_tile = true; + } + } + } + } + } + } + + if (gameover()) { + game.has_lost = true; + game.animating = true; + } + + if (game.spawning_new_tile) { + game.spawning_tile_scale += (TILE_SPAWN_SPEED * cast(f32)delta_t_f); + + if (game.spawning_tile_scale >= 1.0) { + spawn_new_tile_with_value(cast(u8)game.spawning_tile_coords.x, cast(u8)game.spawning_tile_coords.y, game.spawning_tile_value); + game.spawning_tile_coords = zephr.Vec2{0, 0}; + game.spawning_tile_value = 0; + game.spawning_new_tile = false; + game.animating = false; + game.spawning_tile_scale = 0.0 + } + } + + if (game.has_lost) { + if timeElapsed < GAMEOVER_ANIM_DURATION { + game.game_over_opacity = cast(f32)math.lerp(0.0, 255.0, cast(f64)timeElapsed / cast(f64)GAMEOVER_ANIM_DURATION) + game.game_over_bg_opacity = cast(f32)math.lerp(0.0, 200.0, cast(f64)timeElapsed / cast(f64)GAMEOVER_ANIM_DURATION) + timeElapsed += delta_t + } else { + game.game_over_bg_opacity = 255 + game.game_over_bg_opacity = 200 + } + } +} + + +/////////////////////////////////// +// +// +// Drawing +// +// +/////////////////////////////////// + + +draw_bg :: proc() { + window_size := zephr.get_window_size(); + board_con := zephr.DEFAULT_UI_CONSTRAINTS + + zephr.set_width_constraint(&board_con, window_size.x, .FIXED); + zephr.set_height_constraint(&board_con, window_size.y, .FIXED); + + // bg + style := zephr.UiStyle{ + bg_color = game.palette.bg_color, + align = .TOP_LEFT, + }; + zephr.draw_quad(&board_con, style); + + text_batch: zephr.GlyphInstanceList + reserve(&text_batch, 32) + + // 2048 text + text_con := zephr.DEFAULT_UI_CONSTRAINTS; + + zephr.set_y_constraint(&text_con, 0.05, .RELATIVE); + zephr.set_width_constraint(&text_con, 1.5, .RELATIVE_PIXELS); + + zephr.add_text_instance(&text_batch, "2048", 100, text_con, zephr.Color{34, 234, 82, 155}, .TOP_CENTER); + + // score + buf: [24]byte + score := fmt.bprintf(buf[:], "Score %d", game.score); + + zephr.set_parent_constraint(&text_con, nil); + zephr.set_x_constraint(&text_con, 0.05, .RELATIVE); + zephr.set_y_constraint(&text_con, 0.8, .RELATIVE); + zephr.add_text_instance(&text_batch, score, 40, text_con, zephr.COLOR_BLACK, .TOP_LEFT); + + zephr.draw_text_batch(&text_batch); +} + +draw_board :: proc() { + // board + board_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_y_constraint(&board_con, 0.05, .RELATIVE); + zephr.set_height_constraint(&board_con, 0.6, .RELATIVE); + zephr.set_width_constraint(&board_con, 1, .ASPECT_RATIO); + style := zephr.UiStyle{ + bg_color = game.palette.board_bg_color, + border_radius = board_con.width * 0.02, + align = .CENTER, + }; + zephr.draw_quad(&board_con, style); + + // empty tiles + tile_padding := board_con.width * 0.02; + tile_height := board_con.height * 0.225; + tile_board_radius := tile_height * 0.15 + + empty_tile_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_parent_constraint(&empty_tile_con, &board_con); + zephr.set_height_constraint(&empty_tile_con, tile_height, .FIXED); + zephr.set_width_constraint(&empty_tile_con, 1, .ASPECT_RATIO); + + style = zephr.UiStyle{ + bg_color = zephr.mult_color(game.palette.board_bg_color, 0.85), + border_radius = tile_board_radius, + align = .TOP_LEFT, + }; + for i in 0..<4 { + zephr.set_y_constraint(&empty_tile_con, (tile_height + tile_padding) * cast(f32)i + tile_padding, .FIXED); + for j in 0..<4 { + zephr.set_x_constraint(&empty_tile_con, (tile_height + tile_padding) * cast(f32)j + tile_padding, .FIXED); + zephr.draw_quad(&empty_tile_con, style); + } + } + + // filled tiles + text_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_width_constraint(&text_con, 1.5, .RELATIVE_PIXELS); + tile_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_parent_constraint(&tile_con, &board_con); + zephr.set_height_constraint(&tile_con, tile_height, .FIXED); + zephr.set_width_constraint(&tile_con, 1, .ASPECT_RATIO); + + for i in 0..<4 { + for j in 0..<4 { + tile := &game.board[i][j]; + tile_color := get_tile_color(tile.value); + style := zephr.UiStyle { + bg_color = tile_color, + border_radius = tile_board_radius, + align = .TOP_LEFT, + } + buf: [16]byte + value := fmt.bprintf(buf[:], "%d", tile.value) + tile_y_pos := ((tile_height + tile_padding) * cast(f32)i + tile_padding + cast(f32)game.board[i][j].anim_y_offset_relative * board_con.height); + tile_x_pos := ((tile_height + tile_padding) * cast(f32)j + tile_padding + cast(f32)game.board[i][j].anim_x_offset_relative * board_con.height); + + zephr.set_y_constraint(&tile_con, tile_y_pos, .FIXED); + zephr.set_x_constraint(&tile_con, tile_x_pos, .FIXED); + if (tile.value > 0) { + zephr.draw_quad(&tile_con, style); + + // value text + zephr.set_parent_constraint(&text_con, &tile_con); + zephr.set_x_constraint(&text_con, 0, .FIXED); + zephr.set_y_constraint(&text_con, 0, .FIXED); + + zephr.draw_text(value, get_tile_font_size(tile.value), text_con, zephr.mult_color(tile_color, 0.5), .CENTER); + } + } + } + + if (game.spawning_new_tile) { + // spawning tile + tile_color := get_tile_color(game.spawning_tile_value); + style := zephr.UiStyle { + bg_color = tile_color, + border_radius = tile_board_radius * game.spawning_tile_scale, + align = .TOP_LEFT, + }; + tile_x_pos := ((tile_height + tile_padding) * game.spawning_tile_coords.y + tile_padding) + tile_height / 2 - game.spawning_tile_scale * tile_height / 2; + tile_y_pos := ((tile_height + tile_padding) * game.spawning_tile_coords.x + tile_padding) + tile_height / 2 - game.spawning_tile_scale * tile_height / 2; + zephr.set_x_constraint(&tile_con, tile_x_pos, .FIXED); + zephr.set_y_constraint(&tile_con, tile_y_pos, .FIXED); + zephr.set_height_constraint(&tile_con, tile_height * game.spawning_tile_scale, .FIXED); + zephr.set_width_constraint(&tile_con, 1, .ASPECT_RATIO); + zephr.draw_quad(&tile_con, style); + // value text + zephr.set_parent_constraint(&text_con, &tile_con); + zephr.set_x_constraint(&text_con, 0, .FIXED); + zephr.set_y_constraint(&text_con, 0, .FIXED); + + buf: [16]byte + value := fmt.bprintf(buf[:], "%d", game.spawning_tile_value) + zephr.draw_text(value, cast(u32)(cast(f32)get_tile_font_size(game.spawning_tile_value) * game.spawning_tile_scale), text_con, zephr.mult_color(tile_color, 0.5), .CENTER); + } +} + +draw_ui :: proc() { + bg_btns_state: zephr.ButtonState = (game.quit_dialog || game.help_dialog || game.settings_dialog || game.has_lost) ? .INACTIVE : .ACTIVE; + icon_btn_width :: 80; + icon_btn_offset :: 8; + icon_btns_padding :: 10; + + btn_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_x_constraint(&btn_con, -icon_btn_offset, .RELATIVE_PIXELS); + zephr.set_y_constraint(&btn_con, icon_btn_offset, .RELATIVE_PIXELS); + zephr.set_width_constraint(&btn_con, icon_btn_width, .RELATIVE_PIXELS); + zephr.set_height_constraint(&btn_con, 1, .ASPECT_RATIO); + + style := zephr.UiStyle { + bg_color = zephr.Color{201, 146, 126, 255}, + fg_color = zephr.Color{40, 92, 100, 255}, + border_radius = btn_con.height * 0.15, + align = .TOP_RIGHT, + }; + if (zephr.draw_icon_button(&btn_con, game.icon_textures[.HELP_ICON], style, bg_btns_state)) { + game.help_dialog = true; + } + + zephr.set_x_constraint(&btn_con, -icon_btn_offset - icon_btn_width - icon_btns_padding, .RELATIVE_PIXELS); + if (zephr.draw_icon_button(&btn_con, game.icon_textures[.SETTINGS_ICON], style, bg_btns_state)) { + game.settings_dialog = true; + } + + zephr.set_x_constraint(&btn_con, 0, .RELATIVE_PIXELS); + zephr.set_y_constraint(&btn_con, -0.05, .RELATIVE); + zephr.set_width_constraint(&btn_con, 200, .RELATIVE_PIXELS); + zephr.set_height_constraint(&btn_con, 65, .RELATIVE_PIXELS); + style = zephr.UiStyle { + bg_color = zephr.Color{201, 172, 126, 255}, + fg_color = zephr.COLOR_BLACK, + border_radius = btn_con.height * 0.25, + align = .BOTTOM_CENTER, + }; + if (zephr.draw_button(&btn_con, "New Game", style, bg_btns_state)) { + reset_game(); + } + + if (game.settings_dialog) { + draw_settings_dialog(); + } + + if (game.help_dialog) { + draw_help_dialog(); + } + + if (game.has_lost) { + draw_game_over(); + } + + if (game.quit_dialog) { + draw_quit_dialog(); + } +} + +draw_settings_dialog :: proc() { + dialog_con := zephr.DEFAULT_UI_CONSTRAINTS + zephr.set_width_constraint(&dialog_con, 1, .RELATIVE); + zephr.set_height_constraint(&dialog_con, 1, .RELATIVE); + zephr.set_x_constraint(&dialog_con, 0, .FIXED); + zephr.set_y_constraint(&dialog_con, 0, .FIXED); + style := zephr.UiStyle { + bg_color = zephr.Color{0, 0, 0, 200}, + align = .CENTER, + }; + zephr.draw_quad(&dialog_con, style); + + content_card_con := zephr.DEFAULT_UI_CONSTRAINTS + zephr.set_parent_constraint(&content_card_con, &dialog_con); + zephr.set_width_constraint(&content_card_con, 0.55, .RELATIVE); + zephr.set_height_constraint(&content_card_con, 0.6, .RELATIVE); + style = zephr.UiStyle{ + bg_color = zephr.Color{135, 124, 124, 255}, + border_radius = 8, + align = .CENTER, + }; + zephr.draw_quad(&content_card_con, style); + + text_con := zephr.DEFAULT_UI_CONSTRAINTS + zephr.set_parent_constraint(&text_con, &content_card_con); + zephr.set_width_constraint(&text_con, 1, .RELATIVE_PIXELS); + zephr.set_x_constraint(&text_con, 0, .FIXED); + zephr.set_y_constraint(&text_con, 40, .RELATIVE_PIXELS); + zephr.draw_text("Settings", 64, text_con, zephr.COLOR_YELLOW, .TOP_CENTER); + + zephr.set_x_constraint(&text_con, 30, .RELATIVE_PIXELS); + zephr.set_y_constraint(&text_con, 150, .RELATIVE_PIXELS); + zephr.draw_text("Color Palette", 40, text_con, zephr.COLOR_WHITE, .TOP_LEFT); + + bg_color_text := "Background: "; + font_size: u32 = 30; + zephr.set_x_constraint(&text_con, 30, .RELATIVE_PIXELS); + zephr.set_y_constraint(&text_con, 220, .RELATIVE_PIXELS); + zephr.set_height_constraint(&text_con, 0.9, .RELATIVE); + zephr.draw_text(bg_color_text, font_size, text_con, zephr.COLOR_WHITE, .TOP_LEFT); + + text_size := zephr.calculate_text_size(bg_color_text, font_size); + color_picker_con := zephr.DEFAULT_UI_CONSTRAINTS + zephr.set_parent_constraint(&color_picker_con, &content_card_con); + zephr.set_x_constraint(&color_picker_con, 30 + text_size.x + 20, .RELATIVE_PIXELS); + zephr.set_y_constraint(&color_picker_con, 220 - text_size.y / 2 + 6, .RELATIVE_PIXELS); + zephr.set_width_constraint(&color_picker_con, 100, .RELATIVE_PIXELS); + zephr.set_height_constraint(&color_picker_con, 40, .RELATIVE_PIXELS); + zephr.draw_color_picker(&color_picker_con, &game.palette.bg_color, .TOP_LEFT, .ACTIVE); + + zephr.set_y_constraint(&text_con, 270, .RELATIVE_PIXELS); + zephr.draw_text("Board: ", font_size, text_con, zephr.COLOR_WHITE, .TOP_LEFT); + + zephr.set_x_constraint(&color_picker_con, 30 + text_size.x + 20, .RELATIVE_PIXELS); + zephr.set_y_constraint(&color_picker_con, 270 - text_size.y / 2 + 6, .RELATIVE_PIXELS); + zephr.set_width_constraint(&color_picker_con, 100, .RELATIVE_PIXELS); + zephr.set_height_constraint(&color_picker_con, 40, .RELATIVE_PIXELS); + zephr.draw_color_picker(&color_picker_con, &game.palette.board_bg_color, .TOP_LEFT, .ACTIVE); + + zephr.set_y_constraint(&text_con, 320, .RELATIVE_PIXELS); + zephr.draw_text("Tiles: ", font_size, text_con, zephr.COLOR_WHITE, .TOP_LEFT); + + tile_size: f32 = 60; + for i in 0..<11 { + zephr.set_x_constraint(&color_picker_con, 30 + text_size.x + 20 + (cast(f32)i * (tile_size + 10)), .RELATIVE_PIXELS); + zephr.set_y_constraint(&color_picker_con, 320 - text_size.y / 2 + 6, .RELATIVE_PIXELS); + zephr.set_width_constraint(&color_picker_con, tile_size, .RELATIVE_PIXELS); + zephr.set_height_constraint(&color_picker_con, tile_size, .RELATIVE_PIXELS); + zephr.draw_color_picker(&color_picker_con, &game.palette.tile_colors[i], .TOP_LEFT, .ACTIVE, cast(u32)i); + + tile_val := cast(u16)math.pow(2, cast(f32)i + 1); + buf: [16]byte + text := fmt.bprintf(buf[:], "%d", tile_val); + font_size := get_tile_font_size(tile_val) / 2; + tile_color := get_tile_color(tile_val); + zephr.set_parent_constraint(&text_con, &color_picker_con); + zephr.set_x_constraint(&text_con, 0, .RELATIVE_PIXELS); + zephr.set_y_constraint(&text_con, 0, .RELATIVE_PIXELS); + zephr.draw_text(text, font_size, text_con, zephr.mult_color(tile_color, 0.5), .CENTER); + } + + btn_con := zephr.DEFAULT_UI_CONSTRAINTS + zephr.set_parent_constraint(&btn_con, &content_card_con); + zephr.set_x_constraint(&btn_con, 0, .RELATIVE_PIXELS); + zephr.set_y_constraint(&btn_con, 400, .RELATIVE_PIXELS); + zephr.set_width_constraint(&btn_con, 150, .RELATIVE_PIXELS); + zephr.set_height_constraint(&btn_con, 0.35, .ASPECT_RATIO); + style = zephr.UiStyle{ + bg_color = zephr.Color{201, 146, 126, 255}, + fg_color = zephr.COLOR_BLACK, + border_radius = 8, + align = .TOP_CENTER, + }; + if (zephr.draw_button(&btn_con, "Reset", style, .ACTIVE)) { + reset_palette(); + } + + zephr.set_width_constraint(&btn_con, 56, .RELATIVE_PIXELS); + zephr.set_height_constraint(&btn_con, 1, .ASPECT_RATIO); + zephr.set_y_constraint(&btn_con, -24, .RELATIVE_PIXELS); + zephr.set_x_constraint(&btn_con, 24, .RELATIVE_PIXELS); + style = zephr.UiStyle{ + bg_color = zephr.mult_color(zephr.COLOR_WHITE, 0.8), + fg_color = zephr.Color{232, 28, 36, 255}, + border_radius = btn_con.height * 0.2, + align = .TOP_RIGHT, + } + if (zephr.draw_icon_button(&btn_con, game.icon_textures[.CLOSE_ICON], style, .ACTIVE)) { + game.settings_dialog = false; + } +} + +draw_help_dialog :: proc() { + dialog_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_width_constraint(&dialog_con, 1, .RELATIVE); + zephr.set_height_constraint(&dialog_con, 1, .RELATIVE); + zephr.set_x_constraint(&dialog_con, 0, .FIXED); + zephr.set_y_constraint(&dialog_con, 0, .FIXED); + style := zephr.UiStyle { + bg_color = zephr.Color{0, 0, 0, 200}, + align = .CENTER, + }; + zephr.draw_quad(&dialog_con, style); + + content_card_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_parent_constraint(&content_card_con, &dialog_con); + zephr.set_width_constraint(&content_card_con, 0.4, .RELATIVE); + zephr.set_height_constraint(&content_card_con, 0.33, .RELATIVE); + style = zephr.UiStyle{ + bg_color = zephr.Color{135, 124, 124, 255}, + border_radius = 8, + align = .CENTER, + }; + zephr.draw_quad(&content_card_con, style); + + text_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_parent_constraint(&text_con, &content_card_con); + zephr.set_width_constraint(&text_con, 1, .RELATIVE_PIXELS); + zephr.set_x_constraint(&text_con, 0, .FIXED); + zephr.set_y_constraint(&text_con, 40, .RELATIVE_PIXELS); + zephr.draw_text("How to play", 64, text_con, zephr.COLOR_YELLOW, .TOP_CENTER); + + zephr.set_y_constraint(&text_con, 30, .RELATIVE_PIXELS); + zephr.set_height_constraint(&text_con, 0.9, .RELATIVE); + zephr.draw_text("Use the arrow keys to move the tiles.\n" + + "When two tiles with the same number touch, they\n" + + "merge into one!\n\nYour goal is to reach 2048 without filling all the tiles", 30., text_con, zephr.COLOR_WHITE, .CENTER); + + btn_con := zephr.DEFAULT_UI_CONSTRAINTS + zephr.set_parent_constraint(&btn_con, &content_card_con); + zephr.set_width_constraint(&btn_con, 56, .RELATIVE_PIXELS); + zephr.set_height_constraint(&btn_con, 1, .ASPECT_RATIO); + zephr.set_y_constraint(&btn_con, -24, .RELATIVE_PIXELS); + zephr.set_x_constraint(&btn_con, 24, .RELATIVE_PIXELS); + style = zephr.UiStyle{ + bg_color = zephr.mult_color(zephr.COLOR_WHITE, 0.8), + fg_color = zephr.Color{232, 28, 36, 255}, + border_radius = btn_con.height * 0.2, + align = .TOP_RIGHT, + }; + if (zephr.draw_icon_button(&btn_con, game.icon_textures[.CLOSE_ICON], style, .ACTIVE)) { + game.help_dialog = false; + } +} + +draw_game_over :: proc() { + dialog_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_width_constraint(&dialog_con, 1, .RELATIVE); + zephr.set_height_constraint(&dialog_con, 1, .RELATIVE); + zephr.set_x_constraint(&dialog_con, 0, .FIXED); + zephr.set_y_constraint(&dialog_con, 0, .FIXED); + style := zephr.UiStyle { + bg_color = zephr.Color{0, 0, 0, cast(u8)game.game_over_bg_opacity}, + align = .CENTER, + }; + zephr.draw_quad(&dialog_con, style); + + content_card_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_parent_constraint(&content_card_con, &dialog_con); + zephr.set_width_constraint(&content_card_con, 0.3, .RELATIVE); + zephr.set_height_constraint(&content_card_con, 0.2, .RELATIVE); + style = zephr.UiStyle{ + bg_color = zephr.Color{135, 124, 124, cast(u8)game.game_over_opacity}, + border_radius = 8, + align = .CENTER, + }; + zephr.draw_quad(&content_card_con, style); + + text_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_parent_constraint(&text_con, &content_card_con); + zephr.set_width_constraint(&text_con, 1, .RELATIVE_PIXELS); + zephr.set_x_constraint(&text_con, 0, .FIXED); + zephr.set_y_constraint(&text_con, 40, .RELATIVE_PIXELS); + zephr.draw_text("Game Over!", 64, text_con, zephr.Color{255, 255, 0, cast(u8)game.game_over_opacity}, .TOP_CENTER); + + btn_con := zephr.DEFAULT_UI_CONSTRAINTS + btn_state: zephr.ButtonState = game.quit_dialog ? .INACTIVE : game.game_over_opacity > 0 ? .ACTIVE : .INACTIVE; + zephr.set_parent_constraint(&btn_con, &content_card_con); + zephr.set_x_constraint(&btn_con, 0, .RELATIVE_PIXELS); + zephr.set_y_constraint(&btn_con, -24, .RELATIVE_PIXELS); + zephr.set_width_constraint(&btn_con, 0.30, .RELATIVE); + zephr.set_height_constraint(&btn_con, 0.3, .ASPECT_RATIO); + style = zephr.UiStyle{ + bg_color = zephr.Color{201, 146, 126, cast(u8)game.game_over_opacity}, + fg_color = zephr.Color{0, 0, 0, cast(u8)game.game_over_opacity}, + border_radius = 8, + align = .BOTTOM_CENTER, + }; + if (zephr.draw_button(&btn_con, "Try Again", style, btn_state)) { + reset_game(); + } +} + +draw_quit_dialog :: proc() { + dialog_con := zephr.DEFAULT_UI_CONSTRAINTS; + zephr.set_x_constraint(&dialog_con, 0, .FIXED); + zephr.set_y_constraint(&dialog_con, 0, .FIXED); + zephr.set_width_constraint(&dialog_con, 1, .RELATIVE); + zephr.set_height_constraint(&dialog_con, 1, .RELATIVE); + style := zephr.UiStyle { + bg_color = zephr.Color{0, 0, 0, 200}, + align = .CENTER, + }; + zephr.draw_quad(&dialog_con, style); + + zephr.set_width_constraint(&dialog_con, 0.4, .RELATIVE); + zephr.set_height_constraint(&dialog_con, 0.2, .RELATIVE); + style = zephr.UiStyle{ + bg_color = zephr.Color{135, 124, 124, 255}, + border_radius = 8, + align = .CENTER, + }; + zephr.draw_quad(&dialog_con, style); + + text_con := zephr.DEFAULT_UI_CONSTRAINTS + zephr.set_parent_constraint(&text_con, &dialog_con); + zephr.set_x_constraint(&text_con, 0, .FIXED); + zephr.set_y_constraint(&text_con, -0.25, .RELATIVE); + zephr.set_width_constraint(&text_con, 1, .RELATIVE_PIXELS); + zephr.draw_text("Are you sure you want to quit?", 36, text_con, zephr.COLOR_WHITE, .CENTER); + + btn_con := zephr.DEFAULT_UI_CONSTRAINTS + zephr.set_parent_constraint(&btn_con, &dialog_con); + zephr.set_width_constraint(&btn_con, 0.25, .RELATIVE); + zephr.set_height_constraint(&btn_con, 0.25, .RELATIVE); + zephr.set_y_constraint(&btn_con, -0.10, .RELATIVE); + zephr.set_x_constraint(&btn_con, -0.20, .RELATIVE); + style = zephr.UiStyle{ + bg_color = zephr.mult_color(zephr.COLOR_WHITE, 0.9), + fg_color = zephr.COLOR_BLACK, + border_radius = btn_con.height * 0.2, + align = .BOTTOM_CENTER, + }; + if (zephr.draw_button(&btn_con, "Yes", style, .ACTIVE)) { + zephr.quit(); + } + + zephr.set_y_constraint(&btn_con, -0.10, .RELATIVE); + zephr.set_x_constraint(&btn_con, 0.20, .RELATIVE); + if (zephr.draw_button(&btn_con, "No", style, .ACTIVE)) { + game.quit_dialog = false; + } +} diff --git a/glx/constants.odin b/glx/constants.odin new file mode 100644 index 0000000..9ff0a89 --- /dev/null +++ b/glx/constants.odin @@ -0,0 +1,11 @@ +package glx + +RENDER_TYPE :: 0x8011 +RGBA_BIT :: 0x00000001 +DEPTH_SIZE :: 12 +DOUBLEBUFFER :: 5 +SAMPLES :: 100001 +CONTEXT_MAJOR_VERSION_ARB :: 0x2091 +CONTEXT_MINOR_VERSION_ARB :: 0x2092 +CONTEXT_PROFILE_MASK_ARB :: 0x9126 +CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001 diff --git a/glx/wrappers.odin b/glx/wrappers.odin new file mode 100644 index 0000000..6e8724f --- /dev/null +++ b/glx/wrappers.odin @@ -0,0 +1,97 @@ +package glx + +import x11 "vendor:x11/xlib" +foreign import glx "system:GL" + +Drawable :: x11.XID + +@private +__FBConfigRec :: struct { + visualType: i32, + + transparentType: i32, + transparentRed, transparentGreen, transparentBlue, transparentAlpha: i32, + transparentIndex: i32, + + visualCaveat: i32, + + associatedVisualId: i32, + screen: i32, + + drawableType: i32, + renderType: i32, + + maxPbufferWidth, maxPbufferHeight, maxPbufferPixels: i32, + optimalPbufferWidth, optimalPbufferHeight: i32, /* for SGIX_pbuffer */ + + visualSelectGroup: i32, /* visuals grouped by select priority */ + + id: u32, + + rgbMode: b8, + colorIndexMode: b8, + doubleBufferMode: b8, + stereoMode: b8, + haveAccumBuffer: b8, + haveDepthBuffer: b8, + haveStencilBuffer: b8, + + /* The number of bits present in various buffers */ + accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits: i32, + depthBits: i32, + stencilBits: i32, + indexBits: i32, + redBits, greenBits, blueBits, alphaBits: i32, + redMask, greenMask, blueMask, alphaMask: u32, + + multiSampleSize: u32,/* Number of samples per pixel (0 if no ms) */ + + nMultiSampleBuffers: u32,/* Number of available ms buffers */ + maxAuxBuffers: i32, + + /* frame buffer level */ + level: i32, + + /* color ranges (for SGI_color_range) */ + extendedRange: b8, + minRed, maxRed: f64, + minGreen, maxGreen: f64, + minBlue, maxBlue: f64, + minAlpha, maxAlpha: f64, +} + +// apparently this isn't defined anywhere ??? +// so we define a minimal one according to this +// https://dri.freedesktop.org/docs/gallium/glxapi_8h-source.html +// see also: https://github.com/Tarnyko/EGLX/blob/b82af86a8a0daf3408fb7a6e7b07b02b01476626/EGLX.h#L280 +@private +__ContextRec :: struct { + currentDpy: ^x11.Display, + isDirect: b8, + currentDrawable: Drawable, + currentReadable: Drawable, + xid: x11.XID +} + +FBConfig :: ^__FBConfigRec +Context :: ^__ContextRec + +foreign glx { + @(link_name = "glXGetProcAddressARB") + GetProcAddressARB :: proc(name: ^u8) -> rawptr --- + @(link_name = "glXSwapBuffers") + SwapBuffers :: proc(display: ^x11.Display, drawable: Drawable) --- + @(link_name = "glXQueryVersion") + QueryVersion :: proc(display: ^x11.Display, major: ^i32, minor: ^i32) -> bool --- + @(link_name = "glXChooseFBConfig") + ChooseFBConfig :: proc(display: ^x11.Display, screen: i32, attrib_list: ^i32, nelements: ^i32) -> [^]FBConfig --- + @(link_name = "glXCreateContextAttribsARB") + CreateContextAttribsARB :: proc(display: ^x11.Display, config: FBConfig, share_context: Context, direct: bool, attrib_list: ^i32) -> Context --- + @(link_name = "glXDestroyContext") + DestroyContext :: proc(display: ^x11.Display, ctx: Context) --- + @(link_name = "glXSwapIntervalEXT") + SwapIntervalEXT :: proc(display: ^x11.Display, drawable: Drawable, interval: i32) -> bool --- + @(link_name = "glXMakeCurrent") + MakeCurrent :: proc(display: ^x11.Display, drawable: Drawable, ctx: Context) -> bool --- +} + diff --git a/main.odin b/main.odin new file mode 100644 index 0000000..4b3e12c --- /dev/null +++ b/main.odin @@ -0,0 +1,18 @@ +package main + +import gl "vendor:OpenGL" +import "glx" +import "zephr" + +font_path :: "assets/fonts/Rubik/Rubik-VariableFont_wght.ttf" +icon_path :: "assets/icon-128x128.png" +title :: "2048" + +main :: proc() { + zephr.init(font_path, icon_path, title, zephr.Vec2{1200, 800}, true) + + game_loop() + + zephr.deinit() +} + diff --git a/shaders/color_chooser.frag b/shaders/color_chooser.frag new file mode 100644 index 0000000..0d41bb9 --- /dev/null +++ b/shaders/color_chooser.frag @@ -0,0 +1,32 @@ +#version 330 core + +in vec2 v_TexCoords; +out vec4 FragColor; + +uniform bool isSlider; +uniform float sliderPercentage; + +//vec3 rgb2hsv(vec3 c){ +// vec4 K = vec4(0.0,-1.0 / 3.0,2.0 / 3.0,-1.0); +// vec4 p = mix(vec4(c.bg,K.wz),vec4(c.gb,K.xy),step(c.b,c.g)); +// vec4 q = mix(vec4(p.xyw,c.r),vec4(c.r,p.yzx),step(p.x,c.r)); +// float d = q.x - min(q.w,q.y); +// float e = 1.0e-10; +// return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),d / (q.x + e),q.x); +//} + +vec3 hsv2rgb(vec3 color){ + vec3 rgb = clamp(abs(mod(color.r * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0); + rgb = rgb * rgb * (3.0 - 2.0 * rgb); + return color.b * mix(vec3(1.0), rgb, color.g); +} + +void main() { + if (isSlider) { + vec3 color = hsv2rgb(vec3(v_TexCoords.y, 1.0, 1.0)); + FragColor = vec4(color, 1.0); + } else { + vec3 color = hsv2rgb(vec3(sliderPercentage, v_TexCoords.x, 1.0 - v_TexCoords.y)); + FragColor = vec4(color, 1.0); + } +} diff --git a/shaders/font.frag b/shaders/font.frag new file mode 100644 index 0000000..9140f1a --- /dev/null +++ b/shaders/font.frag @@ -0,0 +1,21 @@ +#version 330 core +in vec2 v_TexCoords; +in vec4 textColor; +out vec4 FragColor; + +uniform sampler2D text; + +const float smoothness = 0.05; +const float outlineDistance = 0.50; +const vec4 outlineColor = vec4(0.0, 0.0, 0.0, 1.0); + +void main() { + //float distance = texture(text, v_TexCoords).r; + //float outlineFactor = smoothstep(0.5 - smoothness, 0.5 + smoothness, distance); + //vec4 color = mix(outlineColor, textColor, outlineFactor); + //float alpha = smoothstep(outlineDistance - smoothness, outlineDistance + smoothness, distance); + + vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, v_TexCoords).r); + FragColor = textColor * sampled; + //FragColor = vec4(color.rgb, textColor.a * alpha); +} diff --git a/shaders/font.vert b/shaders/font.vert new file mode 100644 index 0000000..004d09b --- /dev/null +++ b/shaders/font.vert @@ -0,0 +1,21 @@ +#version 330 core +layout (location = 0) in vec2 vertex; + +// per instance +layout (location = 1) in vec4 offset; +layout (location = 2) in int tex_index; +layout (location = 3) in vec4 color; +layout (location = 4) in mat4 model; // this takes locations 4,5,6,7 + +out vec2 v_TexCoords; +out vec4 textColor; +uniform mat4 projection; +// buffer for all the 96 ascii characters' texcoords +uniform vec2 texcoords[96 * 4]; + +void main() { + vec2 pos = vec2((vertex.x) * offset.z, (vertex.y) * offset.w); + gl_Position = projection * model * vec4(pos + offset.xy, 0.0, 1.0); + v_TexCoords = texcoords[tex_index * 4 + gl_VertexID]; + textColor = color; +} diff --git a/shaders/ui.frag b/shaders/ui.frag new file mode 100644 index 0000000..7ffd499 --- /dev/null +++ b/shaders/ui.frag @@ -0,0 +1,40 @@ +#version 330 core + +in vec2 v_TexCoords; +out vec4 FragColor; + +uniform vec4 aColor; +uniform float borderRadius; +uniform float uiWidth; +uniform float uiHeight; +uniform bool hasTexture; + +uniform sampler2D tex; + +const float smoothness = 1.0; + +void main() { + float alpha = aColor.a; + + if (borderRadius > 0.0) { + vec2 dimensions = v_TexCoords * vec2(uiWidth, uiHeight); + float xMax = uiWidth - borderRadius; + float yMax = uiHeight - borderRadius; + + if (dimensions.x < borderRadius && dimensions.y < borderRadius) { + alpha *= 1.0 - smoothstep(borderRadius - smoothness, borderRadius + smoothness, length(dimensions - vec2(borderRadius))); + } else if (dimensions.x < borderRadius && dimensions.y > yMax) { + alpha *= 1.0 - smoothstep(borderRadius - smoothness, borderRadius + smoothness, length(dimensions - vec2(borderRadius, yMax))); + } else if (dimensions.x > xMax && dimensions.y < borderRadius) { + alpha *= 1.0 - smoothstep(borderRadius - smoothness, borderRadius + smoothness, length(dimensions - vec2(xMax, borderRadius))); + } else if (dimensions.x > xMax && dimensions.y > yMax) { + alpha *= 1.0 - smoothstep(borderRadius - smoothness, borderRadius + smoothness, length(dimensions - vec2(xMax, yMax))); + } + } + + if (hasTexture) { + FragColor = texture(tex, v_TexCoords) * vec4(aColor.rgb, alpha); + } else { + FragColor = vec4(aColor.rgb, alpha); + } +} diff --git a/shaders/ui.vert b/shaders/ui.vert new file mode 100644 index 0000000..213850e --- /dev/null +++ b/shaders/ui.vert @@ -0,0 +1,11 @@ +#version 330 core +layout (location = 0) in vec4 vertex; + +out vec2 v_TexCoords; +uniform mat4 projection; +uniform mat4 model; + +void main() { + gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0); + v_TexCoords = vertex.zw; +} diff --git a/xcursor/wrapper.odin b/xcursor/wrapper.odin new file mode 100644 index 0000000..82daf85 --- /dev/null +++ b/xcursor/wrapper.odin @@ -0,0 +1,9 @@ +package xcursor + +import x11 "vendor:x11/xlib" +foreign import xcursor "system:Xcursor" + +foreign xcursor { + @(link_name = "XcursorLibraryLoadCursor") + LibraryLoadCursor :: proc(display: ^x11.Display, name: cstring) -> x11.Cursor --- +} diff --git a/zephr/audio.odin b/zephr/audio.odin new file mode 100644 index 0000000..c2e8c1c --- /dev/null +++ b/zephr/audio.odin @@ -0,0 +1,3 @@ +package zephr + +// TODO: do audio which requries writing a binding for fmod diff --git a/zephr/shader.odin b/zephr/shader.odin new file mode 100644 index 0000000..966cbb3 --- /dev/null +++ b/zephr/shader.odin @@ -0,0 +1,57 @@ +package zephr + +import "core:fmt" + +import gl "vendor:OpenGL" + +Shader :: struct { + program: u32 +} + +create_shader :: proc(vertex_path: string, fragment_path: string) -> (Shader, bool) { + shader: Shader + + program, success := gl.load_shaders(vertex_path, fragment_path) + shader.program = program; + + return shader, success; +} + +use_shader :: proc(shader: Shader) { + gl.UseProgram(shader.program); +} + +set_mat4f :: proc(shader: Shader, name: cstring, mat4: Mat4, transpose: bool = false) { + mat4 := mat4 + loc := gl.GetUniformLocation(shader.program, name); + gl.UniformMatrix4fv(loc, 1, transpose, raw_data(&mat4)) +} + +set_float :: proc(shader: Shader, name: cstring, val: f32) { + loc := gl.GetUniformLocation(shader.program, name); + gl.Uniform1f(loc, val); +} + +set_int :: proc(shader: Shader, name: cstring, val: i32) { + loc := gl.GetUniformLocation(shader.program, name); + gl.Uniform1i(loc, val); +} + +set_bool :: proc(shader: Shader, name: cstring, val: bool) { + set_int(shader, name, cast(i32)val); +} + +set_vec2f :: proc(shader: Shader, name: cstring, val1: f32, val2: f32) { + loc := gl.GetUniformLocation(shader.program, name); + gl.Uniform2f(loc, val1, val2); +} + +set_vec3f :: proc(shader: Shader, name: cstring, val1: f32, val2: f32, val3: f32) { + loc := gl.GetUniformLocation(shader.program, name); + gl.Uniform3f(loc, val1, val2, val3); +} + +set_vec4f :: proc(shader: Shader, name: cstring, val1: f32, val2: f32, val3: f32, val4: f32) { + loc := gl.GetUniformLocation(shader.program, name); + gl.Uniform4f(loc, val1, val2, val3, val4); +} diff --git a/zephr/text.odin b/zephr/text.odin new file mode 100644 index 0000000..98d1621 --- /dev/null +++ b/zephr/text.odin @@ -0,0 +1,419 @@ +package zephr + +import "core:fmt" + +import gl "vendor:OpenGL" + +import FT "../freetype" + +Character :: struct { + size: Vec2, + bearing: Vec2, + advance: u32, + tex_coords: [4]Vec2, +} + +Font :: struct { + atlas_tex_id: TextureId, + characters: [128]Character, +} + +// GlyphInstance needs to be 100 bytes (meaning no padding) otherwise the data we send to the shader +// is misaligned and we get rendering errors +#assert(size_of(GlyphInstance) == 100) + +GlyphInstance :: struct #packed { + pos: Vec4, + tex_coords_idx: u32, + color: Vec4, + model: Mat4, +} + +GlyphInstanceList :: [dynamic]GlyphInstance + +@private +FONT_PIXEL_SIZE :: 100 +@private +LINE_HEIGHT :: 2.0 + +@private +font_shader : Shader +@private +font_vao : u32 +@private +font_instance_vbo : u32 + + +init_freetype :: proc(font_path: cstring) -> i32 { + ft: FT.Library; + if (FT.Init_FreeType(&ft) != 0) { + return -1; + } + + face: FT.Face; + if (FT.New_Face(ft, font_path, 0, &face) != 0) { + return -2; + } + + // sets the variable font to be bold + /* if ((face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { */ + /* printf("[INFO] Got a variable font\n"); */ + /* FT_MM_Var *mm; */ + /* FT_Get_MM_Var(face, &mm); */ + + /* FT_Set_Var_Design_Coordinates(face, mm->num_namedstyles, mm->namedstyle[mm->num_namedstyles - 4].coords); */ + + /* FT_Done_MM_Var(ft, mm); */ + /* } */ + + FT.Set_Pixel_Sizes(face, 0, FONT_PIXEL_SIZE); + + gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1); + + pen_x, pen_y: u32 + + /* FT_UInt glyph_idx; */ + /* FT_ULong c = FT_Get_First_Char(face, &glyph_idx); */ + + tex_width, tex_height: u32; + for i in 32..<128 { + if (FT.Load_Char(face, cast(u64)i, .RENDER) != 0) { + fmt.printf("[ERROR]: failed to load glyph for char '0x%x'\n", i); + } + + /* FT_Render_Glyph(face->glyph, FT_RENDER_MODE_SDF); */ + + tex_width += face.glyph.bitmap.width + 1; + tex_height = max(tex_height, face.glyph.bitmap.rows); + } + + pixels := make([dynamic]u8, tex_width * tex_height); + defer delete(pixels) + + for i in 32..<128 { + /* while (glyph_idx) { */ + if (FT.Load_Char(face, cast(u64)i, .RENDER) != 0) { + fmt.printf("[ERROR]: failed to load glyph for char '0x%x'\n", i); + } + + /* FT_Render_Glyph(face->glyph, FT_RENDER_MODE_SDF); */ + + bmp := &face.glyph.bitmap; + + if (pen_x + bmp.width >= tex_width) { + pen_x = 0; + pen_y += cast(u32)(1 + (face.size.metrics.height >> 6)); + } + + for row in 0.. i32 { + font_vbo, font_ebo: u32; + + res := init_freetype(font_path); + if (res != 0) { + return res; + } + + l_font_shader, success := create_shader("shaders/font.vert", "shaders/font.frag"); + + if (!success) { + fmt.println("[FATAL] Failed to create font shader") + return -2; + } + + font_shader = l_font_shader; + + gl.GenVertexArrays(1, &font_vao); + gl.GenBuffers(1, &font_vbo); + gl.GenBuffers(1, &font_instance_vbo); + gl.GenBuffers(1, &font_ebo); + + quad_vertices := [4][2]f32 { + {0.0, 1.0}, // top left + {1.0, 1.0}, // top right + {1.0, 0.0}, // bottom right + {0.0, 0.0}, // bottom left + }; + + quad_indices := [6]u32 { + 0, 1, 2, + 2, 3, 0, + }; + + gl.BindVertexArray(font_vao); + + // font quad vbo + gl.BindBuffer(gl.ARRAY_BUFFER, font_vbo); + gl.BufferData(gl.ARRAY_BUFFER, size_of(quad_vertices), &quad_vertices, gl.STATIC_DRAW); + gl.EnableVertexAttribArray(0); + gl.VertexAttribPointer(0, 2, gl.FLOAT, gl.FALSE, 2 * size_of(f32), 0); + + // font instance vbo + gl.BindBuffer(gl.ARRAY_BUFFER, font_instance_vbo); + gl.EnableVertexAttribArray(1); + gl.VertexAttribPointer(1, 4, gl.FLOAT, gl.FALSE, size_of(GlyphInstance), 0); + gl.VertexAttribDivisor(1, 1); + gl.EnableVertexAttribArray(2); + gl.VertexAttribIPointer(2, 1, gl.INT, size_of(GlyphInstance), size_of(Vec4)); + gl.VertexAttribDivisor(2, 1); + gl.EnableVertexAttribArray(3); + gl.VertexAttribPointer(3, 4, gl.FLOAT, gl.FALSE, size_of(GlyphInstance), (size_of(Vec4) + size_of(i32))); + gl.VertexAttribDivisor(3, 1); + gl.EnableVertexAttribArray(4); + gl.EnableVertexAttribArray(5); + gl.EnableVertexAttribArray(6); + gl.EnableVertexAttribArray(7); + gl.VertexAttribPointer(4, 4, gl.FLOAT, gl.FALSE, size_of(GlyphInstance), (size_of(Vec4) * 2 + size_of(i32))); + gl.VertexAttribPointer(5, 4, gl.FLOAT, gl.FALSE, size_of(GlyphInstance), (size_of(Vec4) * 3 + size_of(i32))); + gl.VertexAttribPointer(6, 4, gl.FLOAT, gl.FALSE, size_of(GlyphInstance), (size_of(Vec4) * 4 + size_of(i32))); + gl.VertexAttribPointer(7, 4, gl.FLOAT, gl.FALSE, size_of(GlyphInstance), (size_of(Vec4) * 5 + size_of(i32))); + gl.VertexAttribDivisor(4, 1); + gl.VertexAttribDivisor(5, 1); + gl.VertexAttribDivisor(6, 1); + gl.VertexAttribDivisor(7, 1); + + // font ebo + gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, font_ebo); + gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, size_of(quad_indices), &quad_indices, gl.STATIC_DRAW); + + use_shader(font_shader); + + for i in 32..<128 { + for j in 0..<4 { + buf: [24]byte + text := fmt.bprintf(buf[:], "texcoords[%d]", (i - 32) * 4 + j); + set_vec2f(font_shader, cstring(raw_data(text)), zephr_ctx.font.characters[i].tex_coords[j].x, zephr_ctx.font.characters[i].tex_coords[j].y); + } + } + + gl.BindBuffer(gl.ARRAY_BUFFER, 0); + gl.BindVertexArray(0); + + return 0; +} + + +calculate_text_size :: proc(text: string, font_size: u32) -> Vec2 { + scale := cast(f32)font_size / FONT_PIXEL_SIZE; + size : Vec2 = --- + w: f32 = 0; + h: f32 = 0; + max_bearing_h: f32 = 0; + + // NOTE: I don't like looping through the characters twice, but it's fine for now + for i in 0.. 1) { + w -= ch.bearing.x; + } + + // remove the trailing width of the last character + if (i == len(text) - 1) { + w -= ((cast(f32)ch.advance / 64) - (ch.bearing.x + ch.size.x)); + } + + // if we only have one character in the text, then remove the bearing width + if (len(text) == 1) { + w -= (ch.bearing.x); + } + + h = max(h, max_bearing_h - ch.bearing.y + ch.size.y); + + if (text[i] == '\n') { + w = 0; + h += max_bearing_h; + } + } + size.x = w * scale; + size.y = h * scale; + + return size; +} + +draw_text :: proc(text: string, font_size: u32, constraints: UiConstraints, color: Color, alignment: Alignment) { + glyph_instance_list := get_glyph_instance_list_from_text(text, font_size, constraints, color, alignment); + + gl.ActiveTexture(gl.TEXTURE0); + gl.BindTexture(gl.TEXTURE_2D, zephr_ctx.font.atlas_tex_id); + gl.BindVertexArray(font_vao); + + gl.BindBuffer(gl.ARRAY_BUFFER, font_instance_vbo); + gl.BufferData(gl.ARRAY_BUFFER, size_of(GlyphInstance) * len(glyph_instance_list), raw_data(glyph_instance_list), gl.DYNAMIC_DRAW); + + gl.DrawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil, cast(i32)len(glyph_instance_list)) + + gl.BindVertexArray(0); + gl.BindTexture(gl.TEXTURE_2D, 0); + + delete(glyph_instance_list) +} + +draw_text_batch :: proc(batch: ^GlyphInstanceList) { + gl.ActiveTexture(gl.TEXTURE0); + gl.BindTexture(gl.TEXTURE_2D, zephr_ctx.font.atlas_tex_id); + gl.BindVertexArray(font_vao); + + gl.BindBuffer(gl.ARRAY_BUFFER, font_instance_vbo); + gl.BufferData(gl.ARRAY_BUFFER, size_of(GlyphInstance) * len(batch), raw_data(batch^), gl.DYNAMIC_DRAW); + + gl.DrawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil, cast(i32)len(batch)) + + gl.BindVertexArray(0); + gl.BindTexture(gl.TEXTURE_2D, 0); + + delete(batch^) +} + +get_glyph_instance_list_from_text :: proc(text: string, font_size: u32, constraints: UiConstraints, color: Color, alignment: Alignment) -> GlyphInstanceList { + constraints := constraints + use_shader(font_shader); + text_color := Vec4{ cast(f32)color.r / 255, cast(f32)color.g / 255, cast(f32)color.b / 255, cast(f32)color.a / 255 }; + + set_mat4f(font_shader, "projection", zephr_ctx.projection) + + rect: Rect + + apply_constraints(&constraints, &rect.pos, &rect.size); + + text_size := calculate_text_size(text, FONT_PIXEL_SIZE); + font_scale := cast(f32)font_size / FONT_PIXEL_SIZE * rect.size.x; + + apply_alignment(alignment, &constraints, Vec2{ text_size.x * font_scale, text_size.y * font_scale }, &rect.pos); + + model := identity() + scale(&model, Vec3{font_scale, font_scale, 1}); + + // rotate around the center point of the text + translate(&model, Vec3{-text_size.x * font_scale / 2, -text_size.y * font_scale / 2, 0}); + rotate(&model, constraints.rotation, Vec3{0, 0, 1}); + translate(&model, Vec3{text_size.x *font_scale / 2, text_size.y * font_scale / 2, 0}); + + translate(&model, Vec3{rect.pos.x, rect.pos.y, 0}); + + max_bearing_h: f32 = 0; + for i in 0..> 6); + c += 1; + } + + return glyph_instance_list; +} + +add_text_instance :: proc(batch: ^GlyphInstanceList, text: string, font_size: u32, constraints: UiConstraints, color: Color, alignment: Alignment) { + glyph_instance_list := get_glyph_instance_list_from_text(text, font_size, constraints, color, alignment); + + append(batch, ..glyph_instance_list[:]) + + delete(glyph_instance_list); +} + diff --git a/zephr/texture.odin b/zephr/texture.odin new file mode 100644 index 0000000..1efa36f --- /dev/null +++ b/zephr/texture.odin @@ -0,0 +1,45 @@ +package zephr + +import gl "vendor:OpenGL" +import stb "vendor:stb/image" + +TextureId :: u32 + +load_texture :: proc(path: cstring) -> TextureId { + texture_id: TextureId; + width, height, channels: i32 + data := stb.load(path, &width, &height, &channels, 4) // RGBA + defer stb.image_free(data) + + format := gl.RGBA; + + switch (channels) { + case 1: + format = gl.RED; + break; + case 2: + format = gl.RG; + break; + case 3: + format = gl.RGB; + break; + case 4: + format = gl.RGBA; + break; + } + + gl.GenTextures(1, &texture_id); + gl.BindTexture(gl.TEXTURE_2D, texture_id); + + gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + + gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); + gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + + gl.TexImage2D(gl.TEXTURE_2D, 0, cast(i32)format, width, height, 0, cast(u32)format, gl.UNSIGNED_BYTE, data); + + gl.GenerateMipmap(gl.TEXTURE_2D); + + return texture_id; +} diff --git a/zephr/timer.odin b/zephr/timer.odin new file mode 100644 index 0000000..b22fe1b --- /dev/null +++ b/zephr/timer.odin @@ -0,0 +1,35 @@ +package zephr + +import "core:fmt" +import "core:time" + +TimerState :: enum { + RUNNING, + PAUSED, + STOPPED, +} + +Timer :: struct { + start: f64, + elapsed: f64, + duration: f32, + state: TimerState, +} + +@private +TIMER : time.Stopwatch + +@private +start_internal_timer :: proc() { + time.stopwatch_start(&TIMER) +} + +get_time :: proc() -> time.Duration { + return time.stopwatch_duration(TIMER) +} + +start_timer :: proc(timer: ^time.Stopwatch) { + time.stopwatch_start(timer) +} + +// TODO: incomplete diff --git a/zephr/ui.odin b/zephr/ui.odin new file mode 100644 index 0000000..6181a7f --- /dev/null +++ b/zephr/ui.odin @@ -0,0 +1,938 @@ +package zephr + +import "core:fmt" +import "core:os" +import "core:mem" + +import gl "vendor:OpenGL" + +UiIdHash :: u32 + +Alignment :: enum { + TOP_LEFT, + TOP_CENTER, + TOP_RIGHT, + LEFT_CENTER, + CENTER, + RIGHT_CENTER, + BOTTOM_LEFT, + BOTTOM_CENTER, + BOTTOM_RIGHT, +} + +UiConstraint :: enum { + FIXED, + RELATIVE, + RELATIVE_PIXELS, + ASPECT_RATIO, +} + +ButtonState :: enum { + ACTIVE, + INACTIVE, + DISABLED, +} + +UiConstraints :: struct { + x: f32, + y: f32, + width: f32, + height: f32, + rotation: f32, + scale: Vec2, + parent: ^UiConstraints, +} + +Rect :: struct { + pos: Vec2, + size: Vec2, +} + +UiStyle :: struct { + bg_color: Color, + fg_color: Color, + border_radius: f32, + align: Alignment, +} + +Ui :: struct { + active_element: UiIdHash, + popup_open: bool, + popup_parent_hash: UiIdHash, + popup_rect: Rect, + popup_parent_constraints: UiConstraints, + popup_revert_color: ^Color, +} + +@private +ui_shader: Shader +@private +color_chooser_shader: Shader +@private +ui_vao: u32 +@private +ui_vbo: u32 + +DEFAULT_UI_CONSTRAINTS :: UiConstraints{ + x = 0, + y = 0, + width = 0, + height = 0, + rotation = 0, + scale = Vec2{1, 1}, + parent = nil, +} + +@private +ui_init :: proc(font_path: cstring) { + res := init_fonts(font_path); + if (res == -1) { + fmt.printf("[ERROR]: could not initialize freetype library\n"); + os.exit(1) + } else if (res == -2) { + fmt.printf("[ERROR]: could not load font file: \"%s\"\n", font_path); + os.exit(1) + } else if (res != 0) { + os.exit(1) + } + + l_ui_shader, success1 := create_shader("shaders/ui.vert", "shaders/ui.frag") + l_color_chooser_shader, success2 := create_shader("shaders/ui.vert", "shaders/color_chooser.frag") + + ui_shader = l_ui_shader + color_chooser_shader = l_color_chooser_shader + + if !success1 || !success2 { + fmt.printf("[ERROR]: could not load ui shaders\n"); + os.exit(1) + } + + gl.GenVertexArrays(1, &ui_vao); + gl.GenBuffers(1, &ui_vbo); + + gl.BindVertexArray(ui_vao); + gl.BindBuffer(gl.ARRAY_BUFFER, ui_vbo); + gl.BufferData(gl.ARRAY_BUFFER, size_of(f32) * 6 * 4, nil, gl.DYNAMIC_DRAW); + gl.EnableVertexAttribArray(0); + gl.VertexAttribPointer(0, 4, gl.FLOAT, gl.FALSE, 4 * size_of(f32), 0); + + gl.BindBuffer(gl.ARRAY_BUFFER, 0); + gl.BindVertexArray(0); +} + +set_parent_constraint :: proc(constraints: ^UiConstraints, parent_constraints: ^UiConstraints) { + constraints.parent = parent_constraints; +} + +set_x_constraint :: proc(constraints: ^UiConstraints, value: f32, type: UiConstraint) { + switch (type) { + case .ASPECT_RATIO: // no-op. fall back to FIXED + fallthrough + case .FIXED: + constraints.x = value; + case .RELATIVE: + if (constraints.parent != nil) { + constraints.x = (value * constraints.parent.width); + } else { + constraints.x = (value * zephr_ctx.window.size.x); + } + case .RELATIVE_PIXELS: + constraints.x = zephr_ctx.window.size.x / zephr_ctx.screen_size.x * value; + } + + if (constraints.parent != nil) { + constraints.x += constraints.parent.x; + } +} + +set_y_constraint :: proc(constraints: ^UiConstraints, value: f32, type: UiConstraint) { + switch (type) { + case .ASPECT_RATIO: // no-op. fall back to FIXED + fallthrough + case .FIXED: + constraints.y = value; + case .RELATIVE: + if (constraints.parent != nil) { + constraints.y = (value * constraints.parent.height); + } else { + constraints.y = (value * zephr_ctx.window.size.y); + } + case .RELATIVE_PIXELS: + constraints.y = zephr_ctx.window.size.y / zephr_ctx.screen_size.y * value; + } + + if (constraints.parent != nil) { + constraints.y += constraints.parent.y; + } +} + +set_width_constraint :: proc(constraints: ^UiConstraints, value: f32, type: UiConstraint) { + switch (type) { + case .FIXED: + constraints.width = value; + case .RELATIVE: + if (constraints.parent != nil) { + constraints.width = (value * constraints.parent.width); + } else { + constraints.width = (value * zephr_ctx.window.size.x); + } + case .RELATIVE_PIXELS: + constraints.width = zephr_ctx.window.size.x / zephr_ctx.screen_size.x * value; + case .ASPECT_RATIO: + constraints.width = constraints.height * value; + } +} + +set_height_constraint :: proc(constraints: ^UiConstraints, value: f32, type: UiConstraint) { + switch (type) { + case .FIXED: + constraints.height = value; + case .RELATIVE: + if (constraints.parent != nil) { + constraints.height = (value * constraints.parent.height); + } else { + constraints.height = (value * zephr_ctx.window.size.y); + } + case .RELATIVE_PIXELS: + constraints.height = zephr_ctx.window.size.y / zephr_ctx.screen_size.y * value; + case .ASPECT_RATIO: + constraints.height = constraints.width * value; + } +} + +set_rotation_constraint :: proc(constraints: ^UiConstraints, angle_d: f32) { + constraints.rotation = angle_d; +} + +@private +apply_constraints :: proc(constraints: ^UiConstraints, pos: ^Vec2, size: ^Vec2) { + pos^ = Vec2{constraints.x, constraints.y}; + size^ = Vec2{constraints.width, constraints.height}; +} + +@private +apply_alignment :: proc(align: Alignment, constraints: ^UiConstraints, size: Vec2, pos: ^Vec2) { + // if we don't have a parent then we're a top level element and we should align against the window + parent_size := Vec2{zephr_ctx.window.size.x, zephr_ctx.window.size.y}; + if (constraints.parent != nil) { + parent_size = Vec2{constraints.parent.width, constraints.parent.height}; + } + + switch (align) { + case .TOP_LEFT: + pos.x = pos.x; + pos.y = pos.y; + case .TOP_CENTER: + pos.x += parent_size.x / 2 - size.x / 2; + pos.y = pos.y; + case .TOP_RIGHT: + pos.x += parent_size.x - size.x; + pos.y = pos.y; + case .BOTTOM_LEFT: + pos.x = pos.x; + pos.y += parent_size.y - size.y; + case .BOTTOM_CENTER: + pos.x += parent_size.x / 2 - size.x / 2; + pos.y += parent_size.y - size.y; + case .BOTTOM_RIGHT: + pos.x += parent_size.x - size.x; + pos.y += parent_size.y - size.y; + case .LEFT_CENTER: + pos.x = pos.x; + pos.y += parent_size.y / 2 - size.y / 2; + case .RIGHT_CENTER: + pos.x += parent_size.x - size.x; + pos.y += parent_size.y / 2 - size.y / 2; + case .CENTER: + pos.x += parent_size.x / 2 - size.x / 2; + pos.y += parent_size.y / 2 - size.y / 2; + } +} + +@private +// TODO: make this handle rotated and scaled rects too +inside_rect :: proc(rect: Rect, point: Vec2) -> bool { + return point.x >= rect.pos.x && point.x <= rect.pos.x + rect.size.x && + point.y >= rect.pos.y && point.y <= rect.pos.y + rect.size.y; +} + +draw_quad :: proc(constraints: ^UiConstraints, style: UiStyle) { + use_shader(ui_shader) + + set_vec4f(ui_shader, "aColor", cast(f32)style.bg_color.r / 255, cast(f32)style.bg_color.g / 255, cast(f32)style.bg_color.b / 255, cast(f32)style.bg_color.a / 255) + set_float(ui_shader, "uiWidth", constraints.width) + set_float(ui_shader, "uiHeight", constraints.height) + set_float(ui_shader, "borderRadius", style.border_radius) + set_mat4f(ui_shader, "projection", zephr_ctx.projection) + + rect: Rect = --- + + apply_constraints(constraints, &rect.pos, &rect.size) + apply_alignment(style.align, constraints, rect.size, &rect.pos) + + // set the positions after applying alignment so children can use them + constraints.x = rect.pos.x; + constraints.y = rect.pos.y; + + model := identity(); + translate(&model, Vec3{-rect.size.x / 2, -rect.size.y / 2, 0}); + scale(&model, Vec3{constraints.scale.x, constraints.scale.y, 1}); + translate(&model, Vec3{rect.size.x / 2, rect.size.y / 2, 0}); + + translate(&model, Vec3{-rect.size.x / 2, -rect.size.y / 2, 0}); + rotate(&model, constraints.rotation, Vec3{0, 0, 1}); + translate(&model, Vec3{rect.size.x / 2, rect.size.y / 2, 0}); + + translate(&model, Vec3{rect.pos.x, rect.pos.y, 0}); + + set_mat4f(ui_shader, "model", model); + + gl.BindVertexArray(ui_vao) + + vertices: [6][4]f32 = { + // bottom left tri + {0, 0 + rect.size.y, 0.0, 1.0}, + {0, 0, 0.0, 0.0}, + {0 + rect.size.x, 0, 1.0, 0.0}, + + // top right tri + {0, 0 + rect.size.y, 0.0, 1.0}, + {0 + rect.size.x, 0, 1.0, 0.0}, + {0 + rect.size.x, 0 + rect.size.y, 1.0, 1.0}, + }; + + gl.BindBuffer(gl.ARRAY_BUFFER, ui_vbo); + gl.BufferSubData(gl.ARRAY_BUFFER, 0, size_of(vertices), raw_data(&vertices)); + gl.BindBuffer(gl.ARRAY_BUFFER, 0); + + gl.DrawArrays(gl.TRIANGLES, 0, 6); + + gl.BindVertexArray(0); +} + +draw_circle :: proc(constraints: ^UiConstraints, style: UiStyle) { + radius: f32 = 0; + + if (constraints.width > constraints.height) { + radius = constraints.height / 2; + } else { + radius = constraints.width / 2; + } + + new_style := style; + new_style.border_radius = radius; + + draw_quad(constraints, new_style); +} + +draw_triangle :: proc(constraints: ^UiConstraints, style: UiStyle) { + use_shader(ui_shader); + + set_vec4f(ui_shader, "aColor", cast(f32)style.bg_color.r / 255, cast(f32)style.bg_color.g / 255, cast(f32)style.bg_color.b / 255, cast(f32)style.bg_color.a / 255); + set_float(ui_shader, "borderRadius", 0); + set_mat4f(ui_shader, "projection", zephr_ctx.projection) + + rect: Rect = --- + + apply_constraints(constraints, &rect.pos, &rect.size); + apply_alignment(style.align, constraints, rect.size, &rect.pos); + + // set the positions after applying alignment so children can use them + constraints.x = rect.pos.x; + constraints.y = rect.pos.y; + + model := identity(); + translate(&model, Vec3{-rect.size.x / 2, -rect.size.y / 2, 0}); + scale(&model, Vec3{constraints.scale.x, constraints.scale.y, 1}); + translate(&model, Vec3{rect.size.x / 2, rect.size.y / 2, 0}); + + translate(&model, Vec3{-rect.size.x / 2, -rect.size.y / 2, 0}); + rotate(&model, constraints.rotation, Vec3{0, 0, 1}); + translate(&model, Vec3{rect.size.x / 2, rect.size.y / 2, 0}); + + translate(&model, Vec3{rect.pos.x, rect.pos.y, 0}); + + set_mat4f(ui_shader, "model", model); + + gl.BindVertexArray(ui_vao); + + vertices := [3][4]f32 { + {0 + rect.size.x, 0, 0.0, 0.0}, + {0, 0, 0.0, 0.0}, + {0 + rect.size.x / 2, 0 + rect.size.y, 0.0, 0.0}, + }; + + gl.BindBuffer(gl.ARRAY_BUFFER, ui_vbo); + gl.BufferSubData(gl.ARRAY_BUFFER, 0, size_of(vertices), raw_data(&vertices)) + gl.BindBuffer(gl.ARRAY_BUFFER, 0); + + gl.DrawArrays(gl.TRIANGLES, 0, 3); + + gl.BindVertexArray(0); +} + +draw_texture :: proc(constraints: ^UiConstraints, texture_id: TextureId, color: Color, radius: f32, align: Alignment) { + use_shader(ui_shader); + + set_vec4f(ui_shader, "aColor", cast(f32)color.r / 255, cast(f32)color.g / 255, cast(f32)color.b / 255, cast(f32)color.a / 255); + set_float(ui_shader, "uiWidth", constraints.width); + set_float(ui_shader, "uiHeight", constraints.height); + set_float(ui_shader, "borderRadius", radius); + set_bool(ui_shader, "hasTexture", true); + + set_mat4f(ui_shader, "projection", zephr_ctx.projection) + + rect: Rect = --- + + apply_constraints(constraints, &rect.pos, &rect.size); + apply_alignment(align, constraints, rect.size, &rect.pos); + + // set the positions after applying alignment so children can use them + constraints.x = rect.pos.x; + constraints.y = rect.pos.y; + + model := identity(); + translate(&model, Vec3{-rect.size.x / 2, -rect.size.y / 2, 0}); + scale(&model, Vec3{constraints.scale.x, constraints.scale.y, 1}); + translate(&model, Vec3{rect.size.x / 2, rect.size.y / 2, 0}); + + translate(&model, Vec3{-rect.size.x / 2, -rect.size.y / 2, 0}); + rotate(&model, constraints.rotation, Vec3{0, 0, 1}); + translate(&model, Vec3{rect.size.x / 2, rect.size.y / 2, 0}); + + translate(&model, Vec3{rect.pos.x, rect.pos.y, 0}); + + set_mat4f(ui_shader, "model", model) + + gl.BindVertexArray(ui_vao); + + vertices := [6][4]f32 { + // bottom left tri + {0, 0 + rect.size.y, 0.0, 1.0}, + {0, 0, 0.0, 0.0}, + {0 + rect.size.x, 0, 1.0, 0.0}, + + // top right tri + {0, 0 + rect.size.y, 0.0, 1.0}, + {0 + rect.size.x, 0, 1.0, 0.0}, + {0 + rect.size.x, 0 + rect.size.y, 1.0, 1.0}, + }; + + gl.BindBuffer(gl.ARRAY_BUFFER, ui_vbo); + gl.BufferSubData(gl.ARRAY_BUFFER, 0, size_of(vertices), raw_data(&vertices)) + gl.BindBuffer(gl.ARRAY_BUFFER, 0); + + gl.ActiveTexture(gl.TEXTURE0); + gl.BindTexture(gl.TEXTURE_2D, texture_id); + + gl.DrawArrays(gl.TRIANGLES, 0, 6); + + gl.BindVertexArray(0); + set_bool(ui_shader, "hasTexture", false); +} + +draw_button :: proc(constraints: ^UiConstraints, text: string, style: UiStyle, state: ButtonState, caller := #caller_location) -> bool { + line := caller.line + line_bytes := mem.byte_slice(&line, size_of(line)) + hash := fnv_hash32(transmute([]byte)caller.file_path, cast(u32)len(caller.file_path), FNV_HASH32_INIT) + hash = fnv_hash32(line_bytes, size_of(caller.line), hash) + + style := style + rect: Rect = --- + + apply_constraints(constraints, &rect.pos, &rect.size); + apply_alignment(style.align, constraints, rect.size, &rect.pos); + + is_hovered := inside_rect(rect, zephr_ctx.mouse.pos); + is_held := zephr_ctx.ui.active_element == hash + left_mouse_pressed := zephr_ctx.mouse.pressed && zephr_ctx.mouse.button == .BUTTON_LEFT; + left_mouse_released := zephr_ctx.mouse.released && zephr_ctx.mouse.button == .BUTTON_LEFT; + clicked := false; + + if (zephr_ctx.ui.active_element == 0) { + if (is_hovered && left_mouse_pressed) { + zephr_ctx.ui.active_element = hash; + } + } else if (zephr_ctx.ui.active_element == hash) { + if (left_mouse_released) { + zephr_ctx.ui.active_element = 0; + + if (is_hovered) { + clicked = true; + } + } + } + + if (is_hovered && state == .ACTIVE) { + set_cursor(Cursor.HAND); + + if (is_held) { + style.bg_color = mult_color(style.bg_color, 0.8); + draw_quad(constraints, style); + } else { + style.bg_color = mult_color(style.bg_color, 0.9); + draw_quad(constraints, style); + } + } else if (state == .DISABLED) { + if (is_hovered) { + set_cursor(Cursor.DISABLED); + } + + style.bg_color.a = 100; + style.fg_color.a = 100; + draw_quad(constraints, style); + } else { + draw_quad(constraints, style); + } + + if (text != "") { + text_constraints := DEFAULT_UI_CONSTRAINTS + + set_parent_constraint(&text_constraints, constraints); + set_x_constraint(&text_constraints, 0, .RELATIVE_PIXELS); + set_y_constraint(&text_constraints, 0, .RELATIVE_PIXELS); + set_width_constraint(&text_constraints, 1.0, .RELATIVE_PIXELS); + + font_size := ((constraints.width) / (text_constraints.width * 0.1 * 65)); + + // TODO: need to adjust the font size based on the text height + + draw_text(text, cast(u32)font_size, text_constraints, style.fg_color, .CENTER); + } + + if (clicked && state == .ACTIVE) { + return true; + } + + return false; +} + +draw_icon_button :: proc(constraints: ^UiConstraints, icon_tex_id: TextureId, style: UiStyle, state: ButtonState, caller := #caller_location) -> bool { + assert(icon_tex_id != 0, "draw_icon_button() requires that you provide an icon texture"); + + line := caller.line + line_bytes := mem.byte_slice(&line, size_of(line)) + hash := fnv_hash32(transmute([]byte)caller.file_path, cast(u32)len(caller.file_path), FNV_HASH32_INIT) + hash = fnv_hash32(line_bytes, size_of(caller.line), hash) + + style := style + rect: Rect = --- + + apply_constraints(constraints, &rect.pos, &rect.size); + apply_alignment(style.align, constraints, rect.size, &rect.pos); + + is_held := zephr_ctx.ui.active_element == hash; + is_hovered := inside_rect(rect, zephr_ctx.mouse.pos); + left_mouse_pressed := zephr_ctx.mouse.pressed && zephr_ctx.mouse.button == .BUTTON_LEFT; + left_mouse_released := zephr_ctx.mouse.released && zephr_ctx.mouse.button == .BUTTON_LEFT; + clicked := false; + + if (zephr_ctx.ui.active_element == 0) { + if (is_hovered && left_mouse_pressed) { + zephr_ctx.ui.active_element = hash; + } + } else if (zephr_ctx.ui.active_element == hash) { + if (left_mouse_released) { + zephr_ctx.ui.active_element = 0; + + if (is_hovered) { + clicked = true; + } + } + } + + if (is_hovered && state == .ACTIVE) { + set_cursor(.HAND); + + if (is_held) { + style.bg_color = mult_color(style.bg_color, 0.8); + style.fg_color = mult_color(style.fg_color, 0.8); + } else { + style.bg_color = mult_color(style.bg_color, 0.9); + style.fg_color = mult_color(style.fg_color, 0.9); + } + } else if (state == .DISABLED) { + if (is_hovered) { + set_cursor(.DISABLED); + } + + style.fg_color.a = 100; + style.bg_color.a = 100; + } + + draw_quad(constraints, style); + + icon_constraints := DEFAULT_UI_CONSTRAINTS + + set_parent_constraint(&icon_constraints, constraints); + set_x_constraint(&icon_constraints, 0, .RELATIVE_PIXELS); + set_y_constraint(&icon_constraints, 0, .RELATIVE_PIXELS); + set_width_constraint(&icon_constraints, constraints.width * 0.8, .FIXED); + set_height_constraint(&icon_constraints, constraints.height * 0.8, .FIXED); + draw_texture(&icon_constraints, icon_tex_id, style.fg_color, 0, .CENTER); + + if (clicked && state == .ACTIVE) { + return true; + } + + return false; +} + +@private +draw_color_picker_slider :: proc(constraints: ^UiConstraints, align: Alignment, caller := #caller_location) -> f32 { + @static + slider_selection: f32 = 0 + @static + dragging := false + + line := caller.line + line_bytes := mem.byte_slice(&line, size_of(line)) + hash := fnv_hash32(transmute([]byte)caller.file_path, cast(u32)len(caller.file_path), FNV_HASH32_INIT); + hash = fnv_hash32(line_bytes, size_of(caller.line), hash); + + use_shader(color_chooser_shader); + + set_bool(color_chooser_shader, "isSlider", true); + set_mat4f(color_chooser_shader, "projection", zephr_ctx.projection); + + rect: Rect = --- + + apply_constraints(constraints, &rect.pos, &rect.size); + apply_alignment(align, constraints, rect.size, &rect.pos); + + // set the positions after applying alignment so children can use them + constraints.x = rect.pos.x; + constraints.y = rect.pos.y; + + is_hovered := inside_rect(rect, zephr_ctx.mouse.pos); + left_mouse_pressed := zephr_ctx.mouse.pressed && zephr_ctx.mouse.button == .BUTTON_LEFT; + left_mouse_released := zephr_ctx.mouse.released && zephr_ctx.mouse.button == .BUTTON_LEFT; + + if (zephr_ctx.ui.active_element == 0) { + if (is_hovered && left_mouse_pressed) { + zephr_ctx.ui.active_element = hash; + dragging = true; + } + } else if (zephr_ctx.ui.active_element == hash) { + if (left_mouse_released) { + zephr_ctx.ui.active_element = 0; + dragging = false; + } + } + + if (dragging) { + slider_selection = clamp((zephr_ctx.mouse.pos.y - constraints.y) / constraints.height, 0, 1); + } + + model := identity(); + translate(&model, Vec3{rect.pos.x, rect.pos.y, 0}) + + set_mat4f(color_chooser_shader, "model", model); + + gl.BindVertexArray(ui_vao); + + vertices := [6][4]f32 { + // bottom left tri + {0, 0 + rect.size.y, 0.0, 1.0}, + {0, 0, 0.0, 0.0}, + {0 + rect.size.x, 0, 1.0, 0.0}, + + // top right tri + {0, 0 + rect.size.y, 0.0, 1.0}, + {0 + rect.size.x, 0, 1.0, 0.0}, + {0 + rect.size.x, 0 + rect.size.y, 1.0, 1.0}, + }; + + gl.BindBuffer(gl.ARRAY_BUFFER, ui_vbo); + gl.BufferSubData(gl.ARRAY_BUFFER, 0, size_of(vertices), raw_data(&vertices)) + gl.BindBuffer(gl.ARRAY_BUFFER, 0); + + gl.DrawArrays(gl.TRIANGLES, 0, 6); + + gl.BindVertexArray(0); + set_bool(color_chooser_shader, "isSlider", false); + + // draw the selection + triangle_con := DEFAULT_UI_CONSTRAINTS + set_parent_constraint(&triangle_con, constraints); + set_x_constraint(&triangle_con, -11, .RELATIVE_PIXELS); + set_y_constraint(&triangle_con, slider_selection, .RELATIVE); + set_rotation_constraint(&triangle_con, -90); + set_width_constraint(&triangle_con, 14, .RELATIVE_PIXELS); + set_height_constraint(&triangle_con, 0.5, .ASPECT_RATIO); + triangle_con.y += -(triangle_con.height / 2); + tri_style := UiStyle { + bg_color = COLOR_BLACK, + border_radius = 0, + align = .TOP_LEFT, + }; + draw_triangle(&triangle_con, tri_style); + + set_x_constraint(&triangle_con, 1, .RELATIVE); + triangle_con.x -= triangle_con.height / 2; + set_rotation_constraint(&triangle_con, 90); + draw_triangle(&triangle_con, tri_style); + + return slider_selection; +} + +@private +draw_color_picker_canvas :: proc(constraints: ^UiConstraints, slider_percentage: f32, align: Alignment, caller := #caller_location) -> Color { + @static + dragging := false; + @static + canvas_pos := Vec2{0, 0}; + + line := caller.line + line_bytes := mem.byte_slice(&line, size_of(line)) + hash := fnv_hash32(transmute([]byte)caller.file_path, cast(u32)len(caller.file_path), FNV_HASH32_INIT); + hash = fnv_hash32(line_bytes, size_of(caller.line), hash); + + use_shader(color_chooser_shader); + + set_bool(color_chooser_shader, "isSlider", false); + set_float(color_chooser_shader, "sliderPercentage", slider_percentage); + set_mat4f(color_chooser_shader, "projection", zephr_ctx.projection); + + rect: Rect = --- + + apply_constraints(constraints, &rect.pos, &rect.size); + apply_alignment(align, constraints, rect.size, &rect.pos); + + // set the positions after applying alignment so children can use them + constraints.x = rect.pos.x; + constraints.y = rect.pos.y; + + is_hovered := inside_rect(rect, zephr_ctx.mouse.pos); + left_mouse_pressed := zephr_ctx.mouse.pressed && zephr_ctx.mouse.button == .BUTTON_LEFT; + left_mouse_released := zephr_ctx.mouse.released && zephr_ctx.mouse.button == .BUTTON_LEFT; + + if (zephr_ctx.ui.active_element == 0) { + if (is_hovered && left_mouse_pressed) { + zephr_ctx.ui.active_element = hash; + dragging = true; + } + } else if (zephr_ctx.ui.active_element == hash) { + if (left_mouse_released) { + zephr_ctx.ui.active_element = 0; + dragging = false; + } + } + + if (dragging) { + x := (zephr_ctx.mouse.pos.x - constraints.x) / constraints.width; + y := (zephr_ctx.mouse.pos.y - constraints.y) / constraints.height; + + canvas_pos.x = clamp(x, 0, 1); + canvas_pos.y = clamp(y, 0, 1); + } + + model := identity(); + translate(&model, Vec3{rect.pos.x, rect.pos.y, 0}); + + set_mat4f(color_chooser_shader, "model", model); + + gl.BindVertexArray(ui_vao); + + vertices := [6][4]f32 { + // bottom left tri + {0, 0 + rect.size.y, 0.0, 1.0}, + {0, 0, 0.0, 0.0}, + {0 + rect.size.x, 0, 1.0, 0.0}, + + // top right tri + {0, 0 + rect.size.y, 0.0, 1.0}, + {0 + rect.size.x, 0, 1.0, 0.0}, + {0 + rect.size.x, 0 + rect.size.y, 1.0, 1.0}, + }; + + gl.BindBuffer(gl.ARRAY_BUFFER, ui_vbo); + gl.BufferSubData(gl.ARRAY_BUFFER, 0, size_of(vertices), raw_data(&vertices)) + gl.BindBuffer(gl.ARRAY_BUFFER, 0); + + gl.DrawArrays(gl.TRIANGLES, 0, 6); + + gl.BindVertexArray(0); + + selected_color := hsv2rgb(slider_percentage * 360, canvas_pos.x, 1.0 - canvas_pos.y); + + // draw the selection + triangle_con := DEFAULT_UI_CONSTRAINTS + set_parent_constraint(&triangle_con, constraints); + set_x_constraint(&triangle_con, canvas_pos.x, .RELATIVE); + set_y_constraint(&triangle_con, canvas_pos.y, .RELATIVE); + set_width_constraint(&triangle_con, 14, .RELATIVE_PIXELS); + set_height_constraint(&triangle_con, 0.5, .ASPECT_RATIO); + triangle_con.x -= triangle_con.height; + triangle_con.y -= triangle_con.height + triangle_con.height / 2 + triangle_con.width / 2; + set_rotation_constraint(&triangle_con, 0); + tri_style := UiStyle { + bg_color = determine_color_contrast(selected_color), + border_radius = 0, + align = .TOP_LEFT, + }; + draw_triangle(&triangle_con, tri_style); + + triangle_con.x += triangle_con.height * 2; + triangle_con.y += triangle_con.height * 2; + set_rotation_constraint(&triangle_con, 90); + draw_triangle(&triangle_con, tri_style); + + triangle_con.x -= triangle_con.height * 2; + triangle_con.y += triangle_con.height * 2; + set_rotation_constraint(&triangle_con, 180); + draw_triangle(&triangle_con, tri_style); + + triangle_con.x -= triangle_con.height * 2; + triangle_con.y -= triangle_con.height * 2; + set_rotation_constraint(&triangle_con, 270); + draw_triangle(&triangle_con, tri_style); + + return selected_color; +} + +// TODO: consume mouse events on the popup +@private +draw_color_picker_popup :: proc(picker_button_con: ^UiConstraints) { + popup_con := DEFAULT_UI_CONSTRAINTS + set_parent_constraint(&popup_con, picker_button_con); + set_x_constraint(&popup_con, 0, .FIXED); + set_y_constraint(&popup_con, 1.4, .RELATIVE); + set_width_constraint(&popup_con, 450, .RELATIVE_PIXELS); + set_height_constraint(&popup_con, 480, .RELATIVE_PIXELS); + popup_style := UiStyle { + bg_color = mult_color(COLOR_WHITE, 0.94), + border_radius = popup_con.width * 0.02, + align = .TOP_LEFT, + }; + draw_quad(&popup_con, popup_style); + + color_slider_con := DEFAULT_UI_CONSTRAINTS + set_parent_constraint(&color_slider_con, &popup_con); + set_x_constraint(&color_slider_con, -0.04, .RELATIVE); + set_y_constraint(&color_slider_con, 0.05, .RELATIVE); + set_height_constraint(&color_slider_con, 400 * 0.9, .RELATIVE_PIXELS); + set_width_constraint(&color_slider_con, 0.1, .ASPECT_RATIO); + slider_selection := draw_color_picker_slider(&color_slider_con, .TOP_RIGHT); + + set_x_constraint(&color_slider_con, 0.04, .RELATIVE); + set_y_constraint(&color_slider_con, 0.05, .RELATIVE); + set_width_constraint(&color_slider_con, popup_con.width * 0.8, .FIXED); + selected_color := draw_color_picker_canvas(&color_slider_con, slider_selection, .TOP_LEFT); + + button_con := DEFAULT_UI_CONSTRAINTS + set_parent_constraint(&button_con, &popup_con); + set_x_constraint(&button_con, 0.04, .RELATIVE); + set_y_constraint(&button_con, -0.05, .RELATIVE); + set_width_constraint(&button_con, 0.43, .RELATIVE); + set_height_constraint(&button_con, 0.3, .ASPECT_RATIO); + button_style := UiStyle { + bg_color = zephr_ctx.ui.popup_revert_color^, + fg_color = determine_color_contrast(zephr_ctx.ui.popup_revert_color^), + border_radius = 4, + align = .BOTTOM_LEFT, + } + if (draw_button(&button_con, "Revert", button_style, .ACTIVE)) { + zephr_ctx.ui.popup_open = false; + zephr_ctx.ui.popup_parent_hash = 0; + } + + button_style.align = .BOTTOM_RIGHT; + button_style.fg_color = determine_color_contrast(selected_color); + set_x_constraint(&button_con, -0.04, .RELATIVE); + set_y_constraint(&button_con, -0.05, .RELATIVE); + button_style.bg_color = selected_color; + if (draw_button(&button_con, "Apply", button_style, .ACTIVE)) { + zephr_ctx.ui.popup_revert_color^ = selected_color; + zephr_ctx.ui.popup_open = false; + zephr_ctx.ui.popup_parent_hash = 0; + } + + rect := Rect { + {popup_con.x, popup_con.y}, + {popup_con.width, popup_con.height}, + }; + + zephr_ctx.ui.popup_rect = rect; +} + +draw_color_picker :: proc(constraints: ^UiConstraints, color: ^Color, align: Alignment, state: ButtonState, id: u32 = 0, caller := #caller_location) { + line := caller.line + line_bytes := mem.byte_slice(&line, size_of(line)) + id := id + id_bytes := mem.byte_slice(&id, size_of(id)) + hash := fnv_hash32(id_bytes, size_of(id), FNV_HASH32_INIT); + hash = fnv_hash32(transmute([]byte)caller.file_path, cast(u32)len(caller.file_path), hash); + hash = fnv_hash32(line_bytes, size_of(line), hash); + + rect: Rect = --- + display_color := color^; + + con := constraints^; + + apply_constraints(&con, &rect.pos, &rect.size); + apply_alignment(align, &con, rect.size, &rect.pos); + + is_held := zephr_ctx.ui.active_element == hash + is_hovered := inside_rect(rect, zephr_ctx.mouse.pos); + left_mouse_pressed := zephr_ctx.mouse.pressed && zephr_ctx.mouse.button == .BUTTON_LEFT; + left_mouse_released := zephr_ctx.mouse.released && zephr_ctx.mouse.button == .BUTTON_LEFT; + clicked := false; + + if (zephr_ctx.ui.active_element == 0) { + if (is_hovered && left_mouse_pressed) { + zephr_ctx.ui.active_element = hash; + } + } else if (zephr_ctx.ui.active_element == hash) { + if (left_mouse_released) { + zephr_ctx.ui.active_element = 0; + + if (is_hovered) { + clicked = true; + } + } + } + + if (is_hovered && state == .ACTIVE) { + set_cursor(.HAND); + con.scale.y *= 1.08; + con.scale.x *= 1.08; + + if (is_held) { + display_color = mult_color(display_color, 0.8); + } else { + display_color = mult_color(display_color, 0.9); + } + } else if (state == .DISABLED) { + if (is_hovered) { + set_cursor(.DISABLED); + } + + display_color.a = 100; + } + + style := UiStyle { + bg_color = display_color, + border_radius = con.width * 0.08, + align = align, + }; + draw_quad(&con, style); + + if (clicked && state == .ACTIVE) { + zephr_ctx.ui.popup_open = true; + zephr_ctx.ui.popup_parent_constraints = con; + zephr_ctx.ui.popup_revert_color = color; + zephr_ctx.ui.popup_parent_hash = hash; + } + + if (zephr_ctx.ui.popup_parent_hash == hash) { + zephr_ctx.ui.popup_open = true; + zephr_ctx.ui.popup_parent_constraints = con; + } + + /* if (is_hovered && state == BUTTON_STATE_ACTIVE && zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) { */ + /* return true; */ + /* } */ + + /* return false; */ +} diff --git a/zephr/zephr.odin b/zephr/zephr.odin new file mode 100644 index 0000000..e4e3dac --- /dev/null +++ b/zephr/zephr.odin @@ -0,0 +1,1250 @@ +package zephr + +import "core:fmt" + +import x11 "vendor:x11/xlib" +import gl "vendor:OpenGL" +import "vendor:stb/image" + +import "../glx" +import "../xcursor" + +Cursor :: enum { + ARROW, + IBEAM, + CROSSHAIR, + HAND, + HRESIZE, + VRESIZE, + DISABLED, +} + +EventType :: enum { + UNKNOWN, + KEY_PRESSED, + KEY_RELEASED, + MOUSE_BUTTON_PRESSED, + MOUSE_BUTTON_RELEASED, + MOUSE_SCROLL, + MOUSE_MOVED, + WINDOW_RESIZED, + WINDOW_CLOSED, +} + +MouseButton :: enum { + BUTTON_LEFT, + BUTTON_RIGHT, + BUTTON_MIDDLE, + BUTTON_BACK, + BUTTON_FORWARD, + BUTTON_3, + BUTTON_4, + BUTTON_5, + BUTTON_6, + BUTTON_7, +} + +MouseScrollDirection :: enum { + UP, + DOWN, +} + +KeyMod :: bit_set[KeyModBits; u16] +KeyModBits :: enum { + NONE = 0, + + LEFT_SHIFT = 1, + RIGHT_SHIFT = 2, + SHIFT = 3, + + LEFT_CTRL = 4, + RIGHT_CTRL = 5, + CTRL = 6, + + LEFT_ALT = 7, + RIGHT_ALT = 8, + ALT = 9, + + LEFT_META = 10, + RIGHT_META = 11, + META = 12, + + CAPS_LOCK = 13, + NUM_LOCK = 14, +} + +Scancode :: enum { + NULL = 0, + + 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, + + KEY_1 = 30, + KEY_2 = 31, + KEY_3 = 32, + KEY_4 = 33, + KEY_5 = 34, + KEY_6 = 35, + KEY_7 = 36, + KEY_8 = 37, + KEY_9 = 38, + KEY_0 = 39, + + ENTER = 40, + ESCAPE = 41, + BACKSPACE = 42, + TAB = 43, + SPACE = 44, + + MINUS = 45, + EQUALS = 46, + LEFT_BRACKET = 47, + RIGHT_BRACKET = 48, + BACKSLASH = 49, + NON_US_HASH = 50, + SEMICOLON = 51, + APOSTROPHE = 52, + GRAVE = 53, + COMMA = 54, + PERIOD = 55, + SLASH = 56, + + CAPS_LOCK = 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, + + PRINT_SCREEN = 70, + SCROLL_LOCK = 71, + PAUSE = 72, + INSERT = 73, + HOME = 74, + PAGE_UP = 75, + DELETE = 76, + END = 77, + PAGE_DOWN = 78, + RIGHT = 79, + LEFT = 80, + DOWN = 81, + UP = 82, + + NUM_LOCK_OR_CLEAR = 83, + 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, + + NON_US_BACKSLASH = 100, + APPLICATION = 101, + 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, + UNDO = 122, + CUT = 123, + COPY = 124, + PASTE = 125, + FIND = 126, + MUTE = 127, + VOLUME_UP = 128, + VOLUME_DOWN = 129, + KP_COMMA = 133, + KP_EQUALSAS400 = 134, + + INTERNATIONAL1 = 135, + INTERNATIONAL2 = 136, + INTERNATIONAL3 = 137, + INTERNATIONAL4 = 138, + INTERNATIONAL5 = 139, + INTERNATIONAL6 = 140, + INTERNATIONAL7 = 141, + INTERNATIONAL8 = 142, + INTERNATIONAL9 = 143, + LANG1 = 144, + LANG2 = 145, + LANG3 = 146, + LANG4 = 147, + LANG5 = 148, + LANG6 = 149, + LANG7 = 150, + LANG8 = 151, + LANG9 = 152, + + ALT_ERASE = 153, + SYSREQ = 154, + CANCEL = 155, + CLEAR = 156, + PRIOR = 157, + ENTER_2 = 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_LEFT_PAREN = 182, + KP_RIGHT_PAREN = 183, + KP_LEFT_BRACE = 184, + KP_RIGHT_BRACE = 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_PLUS_MINUS = 215, + KP_CLEAR = 216, + KP_CLEARENTRY = 217, + KP_BINARY = 218, + KP_OCTAL = 219, + KP_DECIMAL = 220, + KP_HEXADECIMAL = 221, + + LEFT_CTRL = 224, + LEFT_SHIFT = 225, + LEFT_ALT = 226, + LEFT_META = 227, + RIGHT_CTRL = 228, + RIGHT_SHIFT = 229, + RIGHT_ALT = 230, + RIGHT_META = 231, + + /** Not a key. Marks the number of scancodes. */ + ZEPHR_KEYCODE_COUNT = 512, +} + +Event :: struct { + type: EventType, + + using _: struct #raw_union { + key: struct { + is_pressed: bool, + is_repeat: bool, + scancode: Scancode, + //code: Keycode, + mods: KeyMod, + }, + mouse: struct { + button: MouseButton, + using pos: Vec2, + scroll_direction: MouseScrollDirection, + }, + window: struct { + width: u32, + height: u32, + }, + } +} + +Mouse :: struct { + using pos: Vec2, + pressed: bool, + released: bool, + button: MouseButton, +} + +Window :: struct { + size: Vec2, + pre_fullscreen_size: Vec2, + is_fullscreen: bool, + non_resizable: bool, +} + +Keyboard :: struct { + mods: KeyMod, +} + +Context :: struct { + window_delete_atom: x11.Atom, + should_quit: bool, + screen_size: Vec2, + window: Window, + font: Font, + mouse: Mouse, + keyboard: Keyboard, + cursor: Cursor, + cursors: [Cursor]x11.Cursor, + ui: Ui, + + /* ZephrKeyboard keyboard; */ + /* XkbDescPtr xkb; */ + /* XIM xim; */ + /* CoreStack(ZephrEvent) event_queue; */ + /* u32 event_queue_cursor; */ + + projection: Mat4, +} + +@private +PropModeReplace :: 0 +@private +XA_ATOM :: x11.Atom(4) +@private +XA_STRING :: x11.Atom(31) +@private +XA_CARDINAL :: x11.Atom(6) +@private +FNV_HASH32_INIT :: 0x811c9dc5 +@private +FNV_HASH32_PRIME :: 0x01000193 + +COLOR_BLACK :: Color{0, 0, 0, 255} +COLOR_WHITE :: Color{255, 255, 255, 255} +COLOR_RED :: Color{255, 0, 0, 255} +COLOR_GREEN :: Color{0, 255, 0, 255} +COLOR_BLUE :: Color{0, 0, 255, 255} +COLOR_YELLOW :: Color{255, 255, 0, 255} +COLOR_MAGENTA :: Color{255, 0, 255, 255} +COLOR_CYAN :: Color{0, 255, 255, 255} +COLOR_ORANGE :: Color{255, 128, 0, 255} +COLOR_PURPLE :: Color{128, 0, 255, 255} + +evdev_scancode_to_zephr_scancode_map := []Scancode { + 0 = .NULL, + 1 = .ESCAPE, + 2 = .KEY_1, + 3 = .KEY_2, + 4 = .KEY_3, + 5 = .KEY_4, + 6 = .KEY_5, + 7 = .KEY_6, + 8 = .KEY_7, + 9 = .KEY_8, + 10 = .KEY_9, + 11 = .KEY_0, + 12 = .MINUS, + 13 = .EQUALS, + 14 = .BACKSPACE, + 15 = .TAB, + 16 = .Q, + 17 = .W, + 18 = .E, + 19 = .R, + 20 = .T, + 21 = .Y, + 22 = .U, + 23 = .I, + 24 = .O, + 25 = .P, + 26 = .LEFT_BRACKET, + 27 = .RIGHT_BRACKET, + 28 = .ENTER, + 29 = .LEFT_CTRL, + 30 = .A, + 31 = .S, + 32 = .D, + 33 = .F, + 34 = .G, + 35 = .H, + 36 = .J, + 37 = .K, + 38 = .L, + 39 = .SEMICOLON, + 40 = .APOSTROPHE, + 41 = .GRAVE, + 42 = .LEFT_SHIFT, + 43 = .BACKSLASH, + 44 = .Z, + 45 = .X, + 46 = .C, + 47 = .V, + 48 = .B, + 49 = .N, + 50 = .M, + 51 = .COMMA, + 52 = .PERIOD, + 53 = .SLASH, + 54 = .RIGHT_SHIFT, + 55 = .KP_MULTIPLY, + 56 = .LEFT_ALT, + 57 = .SPACE, + 58 = .CAPS_LOCK, + 59 = .F1, + 60 = .F2, + 61 = .F3, + 62 = .F4, + 63 = .F5, + 64 = .F6, + 65 = .F7, + 66 = .F8, + 67 = .F9, + 68 = .F10, + 69 = .NUM_LOCK_OR_CLEAR, + 70 = .SCROLL_LOCK, + 71 = .KP_7, + 72 = .KP_8, + 73 = .KP_9, + 74 = .KP_MINUS, + 75 = .KP_4, + 76 = .KP_5, + 77 = .KP_6, + 78 = .KP_PLUS, + 79 = .KP_1, + 80 = .KP_2, + 81 = .KP_3, + 82 = .KP_0, + 83 = .KP_PERIOD, + // 84 + 85 = .LANG5, // KEY_ZENKAKUHANKAKU + 86 = .NON_US_BACKSLASH, // KEY_102ND + 87 = .F11, + 88 = .F12, + 89 = .INTERNATIONAL1, // KEY_RO, + 90 = .LANG3, // KEY_KATAKANA + 91 = .LANG4, // KEY_HIRAGANA + 92 = .INTERNATIONAL4, // KEY_HENKAN + 93 = .INTERNATIONAL2, // KEY_KATAKANAHIRAGANA + 94 = .INTERNATIONAL5, // KEY_MUHENKAN + 95 = .INTERNATIONAL5, // KEY_KPJOCOMMA + 96 = .KP_ENTER, + 97 = .RIGHT_CTRL, + 98 = .KP_DIVIDE, + 99 = .SYSREQ, + 100 = .RIGHT_ALT, + 101 = .NULL, // KEY_LINEFEED + 102 = .HOME, + 103 = .UP, + 104 = .PAGE_UP, + 105 = .LEFT, + 106 = .RIGHT, + 107 = .END, + 108 = .DOWN, + 109 = .PAGE_DOWN, + 110 = .INSERT, + 111 = .DELETE, + 112 = .NULL, // KEY_MACRO + 113 = .MUTE, + 114 = .VOLUME_DOWN, + 115 = .VOLUME_UP, + 116 = .POWER, + 117 = .KP_EQUALS, + 118 = .KP_PLUS_MINUS, + 119 = .PAUSE, + // 120 + 121 = .KP_COMMA, + 122 = .LANG1, // KEY_HANGUEL + 123 = .LANG2, // KEY_HANJA + 124 = .INTERNATIONAL3, // KEY_YEN + 125 = .LEFT_META, + 126 = .RIGHT_META, + 127 = .APPLICATION, // KEY_COMPOSE + 128 = .STOP, + 129 = .AGAIN, + 130 = .NULL, // KEY_PROPS + 131 = .UNDO, + 132 = .NULL, // KEY_FRONT + 133 = .COPY, + 134 = .NULL, // KEY_OPEN + 135 = .PASTE, + 136 = .FIND, + 137 = .CUT, + 138 = .HELP, + 139 = .MENU, + 140 = .NULL, // CALCULATOR + 141 = .NULL, // KEY_SETUP + 142 = .NULL, // SLEEP + 143 = .NULL, // KEY_WAKEUP + 144 = .NULL, // KEY_FILE + 145 = .NULL, // KEY_SENDFILE + 146 = .NULL, // KEY_DELETEFILE + 147 = .NULL, // KEY_XFER + 148 = .NULL, // KEY_PROG1 + 149 = .NULL, // KEY_PROG2 + 150 = .NULL, // WWW + 151 = .NULL, // KEY_MSDOS + 152 = .NULL, // KEY_COFFEE + 153 = .NULL, // KEY_DIRECTION + 154 = .NULL, // KEY_CYCLEWINDOWS + 155 = .NULL, // MAIL + 156 = .NULL, // AC_BOOKMARKS + 157 = .NULL, // COMPUTER + 158 = .NULL, // AC_BACK + 159 = .NULL, // AC_FORWARD + 160 = .NULL, // KEY_CLOSECD + 161 = .NULL, // EJECT + 162 = .NULL, // KEY_EJECTCLOSECD + 163 = .NULL, // AUDIO_NEXT + 164 = .NULL, // AUDIO_PLAY + 165 = .NULL, // AUDIO_PREV + 166 = .NULL, // AUDIO_STOP + 167 = .NULL, // KEY_RECORD + 168 = .NULL, // AUDIO_REWIND + 169 = .NULL, // KEY_PHONE + 170 = .NULL, // KEY_ISO + 171 = .NULL, // KEY_CONFIG + 172 = .NULL, // AC_HOME + 173 = .NULL, // AC_REFRESH + 174 = .NULL, // KEY_EXIT + 175 = .NULL, // KEY_MOVE + 176 = .NULL, // KEY_EDIT + 177 = .NULL, // KEY_SCROLLUP + 178 = .NULL, // KEY_SCROLLDOWN + 179 = .KP_LEFT_PAREN, + 180 = .KP_RIGHT_PAREN, + 181 = .NULL, // KEY_NEW + 182 = .NULL, // KEY_REDO + 183 = .F13, + 184 = .F14, + 185 = .F15, + 186 = .F16, + 187 = .F17, + 188 = .F18, + 189 = .F19, + 190 = .F20, + 191 = .F21, + 192 = .F22, + 193 = .F23, + 194 = .F24, + // 195-199 + 200 = .NULL, // KEY_PLAYCD + 201 = .NULL, // KEY_PAUSECD + 202 = .NULL, // KEY_PROG3 + 203 = .NULL, // KEY_PROG4 + // 204 + 205 = .NULL, // KEY_SUSPEND + 206 = .NULL, // KEY_CLOSE + 207 = .NULL, // KEY_PLAY + 208 = .NULL, // AUDIO_FASTFORWARD + 209 = .NULL, // KEY_BASSBOOST + 210 = .NULL, // KEY_PRINT + 211 = .NULL, // KEY_HP + 212 = .NULL, // KEY_CAMERA + 213 = .NULL, // KEY_SOUND + 214 = .NULL, // KEY_QUESTION + 215 = .NULL, // KEY_EMAIL + 216 = .NULL, // KEY_CHAT + 217 = .NULL, // AC_SEARCH + 218 = .NULL, // KEY_CONNECT + 219 = .NULL, // KEY_FINANCE + 220 = .NULL, // KEY_SPORT + 221 = .NULL, // KEY_SHOP + 222 = .ALT_ERASE, + 223 = .CANCEL, + 224 = .NULL, // BRIGHTNESS_DOWN + 225 = .NULL, // BRIGHNESS_UP + 226 = .NULL, // KEY_MEDIA + 227 = .NULL, // DISPLAY_SWITCH + 228 = .NULL, // KBD_ILLUM_TOGGLE + 229 = .NULL, // KBD_ILLUM_DOWN + 230 = .NULL, // KBD_ILLUM_UP + 231 = .NULL, // KEY_SEND + 232 = .NULL, // KEY_REPLY + 233 = .NULL, // KEY_FORWARDEMAIL + 234 = .NULL, // KEY_SAVE + 235 = .NULL, // KEY_DOCUMENTS + 236 = .NULL, // KEY_BATTERY +} + +@private +x11_display : ^x11.Display +@private +x11_window : x11.Window +@private +x11_colormap : x11.Colormap +@private +glx_context : glx.Context +@private +zephr_ctx : Context + + +//////////////////////////// +// +// X11 +// +/////////////////////////// + + +@private +x11_go_fullscreen :: proc() { + // remove the resizing constraint before going fullscreen so WMs such as gnome + // can add the _NET_WM_ACTION_FULLSCREEN action to the _NET_WM_ALLOWED_ACTIONS atom + // and properly fullscreen the window + size_hints := x11.XAllocSizeHints(); + + zephr_ctx.window.pre_fullscreen_size.x = zephr_ctx.window.size.x; + zephr_ctx.window.pre_fullscreen_size.y = zephr_ctx.window.size.y; + if (size_hints != nil) { + size_hints.flags = {.PPosition, .PSize}; + size_hints.width = cast(i32)zephr_ctx.window.size.x; + size_hints.height = cast(i32)zephr_ctx.window.size.y; + x11.XSetWMNormalHints(x11_display, x11_window, size_hints); + x11.XFree(size_hints); + } + + xev: x11.XEvent; + wm_state := x11.XInternAtom(x11_display, "_NET_WM_STATE", false); + fullscreen := x11.XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", false); + xev.type = .ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; // _NET_WM_STATE_ADD + xev.xclient.data.l[1] = cast(int)fullscreen; + xev.xclient.data.l[2] = 0; + x11.XSendEvent(x11_display, x11.XDefaultRootWindow(x11_display), false, + {.SubstructureNotify, .SubstructureRedirect}, &xev); +} + +@private +x11_return_fullscreen :: proc() { + xev: x11.XEvent; + wm_state := x11.XInternAtom(x11_display, "_NET_WM_STATE", false); + fullscreen := x11.XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", false); + xev.type = .ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 0; // _NET_WM_STATE_REMOVE + xev.xclient.data.l[1] = cast(int)fullscreen; + xev.xclient.data.l[2] = 0; + x11.XSendEvent(x11_display, x11.XDefaultRootWindow(x11_display), false, + {.SubstructureNotify, .SubstructureRedirect}, &xev); + + // restore the resizing constraint as well as the pre-fullscreen window size + // when returning from fullscreen + size_hints := x11.XAllocSizeHints(); + + if (size_hints != nil) { + size_hints.flags = {.PPosition, .PSize}; + size_hints.width = cast(i32)zephr_ctx.window.pre_fullscreen_size.x; + size_hints.height = cast(i32)zephr_ctx.window.pre_fullscreen_size.y; + if (zephr_ctx.window.non_resizable) { + size_hints.flags |= {.PMinSize, .PMaxSize}; + size_hints.min_width = cast(i32)zephr_ctx.window.pre_fullscreen_size.x; + size_hints.min_height = cast(i32)zephr_ctx.window.pre_fullscreen_size.y; + size_hints.max_width = cast(i32)zephr_ctx.window.pre_fullscreen_size.x; + size_hints.max_height = cast(i32)zephr_ctx.window.pre_fullscreen_size.y; + } + x11.XSetWMNormalHints(x11_display, x11_window, size_hints); + x11.XFree(size_hints); + } +} + +@private +x11_toggle_fullscreen :: proc(fullscreen: bool) { + if fullscreen { + x11_return_fullscreen() + } else { + x11_go_fullscreen() + } +} + +// TODO: make sure this actually works ??? on gnome cuz I can't see it on dwm lol +// TODO: currently the icon shows on gnome's sidebar correctly but not in gnome-system-monitor. +// investigate. +@private +x11_assign_window_icon :: proc(icon_path: cstring) { + icon_width, icon_height: i32 + icon_data := image.load(icon_path, &icon_width, &icon_height, nil, 4); + defer image.image_free(icon_data) + assert(icon_data != nil, "Failed to load icon image") + + target_size := 2 + icon_width * icon_height; + + data := make([]u64, target_size * size_of(u64)) + + // first two elements are width and height + data[0] = cast(u64)icon_width; + data[1] = cast(u64)icon_height; + + for i in 0..<(icon_width*icon_height) { + data[i + 2] = cast(u64)((icon_data[i * 4] << 16) | (icon_data[i * 4 + 1] << 8) | (icon_data[i * 4 + 2] << 0) | (icon_data[i * 4 + 3] << 24)) + } + + net_wm_icon := x11.XInternAtom(x11_display, "_NET_WM_ICON", false); + + x11.XChangeProperty(x11_display, x11_window, net_wm_icon, XA_CARDINAL, 32, PropModeReplace, raw_data(data), target_size); +} + +@private +x11_get_screen_size :: proc() -> Vec2 { + screen := x11.XDefaultScreenOfDisplay(x11_display); + + return Vec2{cast(f32)screen.width, cast(f32)screen.height} +} + +@private +x11_resize_window :: proc() { + win_attrs : x11.XWindowAttributes + x11.XGetWindowAttributes(x11_display, x11_window, &win_attrs) + gl.Viewport(0, 0, win_attrs.width, win_attrs.height) +} + +@private +x11_create_window :: proc(window_title: cstring, window_size: Vec2, icon_path: cstring, window_non_resizable: bool) { + x11_display = x11.XOpenDisplay(nil) + + if x11_display == nil { + fmt.eprintf("Error: Can't open display\n") + return + } + + screen_num := x11.XDefaultScreen(x11_display) + root := x11.XRootWindow(x11_display, screen_num) + visual := x11.XDefaultVisual(x11_display, screen_num) + + x11_colormap = x11.XCreateColormap(x11_display, root, visual, x11.ColormapAlloc.AllocNone) + + attributes: x11.XSetWindowAttributes + attributes.event_mask = {.Exposure, .KeyPress, .KeyRelease, + .StructureNotify, .ButtonPress, .ButtonRelease, .PointerMotion} + attributes.colormap = x11_colormap + + screen := x11.XDefaultScreenOfDisplay(x11_display) + + window_start_x := screen.width / 2 - cast(i32)window_size.x / 2 + window_start_y := screen.height / 2 - cast(i32)window_size.y / 2 + + x11_window = x11.XCreateWindow(x11_display, root, window_start_x, window_start_y, cast(u32)window_size.x, cast(u32)window_size.y, 0, + x11.XDefaultDepth(x11_display), .InputOutput, visual, + {.CWColormap, .CWEventMask}, &attributes) + + if (icon_path != "") { + x11_assign_window_icon(icon_path); + } + + // Hints to the WM that the window is a normal window + // Of course this is only a hint and the WM can ignore it + net_wm_window_type := x11.XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE", false) + net_wm_window_type_normal := x11.XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE_NORMAL", false) + x11.XChangeProperty(x11_display, x11_window, net_wm_window_type, XA_ATOM, 32, PropModeReplace, &net_wm_window_type_normal, 1) + + wm_delete_window := x11.XInternAtom(x11_display, "WM_DELETE_WINDOW", false) + x11.XSetWMProtocols(x11_display, x11_window, &wm_delete_window, 1) + zephr_ctx.window_delete_atom = wm_delete_window; + + // set window name + { + UTF8_STRING := x11.XInternAtom(x11_display, "UTF8_STRING", false) + x11.XStoreName(x11_display, x11_window, window_title) + text_property: x11.XTextProperty + text_property.value = raw_data(string(window_title)) + text_property.format = 8 + text_property.encoding = UTF8_STRING + text_property.nitems = len(window_title) + x11.XSetWMName(x11_display, x11_window, &text_property) + net_wm_name := x11.XInternAtom(x11_display, "_NET_WM_NAME", false) + wm_class := x11.XInternAtom(x11_display, "WM_CLASS", false) + x11.XChangeProperty(x11_display, x11_window, net_wm_name, UTF8_STRING, 8, PropModeReplace, raw_data(string(window_title)), cast(i32)len(window_title)) + x11.XChangeProperty(x11_display, x11_window, wm_class, XA_STRING, 8, PropModeReplace, raw_data(string(window_title)), cast(i32)len(window_title)) + + class_hint := x11.XAllocClassHint() + + if (class_hint != nil) { + class_hint.res_name = window_title + class_hint.res_class = window_title + x11.XSetClassHint(x11_display, x11_window, class_hint) + x11.XFree(class_hint) + } + } + + size_hints := x11.XAllocSizeHints() + + if (size_hints != nil) { + size_hints.flags = {.PPosition, .PSize} + /* size_hints->win_gravity = StaticGravity; */ + size_hints.x = window_start_x + size_hints.y = window_start_y + size_hints.width = cast(i32)window_size.x + size_hints.height = cast(i32)window_size.y + if (window_non_resizable) { + size_hints.flags |= {.PMinSize, .PMaxSize}; + size_hints.min_width = cast(i32)window_size.x; + size_hints.min_height = cast(i32)window_size.y; + size_hints.max_width = cast(i32)window_size.x; + size_hints.max_height = cast(i32)window_size.y; + } + x11.XSetWMNormalHints(x11_display, x11_window, size_hints) + x11.XFree(size_hints) + } + + x11.XMapWindow(x11_display, x11_window) + + // nocheckin + gl.load_up_to(4, 6, proc(p: rawptr, name: cstring) { (cast(^rawptr)p)^ = glx.GetProcAddressARB(raw_data(string(name))) }) + + glx_major : i32 + glx_minor : i32 + glx.QueryVersion(x11_display, &glx_major, &glx_minor) + + fmt.printf("Loaded GLX %d.%d\n", glx_major, glx_minor) + + visual_attributes := []i32 { + glx.RENDER_TYPE, glx.RGBA_BIT, + glx.DEPTH_SIZE, 24, + glx.DOUBLEBUFFER, 1, + glx.SAMPLES, 4, // MSAA + x11.None, + } + + num_fbc: i32 + fbc := glx.ChooseFBConfig(x11_display, screen_num, raw_data(visual_attributes), &num_fbc) + + context_attributes := []i32 { + glx.CONTEXT_MAJOR_VERSION_ARB, 3, + glx.CONTEXT_MINOR_VERSION_ARB, 3, + glx.CONTEXT_PROFILE_MASK_ARB, glx.CONTEXT_CORE_PROFILE_BIT_ARB, + x11.None, + }; + + glx_context = glx.CreateContextAttribsARB(x11_display, fbc[0], nil, true, raw_data(context_attributes)); + + if glx_context == nil { + fmt.eprintf("Failed to create GLX context\n") + return + } + + glx.MakeCurrent(x11_display, x11_window, glx_context); + + // TODO: find a way to properly get the GL version + gl_major: i32 = --- + gl_minor: i32 = --- + gl.GetIntegerv(gl.MAJOR_VERSION, &gl_major) + gl.GetIntegerv(gl.MINOR_VERSION, &gl_major) + + fmt.printf("GL version: %d.%d\n", gl_major, gl_minor) + + glx.SwapIntervalEXT(x11_display, x11_window, 1); + // we enable blending for text + gl.Enable(gl.BLEND) + gl.Enable(gl.MULTISAMPLE) + gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) + x11_resize_window() + + x11.XFree(fbc) +} + +@private +x11_init :: proc(window_title: cstring, window_size: Vec2, icon_path: cstring, window_non_resizable: bool) { + x11_create_window(window_title, window_size, icon_path, window_non_resizable) +} + +@private +x11_close :: proc() { + glx.MakeCurrent(x11_display, 0, nil); + glx.DestroyContext(x11_display, glx_context); + + x11.XDestroyWindow(x11_display, x11_window); + x11.XFreeColormap(x11_display, x11_colormap); + x11.XCloseDisplay(x11_display); +} + + +//////////////////////////// +// +// Zephr +// +/////////////////////////// + + +init :: proc(font_path: cstring, icon_path: cstring, window_title: cstring, window_size: Vec2, window_non_resizable: bool) { + // TODO: should I initalize the audio here or let the game handle that?? + //int res = audio_init(); + //CORE_ASSERT(res == 0, "Failed to initialize audio"); + + x11_init(window_title, window_size, icon_path, window_non_resizable) + + ui_init(font_path) + + zephr_ctx.window.size = window_size + zephr_ctx.window.non_resizable = window_non_resizable + zephr_ctx.projection = orthographic_projection_2d(0, window_size.x, window_size.y, 0) + + zephr_ctx.cursors[.ARROW] = x11.XCreateFontCursor(x11_display, .XC_left_ptr); + zephr_ctx.cursors[.IBEAM] = x11.XCreateFontCursor(x11_display, .XC_xterm); + zephr_ctx.cursors[.CROSSHAIR] = x11.XCreateFontCursor(x11_display, .XC_crosshair); + zephr_ctx.cursors[.HAND] = x11.XCreateFontCursor(x11_display, .XC_hand1); + zephr_ctx.cursors[.HRESIZE] = x11.XCreateFontCursor(x11_display, .XC_sb_h_double_arrow); + zephr_ctx.cursors[.VRESIZE] = x11.XCreateFontCursor(x11_display, .XC_sb_v_double_arrow); + + // non-standard cursors + zephr_ctx.cursors[.DISABLED] = xcursor.LibraryLoadCursor(x11_display, "crossed_circle"); + + zephr_ctx.screen_size = x11_get_screen_size(); + start_internal_timer(); +} + +deinit :: proc() { + x11_close() + //audio_close() +} + +should_quit :: proc() -> bool { + gl.ClearColor(0, 0, 0, 1) + gl.Clear(gl.COLOR_BUFFER_BIT) + + zephr_ctx.cursor = .ARROW; + zephr_ctx.mouse.released = false; + zephr_ctx.mouse.pressed = false; + + //audio_update(); + + return zephr_ctx.should_quit; +} + +quit :: proc() { + zephr_ctx.should_quit = true; +} + +swap_buffers :: proc() { + if (zephr_ctx.ui.popup_open) { + draw_color_picker_popup(&zephr_ctx.ui.popup_parent_constraints); + } + zephr_ctx.ui.popup_open = false; + + glx.SwapBuffers(x11_display, x11_window) + x11.XDefineCursor(x11_display, x11_window, zephr_ctx.cursors[zephr_ctx.cursor]) +} + +iter_events :: proc(e_out: ^Event) -> bool { + xev: x11.XEvent + + for (cast(bool)x11.XPending(x11_display)) { + x11.XNextEvent(x11_display, &xev) + + if xev.type == .ConfigureNotify { + xce := xev.xconfigure + + if (xce.width != cast(i32)zephr_ctx.window.size.x || xce.height != cast(i32)zephr_ctx.window.size.y) { + zephr_ctx.window.size = Vec2{cast(f32)xce.width, cast(f32)xce.height} + zephr_ctx.projection = orthographic_projection_2d(0, zephr_ctx.window.size.x, zephr_ctx.window.size.y, 0) + x11_resize_window() + + e_out.type = .WINDOW_RESIZED + e_out.window.width = cast(u32)xce.width + e_out.window.height = cast(u32)xce.height + + return true + } + } else if xev.type == .DestroyNotify { + // window destroy event + e_out.type = .WINDOW_CLOSED; + + return true; + } else if xev.type == .ClientMessage { + // window close event + if (cast(x11.Atom)xev.xclient.data.l[0] == zephr_ctx.window_delete_atom) { + e_out.type = .WINDOW_CLOSED; + + return true; + } + } else if xev.type == .KeyPress { + xke := xev.xkey; + + evdev_keycode := xke.keycode - 8; + scancode := evdev_scancode_to_zephr_scancode_map[evdev_keycode]; + + e_out.type = .KEY_PRESSED; + e_out.key.scancode = scancode; + //e_out.key.code = keycode; + e_out.key.mods = x11_mods_to_zephr_mods(scancode, true); + + return true + } else if xev.type == .KeyRelease { + xke := xev.xkey; + + evdev_keycode := xke.keycode - 8; + scancode := evdev_scancode_to_zephr_scancode_map[evdev_keycode]; + + e_out.type = .KEY_RELEASED; + e_out.key.scancode = scancode + //e_out.key.code = keycode; + e_out.key.mods = x11_mods_to_zephr_mods(scancode, false); + + return true + } else if xev.type == .ButtonPress { + e_out.type = .MOUSE_BUTTON_PRESSED; + e_out.mouse.pos = Vec2{cast(f32)xev.xbutton.x, cast(f32)xev.xbutton.y}; + zephr_ctx.mouse.pressed = true; + + switch (xev.xbutton.button) { + case .Button1: + e_out.mouse.button = .BUTTON_LEFT; + zephr_ctx.mouse.button = .BUTTON_LEFT; + case .Button2: + e_out.mouse.button = .BUTTON_MIDDLE; + zephr_ctx.mouse.button = .BUTTON_MIDDLE; + case .Button3: + e_out.mouse.button = .BUTTON_RIGHT; + zephr_ctx.mouse.button = .BUTTON_RIGHT; + case .Button4: + e_out.type = .MOUSE_SCROLL; + e_out.mouse.scroll_direction = .UP; + case .Button5: + e_out.type = .MOUSE_SCROLL; + e_out.mouse.scroll_direction = .DOWN; + case cast(x11.MouseButton)8: // Back + e_out.mouse.button = .BUTTON_BACK; + zephr_ctx.mouse.button = .BUTTON_BACK; + case cast(x11.MouseButton)9: // Forward + e_out.mouse.button = .BUTTON_FORWARD; + zephr_ctx.mouse.button = .BUTTON_FORWARD; + case: + fmt.printf("[WARN] Unknown mouse button pressed: %d\n", xev.xbutton.button); + } + + return true + } else if xev.type == .ButtonRelease { + e_out.type = .MOUSE_BUTTON_RELEASED; + e_out.mouse.pos = Vec2{cast(f32)xev.xbutton.x, cast(f32)xev.xbutton.y}; + zephr_ctx.mouse.released = true; + zephr_ctx.mouse.pressed = false; + + switch (xev.xbutton.button) { + case .Button1: + e_out.mouse.button = .BUTTON_LEFT + case .Button2: + e_out.mouse.button = .BUTTON_MIDDLE + case .Button3: + e_out.mouse.button = .BUTTON_RIGHT + case .Button4: + e_out.type = .MOUSE_SCROLL; + e_out.mouse.scroll_direction = .UP; + case .Button5: + e_out.type = .MOUSE_SCROLL; + e_out.mouse.scroll_direction = .DOWN; + case cast(x11.MouseButton)8: // Back + e_out.mouse.button = .BUTTON_BACK; + zephr_ctx.mouse.button = .BUTTON_BACK; + case cast(x11.MouseButton)9: // Forward + e_out.mouse.button = .BUTTON_FORWARD; + zephr_ctx.mouse.button = .BUTTON_FORWARD; + } + + return true; + } else if xev.type == .MappingNotify { + // input device mapping changed + if (xev.xmapping.request != .MappingKeyboard) { + break; + } + x11.XRefreshKeyboardMapping(&xev.xmapping); + /* x11_keyboard_map_update(); */ + break; + } else if xev.type == .MotionNotify { + e_out.type = .MOUSE_MOVED; + e_out.mouse.pos = Vec2{cast(f32)xev.xmotion.x, cast(f32)xev.xmotion.y}; + zephr_ctx.mouse.pos = e_out.mouse.pos; + + return true; + } + } + + return false +} + +get_window_size :: proc() -> Vec2 { + return zephr_ctx.window.size; +} + +toggle_fullscreen :: proc() { + x11_toggle_fullscreen(zephr_ctx.window.is_fullscreen); + + zephr_ctx.window.is_fullscreen = !zephr_ctx.window.is_fullscreen; +} + +set_cursor :: proc(cursor: Cursor) { + zephr_ctx.cursor = cursor; +} + + +///////////////////////////// +// +// +// Utils +// +// +///////////////////////////// + + +@private +fnv_hash32 :: proc(data: []byte, size: u32, hash: u32) -> u32 { + hash := hash + + for i in 0.. KeyMod { + mods := zephr_ctx.keyboard.mods + + // TODO: figure out a better way of doing this + if (is_press) { + if (scancode == .LEFT_SHIFT) { + mods |= {.LEFT_SHIFT, .SHIFT}; + } + if (scancode == .RIGHT_SHIFT) { + mods |= {.RIGHT_SHIFT, .SHIFT}; + } + if (scancode == .LEFT_CTRL) { + mods |= {.LEFT_CTRL, .CTRL}; + } + if (scancode == .RIGHT_CTRL) { + mods |= {.RIGHT_CTRL, .CTRL}; + } + if (scancode == .LEFT_ALT) { + mods |= {.LEFT_ALT, .ALT}; + } + if (scancode == .RIGHT_ALT) { + mods |= {.RIGHT_ALT, .ALT}; + } + if (scancode == .LEFT_META) { + mods |= {.LEFT_META, .META}; + } + if (scancode == .RIGHT_META) { + mods |= {.RIGHT_META, .META}; + } + if (scancode == .CAPS_LOCK) { + mods |= {.CAPS_LOCK}; + } + if (scancode == .NUM_LOCK_OR_CLEAR) { + mods |= {.NUM_LOCK}; + } + } else { + if (scancode == .LEFT_SHIFT) { + mods &= ~{.LEFT_SHIFT}; + } + if (scancode == .RIGHT_SHIFT) { + mods &= ~{.RIGHT_SHIFT}; + } + if (!(.RIGHT_SHIFT in mods) && !(.LEFT_SHIFT in mods)) { + mods &= ~{.SHIFT}; + } + + if (scancode == .LEFT_CTRL) { + mods &= ~{.LEFT_CTRL}; + } + if (scancode == .RIGHT_CTRL) { + mods &= ~{.RIGHT_CTRL}; + } + if (!(.RIGHT_CTRL in mods) && !(.LEFT_CTRL in mods)) { + mods &= ~{.CTRL}; + } + + if (scancode == .LEFT_ALT) { + mods &= ~{.LEFT_ALT}; + } + if (scancode == .RIGHT_ALT) { + mods &= ~{.RIGHT_ALT}; + } + if (!(.RIGHT_ALT in mods) && !(.LEFT_ALT in mods)) { + mods &= ~{.ALT}; + } + + if (scancode == .LEFT_META) { + mods &= ~{.LEFT_META}; + } + if (scancode == .RIGHT_META) { + mods &= ~{.RIGHT_META}; + } + if (!(.RIGHT_META in mods) && !(.LEFT_META in mods)) { + mods &= ~{.META}; + } + + if (scancode == .CAPS_LOCK) { + mods &= ~{.CAPS_LOCK}; + } + if (scancode == .NUM_LOCK_OR_CLEAR) { + mods &= ~{.NUM_LOCK}; + } + } + + zephr_ctx.keyboard.mods = mods + return mods; +} diff --git a/zephr/zephr_math.odin b/zephr/zephr_math.odin new file mode 100644 index 0000000..93d1a92 --- /dev/null +++ b/zephr/zephr_math.odin @@ -0,0 +1,147 @@ +package zephr + +import "core:math" + +Vec2 :: [2]f32 +Vec3 :: [3]f32 +Vec4 :: [4]f32 + +Mat3 :: matrix[3, 3]f32 +Mat4 :: matrix[4, 4]f32 + +Color :: struct { r, g, b, a: u8 } + +orthographic_projection_2d :: proc(left, right, bottom, top: f32) -> Mat4 { + result := identity(); + + result[0][0] = 2 / (right - left); + result[3][0] = -(right + left) / (right - left); + result[1][1] = 2 / (top - bottom); + result[3][1] = -(top + bottom) / (top - bottom); + result[2][2] = -1; + result[3][3] = 1; + + return result; +} + +identity :: proc() -> Mat4 { + return Mat4 { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + } +} + +translate :: proc(m: ^Mat4, v: Vec3) { + temp := identity() + + temp[3][0] = v.x + temp[3][1] = v.y + temp[3][2] = v.z + + m^ = temp * m^ +} + +rotate :: proc(m: ^Mat4, angle: f32, axis: Vec3) { + temp := identity() + + c := math.cos(math.to_radians(angle)) + s := math.sin(math.to_radians(angle)) + t := 1 - c + + x, y, z := axis.x, axis.y, axis.z + + res := Mat4{ + t*x*x + c, t*x*y - s*z, t*x*z + s*y, 0, + t*x*y + s*z, t*y*y + c, t*y*z - s*x, 0, + t*x*z - s*y, t*y*z + s*x, t*z*z + c, 0, + 0 , 0, 0, 1, + } + + m^ = res * m^ +} + +scale :: proc(m: ^Mat4, v: Vec3) { + temp := identity() + + temp[0][0] = v.x + temp[1][1] = v.y + temp[2][2] = v.z + + m^ = temp * m^ +} + +mult_color :: proc(color: Color, scalar: f32) -> Color { + color := color + + color.r = clamp(cast(u8)(cast(f32)color.r * scalar), 0, 255) + color.g = clamp(cast(u8)(cast(f32)color.g * scalar), 0, 255) + color.b = clamp(cast(u8)(cast(f32)color.b * scalar), 0, 255) + + return color +} + +hsv2rgb :: proc(h: f32, s: f32, v: f32) -> Color { + c := v * s; + x := (c * (1 - abs(math.mod(h / 60.0, 2) - 1))); + m := v - c; + + r, g, b: f32 + + if (h >= 0 && h < 60) { + r = c + g = x + b = 0 + } else if (h >= 60 && h < 120) { + r = x + g = c + b = 0 + } else if (h >= 120 && h < 180) { + r = 0 + g = c + b = x + } else if (h >= 180 && h < 240) { + r = 0 + g = x + b = c + } else if (h >= 240 && h < 300) { + r = x + g = 0 + b = c + } else { + r = c + g = 0 + b = x; + } + + return (Color){(u8)((r + m) * 255), (u8)((g + m) * 255), (u8)((b + m) * 255), 255}; +} + +determine_color_contrast :: proc(bg: Color) -> Color { + white_contrast := get_contrast(bg, COLOR_WHITE); + black_contrast := get_contrast(bg, COLOR_BLACK); + + return white_contrast > black_contrast ? COLOR_WHITE : COLOR_BLACK; +} + +@private +get_srgb :: proc(component: f32) -> f32 { + return (component / 255 <= 0.03928 + ? component / 255 / 12.92 + : math.pow((component / 255 + 0.055) / 1.055, 2.4)); +} + +get_luminance :: proc(color: Color) -> f32 { + return ((0.2126 * get_srgb(cast(f32)color.r)) + + (0.7152 * get_srgb(cast(f32)color.g)) + + (0.0722 * get_srgb(cast(f32)color.b))) / 255; +} + +@private +get_contrast :: proc(fg: Color, bg: Color) -> f32 { + l1 := get_luminance(fg) + l2 := get_luminance(bg) + + return (max(l1, l2) + 0.05) / (min(l1, l2) + 0.05); +}