From 0bd7c5dc0725a4882cb33c5d8f1a3b101d4025cd Mon Sep 17 00:00:00 2001 From: pryazha Date: Thu, 20 Feb 2025 15:08:47 +0500 Subject: initial --- example/UTF-8-demo.html | 213 +++++++++++++++++++++++++++ example/build.sh | 7 + example/example | Bin 0 -> 65664 bytes example/example.c | 260 ++++++++++++++++++++++++++++++++ prb.h | 26 ++++ prb_macros.h | 61 ++++++++ prb_math.c | 385 ++++++++++++++++++++++++++++++++++++++++++++++++ prb_math.h | 64 ++++++++ prb_memory.c | 42 ++++++ prb_memory.h | 11 ++ prb_os_io.c | 31 ++++ prb_os_io.h | 6 + prb_string.c | 115 +++++++++++++++ prb_string.h | 22 +++ prb_types.h | 84 +++++++++++ 15 files changed, 1327 insertions(+) create mode 100644 example/UTF-8-demo.html create mode 100755 example/build.sh create mode 100755 example/example create mode 100644 example/example.c create mode 100644 prb.h create mode 100644 prb_macros.h create mode 100644 prb_math.c create mode 100644 prb_math.h create mode 100644 prb_memory.c create mode 100644 prb_memory.h create mode 100644 prb_os_io.c create mode 100644 prb_os_io.h create mode 100644 prb_string.c create mode 100644 prb_string.h create mode 100644 prb_types.h diff --git a/example/UTF-8-demo.html b/example/UTF-8-demo.html new file mode 100644 index 0000000..b8157db --- /dev/null +++ b/example/UTF-8-demo.html @@ -0,0 +1,213 @@ + + + UTF-8 test file + +

Original by Markus Kuhn, adapted for HTML by Martin Dürst.

+
+UTF-8 encoded sample plain-text file
+‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+
+Markus Kuhn [ˈmaʳkʊs kuːn] <mkuhn@acm.org> — 1999-08-20
+
+
+The ASCII compatible UTF-8 encoding of ISO 10646 and Unicode
+plain-text files is defined in RFC 2279 and in ISO 10646-1 Annex R.
+
+
+Using Unicode/UTF-8, you can write in emails and source code things such as
+
+Mathematics and Sciences:
+
+  ∮ E⋅da = Q,  n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β),
+
+  ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (A ⇔ B),
+
+  2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm
+
+Linguistics and dictionaries:
+
+  ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
+  Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
+
+APL:
+
+  ((V⍳V)=⍳⍴V)/V←,V    ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
+
+Nicer typography in plain text files:
+
+  ╔══════════════════════════════════════════╗
+  ║                                          ║
+  ║   • ‘single’ and “double” quotes         ║
+  ║                                          ║
+  ║   • Curly apostrophes: “We’ve been here” ║
+  ║                                          ║
+  ║   • Latin-1 apostrophe and accents: '´`  ║
+  ║                                          ║
+  ║   • ‚deutsche‘ „Anführungszeichen“       ║
+  ║                                          ║
+  ║   • †, ‡, ‰, •, 3–4, —, −5/+5, ™, …      ║
+  ║                                          ║
+  ║   • ASCII safety test: 1lI|, 0OD, 8B     ║
+  ║                      ╭─────────╮         ║
+  ║   • the euro symbol: │ 14.95 € │         ║
+  ║                      ╰─────────╯         ║
+  ╚══════════════════════════════════════════╝
+
+Greek (in Polytonic):
+
+  The Greek anthem:
+
+  Σὲ γνωρίζω ἀπὸ τὴν κόψη
+  τοῦ σπαθιοῦ τὴν τρομερή,
+  σὲ γνωρίζω ἀπὸ τὴν ὄψη
+  ποὺ μὲ βία μετράει τὴ γῆ.
+
+  ᾿Απ᾿ τὰ κόκκαλα βγαλμένη
+  τῶν ῾Ελλήνων τὰ ἱερά
+  καὶ σὰν πρῶτα ἀνδρειωμένη
+  χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
+
+  From a speech of Demosthenes in the 4th century BC:
+
+  Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
+  ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
+  λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
+  τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿ 
+  εἰς τοῦτο προήκοντα,  ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
+  πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
+  οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
+  οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
+  ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
+  τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
+  γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
+  προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
+  σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
+  τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
+  τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
+  τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
+
+  Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
+
+Georgian:
+
+  From a Unicode conference invitation:
+
+  გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
+  კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
+  ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
+  ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
+  ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
+  ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
+  ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
+
+Russian:
+
+  From a Unicode conference invitation:
+
+  Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
+  Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
+  Конференция соберет широкий круг экспертов по  вопросам глобального
+  Интернета и Unicode, локализации и интернационализации, воплощению и
+  применению Unicode в различных операционных системах и программных
+  приложениях, шрифтах, верстке и многоязычных компьютерных системах.
+
+Thai (UCS Level 2):
+
+  Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
+  classic 'San Gua'):
+
+  [----------------------------|------------------------]
+    ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช  พระปกเกศกองบู๊กู้ขึ้นใหม่
+  สิบสองกษัตริย์ก่อนหน้าแลถัดไป       สององค์ไซร้โง่เขลาเบาปัญญา
+    ทรงนับถือขันทีเป็นที่พึ่ง           บ้านเมืองจึงวิปริตเป็นนักหนา
+  โฮจิ๋นเรียกทัพทั่วหัวเมืองมา         หมายจะฆ่ามดชั่วตัวสำคัญ
+    เหมือนขับไสไล่เสือจากเคหา      รับหมาป่าเข้ามาเลยอาสัญ
+  ฝ่ายอ้องอุ้นยุแยกให้แตกกัน          ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
+    พลันลิฉุยกุยกีกลับก่อเหตุ          ช่างอาเพศจริงหนาฟ้าร้องไห้
+  ต้องรบราฆ่าฟันจนบรรลัย           ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
+
+  (The above is a two-column text. If combining characters are handled
+  correctly, the lines of the second column should be aligned with the
+  | character above.)
+
+Ethiopian:
+
+  Proverbs in the Amharic language:
+
+  ሰማይ አይታረስ ንጉሥ አይከሰስ።
+  ብላ ካለኝ እንደአባቴ በቆመጠኝ።
+  ጌጥ ያለቤቱ ቁምጥና ነው።
+  ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
+  የአፍ ወለምታ በቅቤ አይታሽም።
+  አይጥ በበላ ዳዋ ተመታ።
+  ሲተረጉሙ ይደረግሙ።
+  ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
+  ድር ቢያብር አንበሳ ያስር።
+  ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
+  እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
+  የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
+  ሥራ ከመፍታት ልጄን ላፋታት።
+  ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
+  የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
+  ተንጋሎ ቢተፉ ተመልሶ ባፉ።
+  ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
+  እግርህን በፍራሽህ ልክ ዘርጋ።
+
+Runes:
+
+  ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
+
+  (Old English, which transcribed into Latin reads 'He cwaeth that he
+  bude thaem lande northweardum with tha Westsae.' and means 'He said
+  that he lived in the northern land near the Western Sea.')
+
+Braille:
+
+  ⡌⠁⠧⠑ ⠼⠁⠒  ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
+
+  ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
+  ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
+  ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
+  ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
+  ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑ 
+  ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
+
+  ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
+
+  ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
+  ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
+  ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
+  ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹ 
+  ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎ 
+  ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
+  ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
+  ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
+  ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
+
+  (The first couple of paragraphs of "A Christmas Carol" by Dickens)
+
+Compact font selection example text:
+
+  ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
+  abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
+  –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
+  ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა
+
+Greetings in various languages:
+
+  Hello world, Καλημέρα κόσμε, コンニチハ
+
+Box drawing alignment tests:                                          █
+                                                                      ▉
+  ╔══╦══╗  ┌──┬──┐  ╭──┬──╮  ╭──┬──╮  ┏━━┳━━┓  ┎┒┏┑   ╷  ╻ ┏┯┓ ┌┰┐    ▊ ╱╲╱╲╳╳╳
+  ║┌─╨─┐║  │╔═╧═╗│  │╒═╪═╕│  │╓─╁─╖│  ┃┌─╂─┐┃  ┗╃╄┙  ╶┼╴╺╋╸┠┼┨ ┝╋┥    ▋ ╲╱╲╱╳╳╳
+  ║│╲ ╱│║  │║   ║│  ││ │ ││  │║ ┃ ║│  ┃│ ╿ │┃  ┍╅╆┓   ╵  ╹ ┗┷┛ └┸┘    ▌ ╱╲╱╲╳╳╳
+  ╠╡ ╳ ╞╣  ├╢   ╟┤  ├┼─┼─┼┤  ├╫─╂─╫┤  ┣┿╾┼╼┿┫  ┕┛┖┚     ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
+  ║│╱ ╲│║  │║   ║│  ││ │ ││  │║ ┃ ║│  ┃│ ╽ │┃  ░░▒▒▓▓██ ┊  ┆ ╎ ╏  ┇ ┋ ▎
+  ║└─╥─┘║  │╚═╤═╝│  │╘═╪═╛│  │╙─╀─╜│  ┃└─╂─┘┃  ░░▒▒▓▓██ ┊  ┆ ╎ ╏  ┇ ┋ ▏
+  ╚══╩══╝  └──┴──┘  ╰──┴──╯  ╰──┴──╯  ┗━━┻━━┛           └╌╌┘ ╎ ┗╍╍┛ ┋  ▁▂▃▄▅▆▇█
+
+
+ + diff --git a/example/build.sh b/example/build.sh new file mode 100755 index 0000000..172aa69 --- /dev/null +++ b/example/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh +CFLAGS='-g -Wall' +INCLUDE='-I..' +LIBS='-lm' +set -x +#tcc $CFLAGS $INCLUDE $LIBS -o example example.c && ./example +gcc $CFLAGS $INCLUDE $LIBS -o example example.c && ./example diff --git a/example/example b/example/example new file mode 100755 index 0000000..15b5b35 Binary files /dev/null and b/example/example differ diff --git a/example/example.c b/example/example.c new file mode 100644 index 0000000..1fa85b3 --- /dev/null +++ b/example/example.c @@ -0,0 +1,260 @@ +#include "prb.h" + +typedef struct { + S32 first; + S32 second; + B32 flags; +} SomeStruct; + +typedef struct SLLNode { + S32 val; + struct SLLNode *next; +} SLLNode; + +typedef struct DLLNode { + S32 val; + struct DLLNode *next; + struct DLLNode *prev; +} DLLNode; + +int main(void) +{ + F32 verts[] = { + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f + }; + + Assert(v3a(1.0f).y); + U64 memory_size = Kilobytes(4); + void *some_memory = malloc(memory_size); + *(S32 *)some_memory = 69; + U64 ptr_as_int = IntFromPtr(some_memory); + void *ptr_to_memory = PtrFromInt(ptr_as_int); + printf("IntFromPtr: %lu\n", ptr_as_int); + printf("Using PtrFromInt(%lu) to get the first element of some_memory: %d\n\n", + ptr_as_int, *(S32 *)ptr_to_memory); + free(some_memory); + + printf("OffsetOfMember(SomeStruct, flags): %lld\n\n", + OffsetOfMember(SomeStruct, flags)); + + F32 range_min = 0.0f, range_max = 1.0f; + F32 clamped_number = 1.5f; + F32 another_clamped_number = -0.2f; + printf("ClampBottom(%f, %f): %f\n", range_min, + another_clamped_number, ClampBottom(another_clamped_number, range_min)); + printf("ClampTop(%f, %f): %f\n", range_max, + clamped_number, ClampTop(clamped_number, range_max)); + + printf("Clamp(%f, %f, %f): %f\n", range_min, clamped_number, range_max, + Clamp(range_min, clamped_number, range_max)); + printf("Clamp(%f, %f, %f): %f\n\n", range_min, another_clamped_number, range_max, + Clamp(range_min, another_clamped_number, range_max)); + + F32 swap_test_first = 10.0f, swap_test_second = 20.0f; + printf("Before Swap: swap_test_first = %f, swap_test_second = %f\n", + swap_test_first, swap_test_second); + Swap(F32, swap_test_first, swap_test_second); + printf("After Swap: swap_test_first = %f, swap_test_second = %f\n\n", + swap_test_first, swap_test_second); + + SomeStruct some_stuct = { 10, 20, 30 }; + printf("SomeStruct: first: %d, second: %d, flags: %d\n", + some_stuct.first, some_stuct.second, some_stuct.flags); + MemoryZero(&some_stuct, sizeof(SomeStruct)); + printf("After MemoryZero(&some_stuct, sizeof(SomeStruct)):\n"); + printf("some_stuct: first: %d, second: %d, flags: %d\n\n", + some_stuct.first, some_stuct.second, some_stuct.flags); + + some_stuct = (SomeStruct){ 10, 20, 30 }; + printf("some_stuct: first: %d, second: %d, flags: %d\n", + some_stuct.first, some_stuct.second, some_stuct.flags); + MemoryZeroStruct(&some_stuct); + printf("After MemoryZeroStruct(&some_stuct):\n"); + printf("some_stuct: first: %d, second: %d, flags: %d\n\n", + some_stuct.first, some_stuct.second, some_stuct.flags); + + printf("Before MemoryZeroArray:\n"); + for (S32 i = 0; i < ArrayCount(verts); ++i) + printf("%f%c", verts[i], (((i+1)%4 == 0) || + (i == ArrayCount(verts)-1)) ? '\n' : ' '); + MemoryZeroArray(verts); + printf("After:\n"); + for (S32 i = 0; i < ArrayCount(verts); ++i) + printf("%f%c", verts[i], (((i+1)%4 == 0) || + (i == ArrayCount(verts)-1)) ? '\n' : ' '); + printf("\n"); + + S32 dynamic_array_length = 10; + U64 dynamic_array_size = dynamic_array_length*sizeof(S32); + F32 *dynamic_array_first = malloc(dynamic_array_size); + F32 *dynamic_array_second = malloc(dynamic_array_size); + printf("first dynamic array:\n"); + for (S32 i = 0; i < dynamic_array_length; ++i) { + F32 *element = dynamic_array_first+i; + *element = i+420; + printf("%f%c", *element, (i == dynamic_array_length-1) ? '\n' : ' '); + } + printf("second dynamic array:\n"); + for (S32 i = 0; i < dynamic_array_length; ++i) { + F32 *element = dynamic_array_second+i; + printf("%f%c", *element, (i == dynamic_array_length-1) ? '\n' : ' '); + } + MemoryCopy(dynamic_array_second, dynamic_array_first, dynamic_array_size); + printf("After MemoryCopy(dynamic_array_second, dynamic_array_first, dynamic_array_size):\n"); + printf("second dynamic array:\n"); + for (S32 i = 0; i < dynamic_array_length; ++i) { + F32 *element = dynamic_array_second+i; + printf("%f%c", *element, (i == dynamic_array_length-1) ? '\n' : ' '); + } + S32 memory_match = MemoryMatch(dynamic_array_first, dynamic_array_second, dynamic_array_size); + printf("And MemoryMatch(MemoryMatch(dynamic_array_first, dynamic_array_second, dynamic_array_size): %d\n\n", memory_match); + free(dynamic_array_first); + free(dynamic_array_second); + + printf("Linked Lists:\n"); + printf("Singly linked list: "); + S32 list_length = 5; + U64 list_size = list_length*sizeof(SLLNode); + SLLNode *sllist = malloc(list_size); + SLLNode *sllfirst = 0; + SLLNode *slllast = 0; + for (S32 i = 0; i < list_length; ++i) { + SLLNode *new = sllist+i; + new->val = i; + SLLPush(sllfirst, slllast, new); + } + for (SLLNode *node = sllfirst; node; node = node->next) + printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); + SLLPop(sllfirst, slllast); + printf("After SLLPop(sllfirst, slllast): "); + for (SLLNode *node = sllfirst; node; node = node->next) + printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); + free(sllist); + + printf("Doubly linked list: "); + list_length = 8; + list_size = list_length*sizeof(DLLNode); + DLLNode *dllist = malloc(list_size); + DLLNode *dllfirst = 0; + DLLNode *dlllast = 0; + for (S32 i = 0; i < list_length; ++i) { + DLLNode *new = dllist+i; + new->val = i; + DLLPushBack(dllfirst, dlllast, new); + } + for (DLLNode *node = dllfirst; node; node = node->next) + printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); + printf("Remove odd numbers: "); + for (DLLNode *node = dllfirst; node; node = node->next) + if (node->val % 2 == 1) + DLLRemove(dllfirst, dlllast, node); + for (DLLNode *node = dllfirst; node; node = node->next) + printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); + free(dllist); + printf("\n"); + + printf("I'm pretty sure the vectors are fine.\nAt least for the last few months :)\n\n"); + + printf("Matrices:\n"); + printf("Identity:\n"); + Mat4 m = MAT4_IDENTITY; + mat4print(m); + m = mat4scale(m, v3a(10.0f)); + m = mat4translate(m, v3a(1.0f)); + m = mat4translate(m, v3(0.0f, 68.0f, 0.0f)); + mat4print(m); + printf("Determinant: %f\n", mat4det(m)); + printf("Transpose:\n"); mat4print(mat4transpose(m)); + printf("mat4rotate(MAT4_IDENTITY, v3(0.0f, 45.0f, 0.0f)):\n"); + mat4print(mat4rotate(MAT4_IDENTITY, v3(0.0f, 45.0f, 0.0f))); + + printf("Using Arenas:\n"); + Arena *a = arena_alloc(0); + SLLNode *first = 0; + SLLNode *last = 0; + S32 node_count = 10; + for (S32 i = 0; i < node_count; ++i) { + SLLNode *new = arena_push(a, sizeof(SLLNode)); + new->val = i; + SLLPush(first, last, new); + } + for (SLLNode *node = first; node; node = node->next) + printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); + arena_release(a); + + a = arena_alloc(sizeof(verts)); + S32 verts_count = ArrayCount(verts); + F32 *dynamic_verts = arena_push(a, sizeof(verts)); + MemoryZero(dynamic_verts, verts_count*sizeof(F32)); + for (S32 i = 0; i < verts_count; ++i) { + F32 *vert = dynamic_verts+i; + printf("%f%c", *vert, (i == verts_count-1) ? '\n' : ' '); + } + arena_release(a); + printf("\n"); + + Arena *str_arena = arena_alloc(0); + printf("Strings:\n"); + char *cstr = "This is a C str\n"; + Str8 str = str8_from_cstr(cstr); + str = str8_chop_start(str, 10); + cstr = str8_to_cstr(a, str); + printf("%s", cstr); + str8print(str); + Str8 choped_str = str8_chop_end(str, 3); + str8print(choped_str); + printf("\n"); + Str8List *list = str8_list(str_arena); + str8_list_push(str_arena, list, str, 0); + str8_list_push(str_arena, list, str8_from_cstr("test"), 0); + str8_list_push(str_arena, list, str8_from_cstr("and this is also a test\n"), 0); + str8_list_push(str_arena, list, str8_from_cstr("Kinda works!"), 1); + printf("Str8List: "); + str8_list_print(list); + arena_release(str_arena); + str8_list_print(list); + + str_arena = arena_alloc(Kilobytes(10)); + memory_size = 512; + U32 count = memory_size/sizeof(S32); + S32 *some = arena_push(str_arena, memory_size); + printf("str_arena(size): %ld\nMemory:\n", str_arena->cap); + for (S32 i = 0; i < count; i++) { + S32 *e = some+i; + *e = 69; + printf("%d: %d%c", i, *e, ((i == count-1) ? '\n' : ' ')); + } + printf("Memory used: %lu\n", str_arena->used); + printf("Remaining memory: %lu\n", + str_arena->cap-str_arena->used); + + arena_pop(str_arena, memory_size); + + printf("After arena pop\n"); + printf("Memory used: %lu\n", str_arena->used); + printf("Remaining memory: %lu\n", + str_arena->cap-str_arena->used); + printf("some ptr is %s\n", some ? "not null" : "null"); + printf("str_arena(size): %lu\nMemory:\n", str_arena->cap); + + Str8 new_str = str8_pushf(str_arena, "Test of the formatted string: %d\n", 69); + str8print(new_str); + + list = str8_list(str_arena); + str8_list_pushf(str_arena, list, 0, "This is a list %d", 34); + str8_list_pushf(str_arena, list, 0, " of formatted strings: %d", 35); + str8_list_pushf(str_arena, list, 1, "And you can push to the start"); + str8_list_print(list); + + arena_release(str_arena); + + a = arena_alloc(Megabytes(1)); + str8print(str8lit("build.sh content:\n")); + Str8 file_content = str8_read_entire_file(a, str8lit("build.sh")); + str8print(file_content); + arena_release(a); + + return(0); +} diff --git a/prb.h b/prb.h new file mode 100644 index 0000000..65f3244 --- /dev/null +++ b/prb.h @@ -0,0 +1,26 @@ +#ifndef PRB_H +#define PRB_H + +#include +#include +#include +#include +#include +#include + +#include "prb_macros.h" +#include "prb_types.h" + +#include "prb_math.h" +#include "prb_math.c" + +#include "prb_memory.h" +#include "prb_memory.c" + +#include "prb_string.h" +#include "prb_string.c" + +#include "prb_os_io.h" +#include "prb_os_io.c" + +#endif /* PRB_H */ diff --git a/prb_macros.h b/prb_macros.h new file mode 100644 index 0000000..a9a465d --- /dev/null +++ b/prb_macros.h @@ -0,0 +1,61 @@ +#ifndef PRB_MACROS_H +#define PRB_MACROS_H + +#define Assert(e) if (!(e)) { *(int *)0 = 0; } + +#define ArrayCount(a) (sizeof(a)/sizeof(*(a))) + +#define IntFromPtr(p) (unsigned long long)((char *)(p)-(char *)0) +#define PtrFromInt(n) (void *)((char *)0+(n)) + +#define Member(t, m) (((t *)0)->m) +#define OffsetOfMember(t, m) (IntFromPtr(&Member(t, m))) + +#define Min(a, b) (((a) < (b)) ? (a) : (b)) +#define Max(a, b) (((a) > (b)) ? (a) : (b)) + +#define Clamp(a, x, b) (((x) < (a)) ? (a) : \ + (((x) > (b)) ? (b) : (x))) +#define ClampTop(a, b) Min(a, b) +#define ClampBottom(a, b) Max(a, b) + +#define Swap(t, a, b) { t temp = a; a = b; b = temp; } + +/* NOTE(pryazha): Memory */ +#define MemoryZero(p, n) memset((p), 0, (n)) +#define MemoryZeroStruct(p) MemoryZero((p), sizeof(*(p))) +#define MemoryZeroArray(p) MemoryZero((p), sizeof(p)) + +#define MemoryCopy(d, s, n) memmove((d), (s), (n)) +#define MemoryCopyStruct(d, s) MemoryCopy((d), (s), Min(sizeof(*(d)), sizeof(*(s)))) +#define MemoryCopyArray(d, s) MemoryCopy((d), (s), Min(sizeof(d), sizeof(s))) + +#define MemoryMatch(a, b, n) (memcmp((a), (b), (n)) == 0) + +#define Kilobytes(n) n*1024 +#define Megabytes(n) Kilobytes(n)*1024 +#define Gigabytes(n) Megabytes(n)*1024 + +/* NOTE(pryazha): Linked lists */ +#define SLLPush(f, l, n) \ + ((f) == 0 ? \ + ((f) = (l) = (n), (n)->next = 0) : \ + ((l)->next = (n), (l) = (n), (n)->next = 0)) +#define SLLPop(f, l) \ + ((f) == (l) ? \ + ((f) = (l) = 0) : \ + ((f) = (f)->next)) + +#define DLLPushBack_NP(f, l, n, next, prev) \ + ((f) == 0 ? \ + ((f) = (l) = (n), (n)->next = (n)->prev = 0) : \ + ((n)->prev = (l), (l)->next = (n), (l) = (n), (n)->next = 0)) +#define DLLPushBack(f, l, n) DLLPushBack_NP(f, l, n, next, prev) +#define DLLPushFront(f, l, n) DLLPushBack_NP(l, f, n, prev, next) +#define DLLRemove(f, l, n) \ + ((f) == (n) ? \ + ((f) == (l) ? (f) = (l) = 0 : ((f) = (f)->next, (f)->prev = 0)) : \ + ((l) == (n) ? ((l) = (l)->prev, (l)->next = 0) : \ + ((n)->next->prev = (n)->prev, (n)->prev->next = (n)->next))) + +#endif /* PRB_MACROS_H */ diff --git a/prb_math.c b/prb_math.c new file mode 100644 index 0000000..a2d58bc --- /dev/null +++ b/prb_math.c @@ -0,0 +1,385 @@ +F32 f32sin(F32 a) +{ + F32 r = sinf(a); + return r; +} + +F32 f32cos(F32 a) +{ + F32 r = cosf(a); + return r; +} + +F32 f32sqrt(F32 a) +{ + F32 r = sqrtf(a); + return r; +} + +/* NOTE(pryazha): Vectors */ +V2 v2(F32 x, F32 y) +{ + V2 r = { x, y }; + return r; +} + +V2 v2a(F32 x) +{ + V2 r = { x, x }; + return r; +} + +V2 v2neg(V2 a) +{ + V2 r = { -a.x, -a.y }; + return r; +} + +V2 v2add(V2 a, V2 b) +{ + V2 r = { a.x+b.x, a.y+b.y }; + return r; +} + +V2 v2sub(V2 a, V2 b) +{ + V2 r = { a.x-b.x, a.y-b.y }; + return r; +} + +V2 v2scalef(V2 a, F32 s) +{ + V2 r = { a.x*s, a.y*s }; + return r; +} + +V2 v2scale(V2 a, V2 s) +{ + V2 r = { a.x*s.x, a.y*s.y }; + return r; +} + +F32 v2dot(V2 a, V2 b) +{ + F32 r = a.x*b.x+a.y*b.y; + return r; +} + +F32 v2len2(V2 a) +{ + F32 r = v2dot(a, a); + return r; +} + +F32 v2len(V2 a) +{ + F32 r = f32sqrt(v2len2(a)); + return r; +} + +void v2print(V2 a) +{ + fprintf(stdout, "{%f, %f}\n", a.x, a.y); +} + +V3 v3(F32 x, F32 y, F32 z) +{ + V3 r = { x, y, z }; + return r; +} + +V3 v3a(F32 x) +{ + V3 r = { x, x, x }; + return r; +} + +V3 v3neg(V3 a) +{ + V3 r = { -a.x, -a.y, -a.z }; + return r; +} + +V3 v3add(V3 a, V3 b) +{ + V3 r = { a.x+b.x, a.y+b.y, a.z+b.z }; + return r; +} + +V3 v3sub(V3 a, V3 b) +{ + V3 r = { a.x-b.x, a.y-b.y, a.z-b.z }; + return r; +} + +V3 v3scalef(V3 a, F32 s) +{ + V3 r = { a.x*s, a.y*s, a.z*s }; + return r; +} + +V3 v3scale(V3 a, V3 s) +{ + V3 r = { a.x*s.x, a.y*s.y, a.z*s.z }; + return r; +} + +F32 v3dot(V3 a, V3 b) +{ + F32 r = a.x*b.x+a.y*b.y+a.z*b.z; + return r; +} + +V3 v3cross(V3 left, V3 right) +{ + V3 r = { + (left.y*right.z-right.y*left.z), + (right.x*left.z-left.x*right.z), + (left.x*right.y-right.x*left.y) + }; + return r; +} + +F32 v3len2(V3 a) +{ + F32 r = v3dot(a, a); + return r; +} + +F32 v3len(V3 a) +{ + F32 r = f32sqrt(v3len2(a)); + return r; +} + +void v3print(V3 a) +{ + fprintf(stdout, "{%f, %f, %f}\n", a.x, a.y, a.z); +} + +V4 v4(F32 x, F32 y, F32 z, F32 w) +{ + V4 r = { x, y, z, w }; + return r; +} + +V4 v4a(F32 x) +{ + V4 r = { x, x, x, x }; + return r; +} + +V4 v4fromv3(V3 a) +{ + V4 r = { a.x, a.y, a.z, 0.0f }; + return r; +} + +V4 v4neg(V4 a) +{ + V4 r = { -a.x, -a.y, -a.z, -a.w }; + return r; +} + +V4 v4add(V4 a, V4 b) +{ + V4 r = { a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w }; + return r; +} + +V4 v4sub(V4 a, V4 b) +{ + V4 r = { a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w }; + return r; +} + +V4 v4scalef(V4 a, F32 s) +{ + V4 r = { a.x*s, a.y*s, a.z*s, a.w*s }; + return r; +} + +V4 v4scale(V4 a, V4 s) +{ + V4 r = { a.x*s.x, a.y*s.y, a.z*s.z, a.w*s.w }; + return r; +} + +F32 v4dot(V4 a, V4 b) +{ + F32 r = a.x*b.x+a.y*b.y+a.z*b.z+a.w*b.w; + return r; +} + +F32 v4len2(V4 a) +{ + F32 r = v4dot(a, a); + return r; +} + +F32 v4len(V4 a) +{ + F32 r = f32sqrt(v4len2(a)); + return r; +} + +void v4print(V4 a) +{ + fprintf(stdout, "{%f, %f, %f, %f}\n", a.x, a.y, a.z, a.w); +} + +/* NOTE(pryazha): Matrices */ +F32 mat4det(Mat4 m) +{ + F32 r, m00minor, m01minor, m02minor, m03minor; + + F32 m00 = m.m0.x, m10 = m.m0.y, m20 = m.m0.z, m30 = m.m0.w; + F32 m01 = m.m1.x, m11 = m.m1.y, m21 = m.m1.z, m31 = m.m1.w; + F32 m02 = m.m2.x, m12 = m.m2.y, m22 = m.m2.z, m32 = m.m2.w; + F32 m03 = m.m3.x, m13 = m.m3.y, m23 = m.m3.z, m33 = m.m3.w; + + m00minor = ((m11*m22*m33)+(m12*m23*m31)+(m21*m32*m13)- + (m31*m22*m13)-(m21*m12*m33)-(m11*m32*m23)); + + m01minor = ((m10*m22*m33)+(m12*m23*m30)+(m20*m32*m13)- + (m13*m22*m30)-(m23*m32*m10)-(m12*m20*m33)); + + m02minor = ((m10*m21*m33)+(m20*m31*m13)+(m11*m23*m31)- + (m13*m21*m30)-(m23*m31*m10)-(m11*m20*m33)); + + m03minor = ((m10*m21*m32)+(m20*m31*m12)+(m11*m22*m30)- + (m12*m21*m30)-(m11*m20*m32)-(m22*m31*m10)); + + r = m00*m00minor+m01*m01minor-m02*m02minor+m03*m03minor; + + return r; +} + +Mat4 mat4transpose(Mat4 m) +{ + Mat4 r = m; + + Swap(F32, r.m0.y, r.m1.x); + Swap(F32, r.m0.z, r.m2.x); + Swap(F32, r.m0.w, r.m3.x); + + Swap(F32, r.m1.z, r.m2.y); + Swap(F32, r.m1.w, r.m3.y); + + Swap(F32, r.m2.w, r.m3.z); + + return r; +} + +Mat4 mat4mul(Mat4 left, Mat4 right) +{ + F32 l00 = left.m0.x, l01 = left.m0.y, l02 = left.m0.z, l03 = left.m0.w; + F32 l10 = left.m1.x, l11 = left.m1.y, l12 = left.m1.z, l13 = left.m1.w; + F32 l20 = left.m2.x, l21 = left.m2.y, l22 = left.m2.z, l23 = left.m2.w; + F32 l30 = left.m3.x, l31 = left.m3.y, l32 = left.m3.z, l33 = left.m3.w; + + F32 r00 = right.m0.x, r01 = right.m0.y, r02 = right.m0.z, r03 = right.m0.w; + F32 r10 = right.m1.x, r11 = right.m1.y, r12 = right.m1.z, r13 = right.m1.w; + F32 r20 = right.m2.x, r21 = right.m2.y, r22 = right.m2.z, r23 = right.m2.w; + F32 r30 = right.m3.x, r31 = right.m3.y, r32 = right.m3.z, r33 = right.m3.w; + + Mat4 r; + + r.m0.x = l00*r00+l10*r01+l20*r02+l30*r03; + r.m0.y = l01*r00+l11*r01+l21*r02+l31*r03; + r.m0.z = l02*r00+l12*r01+l22*r02+l32*r03; + r.m0.w = l03*r00+l13*r01+l23*r02+l33*r03; + + r.m1.x = l00*r10+l10*r11+l20*r12+l30*r13; + r.m1.y = l01*r10+l11*r11+l21*r12+l31*r13; + r.m1.z = l02*r10+l12*r11+l22*r12+l32*r13; + r.m1.w = l03*r10+l13*r11+l23*r12+l33*r13; + + r.m2.x = l00*r20+l10*r21+l20*r22+l30*r23; + r.m2.y = l01*r20+l11*r21+l21*r22+l31*r23; + r.m2.z = l02*r20+l12*r21+l22*r22+l32*r23; + r.m2.w = l03*r20+l13*r21+l23*r22+l33*r23; + + r.m3.x = l00*r30+l10*r31+l20*r32+l30*r33; + r.m3.y = l01*r30+l11*r31+l21*r32+l31*r33; + r.m3.z = l02*r30+l12*r31+l22*r32+l32*r33; + r.m3.w = l03*r30+l13*r31+l23*r32+l33*r33; + + return r; +} + +Mat4 mat4translate(Mat4 m, V3 v) +{ + Mat4 t = MAT4_IDENTITY; + t.m3 = v4fromv3(v); + Mat4 r = mat4mul(t, m); + return r; +} + +Mat4 mat4scale(Mat4 m, V3 v) +{ + Mat4 s = MAT4_IDENTITY; + s.m0 = v4fromv3(v); + Mat4 r = mat4mul(s, m); + return r; +} + +Mat4 mat4_change_basis(V3 x, V3 y, V3 z) +{ + Mat4 r = MAT4_IDENTITY; + r.m0 = v4(x.x, x.y, x.z, 0.0f); + r.m1 = v4(y.x, y.y, y.z, 0.0f); + r.m2 = v4(z.x, z.y, z.z, 0.0f); + return r; +} + +/* + * NOTE(pryazha): Angles in degrees + * | 1 0 0 | | cy 0 sy | | cz -sz 0 | | cy*cz -cy*sz sy | + * | 0 cx -sx |*| 0 1 0 |*| sz cz 0 |=| sx*sy*cz+cx*sz -sx*sy*sz+cx*cz -sx*cy | + * | 0 sx cx | | -sy 0 cy | | 0 0 1 | | -cx*sy*cz+sx*sz cx*sy*sz+sx*cz cx*cy | + */ +Mat4 mat4rotate(Mat4 m, V3 angles) +{ + F32 angle, cx, sx, cy, sy, cz, sz; + Mat4 rotate, r; + V3 newx, newy, newz; + + angle = DEG2RAD*angles.x; + cx = f32cos(angle); + sx = f32sin(angle); + angle = DEG2RAD*angles.y; + cy = f32cos(angle); + sy = f32sin(angle); + angle = DEG2RAD*angles.z; + cz = f32cos(angle); + sz = f32sin(angle); + + newx = v3(cy*cz, sx*sy*cz+cx*sz, -cx*sy*cz+sx*sz); + newy = v3(-cy*sz, -sx*sy*sz+cx*cz, cx*sy*sz+sx*cz); + newz = v3(sy, -sx*cy, cx*cy); + rotate = mat4_change_basis(newx, newy, newz); + + r = mat4mul(rotate, m); + + return r; +} + +V4 mat4v4mul(Mat4 m, V4 v) +{ + V4 r = { + m.m0.x*v.x+m.m1.x*v.y+m.m2.x*v.z+m.m3.x*v.w, + m.m0.y*v.x+m.m1.y*v.y+m.m2.y*v.z+m.m3.y*v.w, + m.m0.z*v.x+m.m1.z*v.y+m.m2.z*v.z+m.m3.z*v.w, + m.m0.w*v.x+m.m1.w*v.y+m.m2.w*v.z+m.m3.w*v.w + }; + return r; +} + +void mat4print(Mat4 m) +{ + printf("| %.4f %.4f %.4f %.4f |\n", m.m0.x, m.m1.x, m.m2.x, m.m3.x); + printf("| %.4f %.4f %.4f %.4f |\n", m.m0.y, m.m1.y, m.m2.y, m.m3.y); + printf("| %.4f %.4f %.4f %.4f |\n", m.m0.z, m.m1.z, m.m2.z, m.m3.z); + printf("| %.4f %.4f %.4f %.4f |\n\n", m.m0.w, m.m1.w, m.m2.w, m.m3.w); +} diff --git a/prb_math.h b/prb_math.h new file mode 100644 index 0000000..efa0fab --- /dev/null +++ b/prb_math.h @@ -0,0 +1,64 @@ +#ifndef PRB_MATH_H +#define PRB_MATH_H + +/* NOTE(pryazha): Numeric */ +#define F32_PI 3.14159265359f + +#define DEG2RAD F32_PI/180.0f +#define RAD2DEG 182.0f/F32_PI + +F32 f32sin(F32 a); +F32 f32cos(F32 a); +F32 f32sqrt(F32 a); + +/* NOTE(pryazha): Vectors */ +V2 v2(F32 x, F32 y); +V2 v2a(F32 x); +V2 v2neg(V2 a); +V2 v2add(V2 a, V2 b); +V2 v2sub(V2 a, V2 b); +V2 v2scalef(V2 a, F32 s); +V2 v2scale(V2 a, V2 s); +F32 v2dot(V2 a, V2 b); +F32 v2len2(V2 a); +F32 v2len(V2 a); +void v2print(V2 a); + +V3 v3(F32 x, F32 y, F32 z); +V3 v3a(F32 x); +V3 v3neg(V3 a); +V3 v3add(V3 a, V3 b); +V3 v3sub(V3 a, V3 b); +V3 v3scalef(V3 a, F32 s); +V3 v3scale(V3 a, V3 s); +F32 v3dot(V3 a, V3 b); +V3 v3cross(V3 l, V3 r); +F32 v3len2(V3 a); +F32 v3len(V3 a); +void v3print(V3 a); + +V4 v4(F32 x, F32 y, F32 z, F32 w); +V4 v4a(F32 x); +V4 v4fromv3(V3 a); +V4 v4neg(V4 a); +V4 v4add(V4 a, V4 b); +V4 v4sub(V4 a, V4 b); +V4 v4scalef(V4 a, F32 s); +V4 v4scale(V4 a, V4 s); +F32 v4dot(V4 a, V4 b); +F32 v4len2(V4 a); +F32 v4len(V4 a); +void v4print(V4 a); + +/* NOTE(pryazha): Matrices */ +F32 mat4det(Mat4 m); +Mat4 mat4transpose(Mat4 m); +Mat4 mat4mul(Mat4 left, Mat4 right); +Mat4 mat4translate(Mat4 m, V3 v); +Mat4 mat4scale(Mat4 m, V3 v); +Mat4 mat4_change_basis(V3 x, V3 y, V3 z); +Mat4 mat4rotate(Mat4 m, V3 angles); /* NOTE(pryazha): Angles in degrees */ +V4 mat4v4mul(Mat4 m, V4 v); +void mat4print(Mat4 m); + +#endif /* PRB_MATH_H */ diff --git a/prb_memory.c b/prb_memory.c new file mode 100644 index 0000000..4bceccc --- /dev/null +++ b/prb_memory.c @@ -0,0 +1,42 @@ +Arena *arena_alloc(U64 cap) +{ + Arena *arena = 0; + + /* TODO(pryazha): Use OS related memory allocator (like VirtualAlloc on Windows) */ + arena = malloc(sizeof(Arena)); + Assert(arena); + + if (!cap) + cap = DEFAULT_ALLOC_SIZE; + + arena->mem = malloc(cap); + Assert(arena->mem); + arena->cap = cap; + arena->used = 0; + + return arena; +} + +void arena_release(Arena *arena) +{ + free(arena->mem); + arena->mem = 0; + arena->cap = 0; + arena->used = 0; + free(arena); +} + +void *arena_push(Arena *arena, U64 size) +{ + Assert(arena->used+size <= arena->cap); + void *r = arena->mem+arena->used; + arena->used += size; + return r; +} + +void arena_pop(Arena *arena, U64 amount) +{ + Assert(arena); + U64 clamped = ClampTop(amount, arena->used); + arena->used = arena->used-clamped; +} diff --git a/prb_memory.h b/prb_memory.h new file mode 100644 index 0000000..40a00dc --- /dev/null +++ b/prb_memory.h @@ -0,0 +1,11 @@ +#ifndef PRB_MEMORY_H +#define PRB_MEMORY_H + +#define DEFAULT_ALLOC_SIZE Kilobytes(4) + +Arena *arena_alloc(U64 cap); +void arena_release(Arena *arena); +void *arena_push(Arena *arena, U64 size); +void arena_pop(Arena *arena, U64 amount); + +#endif /* PRB_MEMORY_H */ diff --git a/prb_os_io.c b/prb_os_io.c new file mode 100644 index 0000000..d35b73f --- /dev/null +++ b/prb_os_io.c @@ -0,0 +1,31 @@ +Str8 str8_read_entire_file(Arena *arena, Str8 filename) +{ + /* TODO(pryazha): Make it crossplatform already */ + Assert(filename.ptr); + Assert(filename.length); + + Str8 result = {0}; + Arena *tmp = arena_alloc(0); + + char *cfilename = str8_to_cstr(tmp, filename); + + FILE *f = fopen(cfilename, "rb"); + if (!f) + return result; + + fseek(f, 0, SEEK_END); + U64 size = ftell(f); + rewind(f); + + U8 *mem = arena_push(arena, size+1); + fread(mem, size, 1, f); + fclose(f); + + mem[size] = 0; + + result = str8(mem, size); + + arena_release(tmp); + + return result; +} diff --git a/prb_os_io.h b/prb_os_io.h new file mode 100644 index 0000000..811778c --- /dev/null +++ b/prb_os_io.h @@ -0,0 +1,6 @@ +#ifndef PRB_OS_IO_H +#define PRB_OS_IO_H + +Str8 str8_read_entire_file(Arena *arena, Str8 filename); + +#endif /* PRB_OS_IO_H */ diff --git a/prb_string.c b/prb_string.c new file mode 100644 index 0000000..061731c --- /dev/null +++ b/prb_string.c @@ -0,0 +1,115 @@ +Str8 str8(U8 *ptr, U64 length) +{ + Assert(ptr); + Str8 r = { ptr, length }; + return r; +} + +Str8 str8_range(U8 *start, U8 *end) +{ + Str8 r = { start, end-start }; + return r; +} + +Str8 str8_from_cstr(char *cstr) +{ + U8 *ptr = (U8 *)cstr; + for (; *ptr; ++ptr); + Str8 r = str8_range((U8 *)cstr, ptr); + return r; +} + +char *str8_to_cstr(Arena *arena, Str8 s) +{ + U64 length = s.length+1; + char *r = arena_push(arena, length*sizeof(U8)); + MemoryCopy(r, s.ptr, length*sizeof(U8)); + *(r+s.length) = 0; + return r; +} + +Str8 str8_chop_end(Str8 s, U64 count) +{ + U64 length = s.length-ClampTop(count, s.length); + Str8 r = str8(s.ptr, length); + return r; +} + +Str8 str8_chop_start(Str8 s, U64 count) +{ + U64 clamped = ClampTop(count, s.length); + U64 length = s.length-ClampTop(count, s.length); + Str8 r = str8(s.ptr+clamped, length); + return r; +} + +Str8 str8_pushfv(Arena *arena, char *fmt, va_list args) +{ + Str8 r = {0}; + + va_list args2; + va_copy(args2, args); + + U32 buf_size = 1024; + U8 *buf = arena_push(arena, buf_size); + + S32 n = vsnprintf((char *)buf, buf_size, fmt, args); + va_end(args2); + + if (n > 0) + r = str8(buf, n); + + return r; +} + +Str8 str8_pushf(Arena *arena, char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + Str8 r = str8_pushfv(arena, fmt, args); + va_end(args); + return r; +} + +void str8print(Str8 s) +{ + for (U64 i = 0; i < s.length; ++i) + printf("%c", (char)(*(s.ptr+i))); +} + +Str8List *str8_list(Arena *arena) +{ + Str8List *list = arena_push(arena, sizeof(Str8List)); + MemoryZero(list, sizeof(Str8List)); + return list; +} + +void str8_list_push(Arena *arena, Str8List *list, Str8 str, B32 to_front) +{ + Assert(arena && list); + Str8Node *n = arena_push(arena, sizeof(Str8Node)); + n->str = str; + if (to_front) + DLLPushFront(list->first, list->last, n); + else + DLLPushBack(list->first, list->last, n); + list->total_length += str.length; + list->node_count++; +} + +void str8_list_pushf(Arena *arena, Str8List *list, B32 to_front, char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + Str8 str = str8_pushfv(arena, fmt, args); + va_end(args); + str8_list_push(arena, list, str, to_front); +} + +void str8_list_print(Str8List *list) +{ + for (Str8Node *n = list->first; n; n = n->next) { + str8print(n->str); + printf("%s", (n->next) ? " -> " : "\n"); + } +} diff --git a/prb_string.h b/prb_string.h new file mode 100644 index 0000000..85496cb --- /dev/null +++ b/prb_string.h @@ -0,0 +1,22 @@ +#ifndef PRB_STRING_H +#define PRB_STRING_H + +#define str8lit(s) str8((U8 *)(s), sizeof(s)-1) +#define str8expand(s) (int)((s).length), ((s).ptr) + +Str8 str8(U8 *ptr, U64 length); +Str8 str8_range(U8 *start, U8 *end); +Str8 str8_from_cstr(char *cstr); +char *str8_to_cstr(Arena *arena, Str8 s); +Str8 str8_chop_end(Str8 s, U64 count); +Str8 str8_chop_start(Str8 s, U64 count); +Str8 str8_pushfv(Arena *arena, char *fmt, va_list args); +Str8 str8_pushf(Arena *arena, char *fmt, ...); +void str8print(Str8 s); + +Str8List *str8_list(Arena *arena); +void str8_list_push(Arena *arena, Str8List *list, Str8 str, B32 to_front); +void str8_list_pushf(Arena *arena, Str8List *list, B32 to_front, char *fmt, ...); +void str8_list_print(Str8List *list); + +#endif /* PRB_STRING_H */ diff --git a/prb_types.h b/prb_types.h new file mode 100644 index 0000000..a1ac3ba --- /dev/null +++ b/prb_types.h @@ -0,0 +1,84 @@ +#ifndef PRB_TYPES_H +#define PRB_TYPES_H + +typedef int8_t S8; +typedef int16_t S16; +typedef int32_t S32; +typedef int64_t S64; +typedef uint8_t U8; +typedef uint16_t U16; +typedef uint32_t U32; +typedef uint64_t U64; +typedef S32 B32; +typedef float F32; +typedef double F64; + +/* NOTE(pryazha): The library uses a right-handed coordiante system (for now) */ + +typedef struct { + F32 x, y; +} V2; + +#define V2_ZERO (V2){ 0.0f, 0.0f } +#define V2_ONE (V2){ 1.0f, 1.0f } +#define V2_RIGHT (V2){ 1.0f, 0.0f } +#define V2_UP (V2){ 0.0f, 1.0f } +#define V2_LEFT (V2){-1.0f, 0.0f } +#define V2_DOWN (V2){ 0.0f, -1.0f } + +typedef struct { + F32 x, y, z; +} V3; + +#define V3_ZERO (V3){ 0.0f, 0.0f, 0.0f } +#define V3_ONE (V3){ 1.0f, 1.0f, 1.0f } +#define V3_RIGHT (V3){ 1.0f, 0.0f, 0.0f } +#define V3_UP (V3){ 0.0f, 1.0f, 0.0f } +#define V3_LEFT (V3){-1.0f, 0.0f, 0.0f } +#define V3_DOWN (V3){ 0.0f, -1.0f, 0.0f } +#define V3_FORWARD (V3){ 0.0f, 0.0f, 1.0f } +#define V3_BACKWARD (V3){ 0.0f, 0.0f, -1.0f } + +typedef struct { + F32 x, y, z, w; +} V4; + +#define V4_ZERO (V4){ 0.0f, 0.0f, 0.0f, 0.0f } +#define V4_ONE (V4){ 1.0f, 1.0f, 1.0f, 1.0f } + +typedef struct { + V4 m0, m1, m2, m3; +} Mat4; + +#define MAT4_IDENTITY (Mat4) { \ + { 1.0f, 0.0f, 0.0f, 0.0f }, \ + { 0.0f, 1.0f, 0.0f, 0.0f }, \ + { 0.0f, 0.0f, 1.0f, 0.0f }, \ + { 0.0f, 0.0f, 0.0f, 1.0f } } + +typedef struct { + U8 *mem; + U64 cap; + U64 used; +} Arena; + +/* NOTE(pryazha): Strings */ +typedef struct { + U8 *ptr; + U64 length; +} Str8; + +typedef struct Str8Node { + Str8 str; + struct Str8Node *next; + struct Str8Node *prev; +} Str8Node; + +typedef struct { + Str8Node *first; + Str8Node *last; + U64 total_length; + U32 node_count; +} Str8List; + +#endif /* PRB_TYPES_H */ -- cgit v1.2.3-70-g09d2