Compare commits
180 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8999d2ba44 | ||
|
|
7ac798cef9 | ||
|
|
67359073ca | ||
|
|
3edfe19438 | ||
|
|
9215540015 | ||
|
|
83cb4cc210 | ||
|
|
d1a14bee5d | ||
|
|
ba3b8f8370 | ||
|
|
962bbfc6bf | ||
|
|
b00e465deb | ||
|
|
db0870f31f | ||
|
|
87a6e9693c | ||
|
|
aaacda6e14 | ||
|
|
f9c41a0866 | ||
|
|
fa8aca8789 | ||
|
|
efef4e31dd | ||
|
|
3973766b84 | ||
|
|
4d2b1d51e4 | ||
|
|
8713741782 | ||
|
|
ac6526b731 | ||
|
|
94897c4eca | ||
|
|
444cc22633 | ||
|
|
aeea213873 | ||
|
|
8d31d0c3cc | ||
|
|
9bd3d84f3d | ||
|
|
04b66f1965 | ||
|
|
7c1b9d0a32 | ||
|
|
02869da279 | ||
|
|
aebfd788c7 | ||
|
|
26d82cf55d | ||
|
|
d9335f6a95 | ||
|
|
0e7cc36567 | ||
|
|
e57663c937 | ||
|
|
23433fe2dc | ||
|
|
fefb9f4428 | ||
|
|
68c4b8a60f | ||
|
|
33b6f0f3a4 | ||
|
|
ca0ba55050 | ||
|
|
236618f87b | ||
|
|
f5ea52a2b8 | ||
|
|
6a6daad739 | ||
|
|
4724e5fec3 | ||
|
|
d3d1b0cbcc | ||
|
|
20aa6cb764 | ||
|
|
a41bb7c07a | ||
|
|
53ccae09cc | ||
|
|
869251e590 | ||
|
|
45f1af2bde | ||
|
|
15d25242be | ||
|
|
22509ab2d4 | ||
|
|
796e1ad22a | ||
|
|
acfcf2f1d1 | ||
|
|
ca46387b64 | ||
|
|
fd79b81918 | ||
|
|
9ace148917 | ||
|
|
a85c9f4898 | ||
|
|
fadcd1fac5 | ||
|
|
1a4445f510 | ||
|
|
fc824ff6d4 | ||
|
|
2c690425c9 | ||
|
|
ee71f0f870 | ||
|
|
e8650c1b8e | ||
|
|
cef7718468 | ||
|
|
895154bcb2 | ||
|
|
f421b74c0f | ||
|
|
90edc3b0a5 | ||
|
|
f1d602029c | ||
|
|
10a889c482 | ||
|
|
b7f50b2fb6 | ||
|
|
2ee6a76464 | ||
|
|
f0d3e9a5c8 | ||
|
|
7c284cc5bc | ||
|
|
7b96144716 | ||
|
|
81c7cb6527 | ||
|
|
186d3ce9fb | ||
|
|
e7edb181dc | ||
|
|
ef8b3e6195 | ||
|
|
7f9ded7642 | ||
|
|
34b06ca587 | ||
|
|
4d845608b8 | ||
|
|
eaf32c83bf | ||
|
|
808e6b9b20 | ||
|
|
7dd72e7328 | ||
|
|
f8270483e1 | ||
|
|
f17babfe8a | ||
|
|
f65d5ad7a9 | ||
|
|
0d78f10161 | ||
|
|
7d5b61ce01 | ||
|
|
b48933b096 | ||
|
|
fd1dfd7d65 | ||
|
|
be56f2c524 | ||
|
|
d31c10a01e | ||
|
|
c04e57399a | ||
|
|
6c090f6193 | ||
|
|
5ca45bce37 | ||
|
|
729327a078 | ||
|
|
ea76845ecb | ||
|
|
5506aed190 | ||
|
|
43366d1c6a | ||
|
|
f35f4b9fad | ||
|
|
c4b4fcc17e | ||
|
|
fbf132d1d1 | ||
|
|
e274c195af | ||
|
|
fd28dc5644 | ||
|
|
5aa3de194c | ||
|
|
9400199b80 | ||
|
|
200d344dee | ||
|
|
094edcd32e | ||
|
|
a005a044da | ||
|
|
ae315eecb9 | ||
|
|
dcb0ca5d14 | ||
|
|
07b729d5d6 | ||
|
|
cd4599b447 | ||
|
|
b2ea5eae5e | ||
|
|
29ff1f02e9 | ||
|
|
d840a100a7 | ||
|
|
95bfa196fd | ||
|
|
aceb8ce3a8 | ||
|
|
33e889907e | ||
|
|
61537200c0 | ||
|
|
080f5c94bd | ||
|
|
7207c03c72 | ||
|
|
cf9f27db54 | ||
|
|
0a2b81b128 | ||
|
|
05c15c8ba7 | ||
|
|
d768dae402 | ||
|
|
d580c47504 | ||
|
|
7b7ded566c | ||
|
|
d9427b1e6f | ||
|
|
da55d9067c | ||
|
|
e5702a716f | ||
|
|
2dd8d7e8b1 | ||
|
|
168e2c43d0 | ||
|
|
638c1cb339 | ||
|
|
6a430eb834 | ||
|
|
3c82b48b1f | ||
|
|
72a341a37f | ||
|
|
79d5353cfd | ||
|
|
98efce4b0d | ||
|
|
c9c26d8071 | ||
|
|
0e68f812b5 | ||
|
|
2752837839 | ||
|
|
a627cd5b65 | ||
|
|
361dcb2a1f | ||
|
|
5082f5a813 | ||
|
|
3d2008c70b | ||
|
|
a685b812d9 | ||
|
|
3b70f83c7d | ||
|
|
a28b924f94 | ||
|
|
636269f6af | ||
|
|
826ca42d83 | ||
|
|
620b21bfce | ||
|
|
52dc7658da | ||
|
|
06621eb3b7 | ||
|
|
3b9ee2e9f3 | ||
|
|
6ae16c9895 | ||
|
|
aa1100817a | ||
|
|
725c8b57ae | ||
|
|
00f3af78e3 | ||
|
|
3d3e6996b0 | ||
|
|
47bb749ce9 | ||
|
|
ba72d25867 | ||
|
|
8e82249f65 | ||
|
|
dff07d020c | ||
|
|
0f98d78a67 | ||
|
|
c2ea6a38b5 | ||
|
|
ccc0d7452a | ||
|
|
386eabb932 | ||
|
|
4ee2013169 | ||
|
|
d892f3ba4a | ||
|
|
61dd488b76 | ||
|
|
4cae4ba9d5 | ||
|
|
07a056441a | ||
|
|
254953611e | ||
|
|
5608460901 | ||
|
|
3b23200b85 | ||
|
|
1c5cd35372 | ||
|
|
e9caf5a981 | ||
|
|
de8419cc8b | ||
|
|
f220848896 |
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -65,7 +65,7 @@ src/external/SDL3
|
|||
# Emscripten
|
||||
emsdk
|
||||
|
||||
# Ignore wasm data in examples/
|
||||
# Ignore binaries generated in examples/
|
||||
examples/**/*
|
||||
!examples/**/*.*
|
||||
!examples/**/*/
|
||||
|
|
@ -125,8 +125,8 @@ build-*/
|
|||
docgen_tmp/
|
||||
|
||||
# Tools stuff
|
||||
tools/parser/rlparser.exe
|
||||
tools/parser/rlparser
|
||||
tools/rlparser/rlparser.exe
|
||||
tools/rlparser/rlparser
|
||||
tools/rexm/rexm.exe
|
||||
tools/rexm/rexm
|
||||
|
||||
|
|
|
|||
31
BINDINGS.md
31
BINDINGS.md
|
|
@ -10,8 +10,8 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **5.5** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
|
||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
|
||||
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib55.c3l) | **5.5** | [C3](https://c3-lang.org) | MIT |
|
||||
| [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib6.c3l) | **6** | [C3](https://c3-lang.org) | MIT |
|
||||
| [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **6.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||
| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
|
||||
|
|
@ -26,18 +26,19 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 |
|
||||
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
|
||||
| [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT |
|
||||
| [raylib_dart](https://pub.dev/packages/raylib_dart) | 6.0 | [Dart](https://dart.dev) | MIT |
|
||||
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
|
||||
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
|
||||
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib |
|
||||
| [DenoRaylib550](https://github.com/JJLDonley/DenoRaylib550) | **5.5** | [Deno](https://deno.land) | MIT |
|
||||
| [raylib-d](https://github.com/schveiguy/raylib-d) | **6.0** | [D](https://dlang.org) | Zlib |
|
||||
| [Deno-Raylib](https://github.com/JJLDonley/Deno-Raylib) | **6.0** | [Deno / TS](https://deno.land) | MIT |
|
||||
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 5.5 | [Factor](https://factorcode.org) | BSD |
|
||||
| [raylib4fb](https://github.com/mudhairless/raylib4fb) | **5.5** | [FreeBASIC](https://www.freebasic.net) | Zlib |
|
||||
| [raylib4fb](https://github.com/mudhairless/raylib4fb) | **6.0** | [FreeBASIC](https://www.freebasic.net) | Zlib |
|
||||
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
||||
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
||||
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
|
||||
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.5** | [Go](https://golang.org) | Zlib |
|
||||
| [raylib-go](https://github.com/gen2brain/raylib-go) | **6.0** | [Go](https://golang.org) | Zlib |
|
||||
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
|
||||
| [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** |
|
||||
| [h-raylib](https://github.com/Anut-py/h-raylib) | **5.5-dev** | [Haskell](https://haskell.org) | Apache-2.0 |
|
||||
|
|
@ -49,7 +50,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [Raylib.jl](https://github.com/chengchingwen/Raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib |
|
||||
| [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** |
|
||||
| [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib |
|
||||
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.0 | [Lua](http://www.lua.org) | ISC |
|
||||
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.5 | [Lua](http://www.lua.org) | ISC |
|
||||
| [raylib-lua-bindings (WIP)](https://github.com/legendaryredfox/raylib-lua-bindings) | 5.5 | [Lua](http://www.lua.org) | ISC |
|
||||
| [ReiLua](https://github.com/nullstare/ReiLua) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
||||
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib |
|
||||
|
|
@ -62,9 +63,9 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib |
|
||||
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | Zlib |
|
||||
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
|
||||
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **5.0** | [OCaml](https://ocaml.org) | MIT |
|
||||
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **6.0** | [OCaml](https://ocaml.org) | MIT |
|
||||
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
||||
| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **5.5** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)/[Delphi](https://en.wikipedia.org/wiki/Delphi_(software)) | Zlib |
|
||||
| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **6.0** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)/[Delphi](https://en.wikipedia.org/wiki/Delphi_(software)) | Zlib |
|
||||
| [Raylib.4.0.Pascal](https://github.com/sysrpl/Raylib.4.0.Pascal) | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
||||
| [pyraylib](https://github.com/Ho011/pyraylib) | 3.7 | [Python](https://www.python.org) | Zlib |
|
||||
| [raylib-python-cffi](https://github.com/electronstudio/raylib-python-cffi) | **5.5** | [Python](https://www.python.org) | EPL-2.0 |
|
||||
|
|
@ -77,6 +78,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [raylibr](https://github.com/jeroenjanssens/raylibr) | 4.0 | [R](https://www.r-project.org) | MIT |
|
||||
| [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 5.5 | [Rust](https://www.rust-lang.org) | GPLv3 |
|
||||
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib |
|
||||
| [sola-raylib](https://github.com/brettchalupa/sola-raylib) | **6.0** | [Rust](https://www.rust-lang.org) | Zlib |
|
||||
| [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib |
|
||||
| [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** |
|
||||
| [racket-raylib](https://github.com/eutro/racket-raylib) | **5.5** | [Racket](https://racket-lang.org) | MIT/Apache-2.0 |
|
||||
|
|
@ -86,10 +88,10 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [raylib-umka](https://github.com/robloach/raylib-umka) | 4.5 | [Umka](https://github.com/vtereshkov/umka-lang) | Zlib |
|
||||
| [raylib-v](https://github.com/vlang/raylib) | 5.5 | [V](https://vlang.io) | MIT/Unlicense |
|
||||
| [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib |
|
||||
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **5.0** | [Vala](https://vala.dev) | Zlib |
|
||||
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **6.0** | [Vala](https://vala.dev) | Zlib |
|
||||
| [raylib-wave](https://github.com/wavefnd/raylib-wave) | **auto** |[Wave](http://wave-lang.dev) | Zlib |
|
||||
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
|
||||
| [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **5.6-dev** | [Zig](https://ziglang.org) | MIT |
|
||||
| [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **6.0** | [Zig](https://ziglang.org) | MIT |
|
||||
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT |
|
||||
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
|
||||
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
|
||||
|
|
@ -101,10 +103,11 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [Raylib.lean](https://github.com/KislyjKisel/Raylib.lean) | **5.5-dev** | [Lean4](https://lean-lang.org) | BSD-3-Clause |
|
||||
| [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain |
|
||||
| [raylib-apl](https://github.com/Brian-ED/raylib-apl) | **5.0** | [Dyalog APL](https://www.dyalog.com/) | MIT |
|
||||
| [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **5.5** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT |
|
||||
| [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **6.0** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT |
|
||||
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
|
||||
| [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** |
|
||||
| [Target](https://github.com/FinnDemonCat/Target/tree/main/libs/raylib) | **5.5** | [Dart](https://dart.dev/) | Apache-2.0 license |
|
||||
| [Target](https://github.com/FinnDemonCat/Target/tree/main/libs/raylib) | **5.5** | [Dart](https://dart.dev/) | Apache-2.0 license |
|
||||
| [gclang-raylib](https://github.com/gnuchanos/gcLang_Compiler/tree/main/windows_version/raylib_version)| **6.0** | [gclang](https://github.com/gnuchanos/gcLang_Compiler) | AGPL-3.0 |
|
||||
|
||||
|
||||
### Utility Wrapers
|
||||
|
|
@ -112,7 +115,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's paradigm.
|
||||
| Name | raylib Version | Language | License |
|
||||
| ---------------------------------------------------- | :------------: | :------------------------------------------: | :-----: |
|
||||
| [raylib-cpp](https://github.com/robloach/raylib-cpp) | **5.5** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib |
|
||||
| [raylib-cpp](https://github.com/robloach/raylib-cpp) | **6.0** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib |
|
||||
| [claylib](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
|
||||
| [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
||||
| [DOOR](https://github.com/RealDoigt/DOOR) | 4.0 | [D](https://dlang.org) | MIT |
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
#this change avoid the warning that appear when we include raylib using Cmake fatch content
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
project(raylib)
|
||||
|
||||
# Avoid excessive expansion of variables in conditionals. In particular, if
|
||||
|
|
@ -29,7 +28,7 @@ include(CompilerFlags)
|
|||
# Registers build options that are exposed to cmake
|
||||
include(CMakeOptions.txt)
|
||||
|
||||
if (UNIX AND NOT APPLE AND NOT "${PLATFORM}" MATCHES "DRM" AND NOT "${PLATFORM}" MATCHES "Web")
|
||||
if (UNIX AND NOT APPLE AND NOT "${PLATFORM}" MATCHES "DRM" AND NOT "${PLATFORM}" MATCHES "Web" AND NOT "${PLATFORM}" MATCHES "SDL")
|
||||
if (NOT GLFW_BUILD_WAYLAND AND NOT GLFW_BUILD_X11)
|
||||
message(FATAL_ERROR "Cannot disable both Wayland and X11")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ if(EMSCRIPTEN)
|
|||
# When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default
|
||||
SET(PLATFORM Web CACHE STRING "Platform to build for.")
|
||||
endif()
|
||||
enum_option(PLATFORM "Desktop;Web;WebRGFW;Android;Raspberry Pi;DRM;SDL;RGFW;Memory" "Platform to build for.")
|
||||
enum_option(PLATFORM "Desktop;Win32;Web;WebRGFW;Android;Raspberry Pi;DRM;SDL;RGFW;Memory" "Platform to build for.")
|
||||
|
||||
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")
|
||||
|
||||
|
|
@ -29,11 +29,15 @@ option(GLFW_BUILD_WAYLAND "Build the bundled GLFW with Wayland support" OFF)
|
|||
option(GLFW_BUILD_X11 "Build the bundled GLFW with X11 support" ON)
|
||||
|
||||
option(INCLUDE_EVERYTHING "Include everything disabled by default (for CI usage)" OFF)
|
||||
set(OFF ${INCLUDE_EVERYTHING} CACHE INTERNAL "Replace any OFF by default with \${OFF} to have it covered by this option")
|
||||
|
||||
include(ParseConfigHeader)
|
||||
|
||||
foreach(FLAG IN LISTS CONFIG_HEADER_FLAGS)
|
||||
string(REGEX MATCH "([^=]+)=(.+)" _ ${FLAG})
|
||||
cmake_dependent_option(${CMAKE_MATCH_1} "" ${CMAKE_MATCH_2} CUSTOMIZE_BUILD ${CMAKE_MATCH_2})
|
||||
set(CONFIG_HEADER_FLAG_DEFAULT ${CMAKE_MATCH_2})
|
||||
if (INCLUDE_EVERYTHING AND "${CONFIG_HEADER_FLAG_DEFAULT}" STREQUAL "OFF")
|
||||
set(CONFIG_HEADER_FLAG_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
cmake_dependent_option(${CMAKE_MATCH_1} "" ${CONFIG_HEADER_FLAG_DEFAULT} CUSTOMIZE_BUILD ${CONFIG_HEADER_FLAG_DEFAULT})
|
||||
endforeach()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
|
|||
|
||||
[](https://github.com/raysan5/raylib/releases)
|
||||
[](https://github.com/raysan5/raylib/stargazers)
|
||||
[](https://github.com/raysan5/raylib/commits/master)
|
||||
[](https://github.com/raysan5/raylib/commits/master)
|
||||
[](https://github.com/sponsors/raysan5)
|
||||
[](https://repology.org/project/raylib/versions)
|
||||
[](LICENSE)
|
||||
|
|
|
|||
|
|
@ -706,10 +706,16 @@ fn addExamples(
|
|||
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize });
|
||||
const emcc_settings = emsdk.emccDefaultSettings(b.allocator, .{ .optimize = optimize });
|
||||
|
||||
const EmccExamplesPreloadMap = std.static_string_map.StaticStringMap([]const emsdk.zemscripten.EmccFilePath);
|
||||
const EmccExamplesPreloadKV = struct { []const u8, []const emsdk.zemscripten.EmccFilePath };
|
||||
const emcc_examples_preloads: []const EmccExamplesPreloadKV = @import("examples/example_resources.zon");
|
||||
const emcc_examples_preloads_map = EmccExamplesPreloadMap.initComptime(emcc_examples_preloads);
|
||||
|
||||
const emcc_step = emsdk.emccStep(b, raylib, wasm, .{
|
||||
.optimize = optimize,
|
||||
.flags = emcc_flags,
|
||||
.settings = emcc_settings,
|
||||
.preload_paths = emcc_examples_preloads_map.get(filename) orelse &.{},
|
||||
.shell_file_path = b.path("src/shell.html"),
|
||||
.install_dir = install_dir,
|
||||
});
|
||||
|
|
@ -733,7 +739,6 @@ fn addExamples(
|
|||
.root_module = exe_mod,
|
||||
.use_lld = target.result.os.tag == .windows,
|
||||
});
|
||||
b.installArtifact(exe);
|
||||
|
||||
const install_cmd = b.addInstallArtifact(exe, .{ .dest_sub_path = b.fmt("{s}/{s}", .{ module, filename }) });
|
||||
|
||||
|
|
@ -788,3 +793,4 @@ fn waylandGenerate(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,30 @@ if(POLICY CMP0072)
|
|||
cmake_policy(SET CMP0072 NEW)
|
||||
endif()
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
include(CMakePushCheckState)
|
||||
|
||||
function(raylib_check_libatomic_required result)
|
||||
set(_atomic_test_source "
|
||||
int main(void)
|
||||
{
|
||||
volatile long long value = 0;
|
||||
return (int)__atomic_fetch_add(&value, 1, __ATOMIC_SEQ_CST);
|
||||
}")
|
||||
|
||||
check_c_source_compiles("${_atomic_test_source}" RAYLIB_ATOMICS_WITHOUT_LIBATOMIC)
|
||||
|
||||
if (RAYLIB_ATOMICS_WITHOUT_LIBATOMIC)
|
||||
set(${result} FALSE PARENT_SCOPE)
|
||||
else ()
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES atomic)
|
||||
check_c_source_compiles("${_atomic_test_source}" RAYLIB_ATOMICS_WITH_LIBATOMIC)
|
||||
cmake_pop_check_state()
|
||||
set(${result} ${RAYLIB_ATOMICS_WITH_LIBATOMIC} PARENT_SCOPE)
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
set(RAYLIB_DEPENDENCIES "include(CMakeFindDependencyMacro)")
|
||||
|
||||
if (${PLATFORM} STREQUAL "Desktop")
|
||||
|
|
@ -67,6 +91,21 @@ if (${PLATFORM} STREQUAL "Desktop")
|
|||
endif ()
|
||||
endif ()
|
||||
|
||||
elseif (${PLATFORM} STREQUAL "Win32")
|
||||
if ((NOT WIN32) AND (NOT CMAKE_C_COMPILER MATCHES "mingw|mingw32|mingw64"))
|
||||
message(FATAL_ERROR "Win32 platform requires Windows or a cross compiler.")
|
||||
endif ()
|
||||
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_WIN32")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
|
||||
if (${OPENGL_VERSION} MATCHES "Software")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||
endif ()
|
||||
|
||||
find_package(OpenGL QUIET)
|
||||
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm)
|
||||
|
||||
elseif (${PLATFORM} STREQUAL "Web")
|
||||
set(PLATFORM_CPP "PLATFORM_WEB")
|
||||
if(NOT GRAPHICS)
|
||||
|
|
@ -222,6 +261,14 @@ endif ()
|
|||
|
||||
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY})
|
||||
|
||||
if (SUPPORT_MODULE_RAUDIO AND UNIX AND NOT APPLE)
|
||||
raylib_check_libatomic_required(RAYLIB_LIBATOMIC_REQUIRED)
|
||||
if (RAYLIB_LIBATOMIC_REQUIRED)
|
||||
message(STATUS "64-bit atomics require libatomic")
|
||||
list(APPEND LIBS_PRIVATE atomic)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (${PLATFORM} MATCHES "Desktop")
|
||||
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
|
||||
endif ()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ string(REGEX MATCHALL ${MACRO_REGEX} MACRO_LIST ${CONFIG_HEADER_CONTENT})
|
|||
set(CONFIG_HEADER_FLAGS ${MACRO_LIST})
|
||||
list(FILTER CONFIG_HEADER_FLAGS INCLUDE REGEX "^.+SUPPORT_")
|
||||
list(TRANSFORM CONFIG_HEADER_FLAGS REPLACE ${MACRO_REGEX} [[\2=OFF]] REGEX "^//")
|
||||
list(TRANSFORM CONFIG_HEADER_FLAGS REPLACE ${MACRO_REGEX} [[\2=ON]])
|
||||
list(TRANSFORM CONFIG_HEADER_FLAGS REPLACE ${MACRO_REGEX} [[\2=\3]] REGEX "^[^/]")
|
||||
list(TRANSFORM CONFIG_HEADER_FLAGS REPLACE [[=0$]] [[=OFF]])
|
||||
list(TRANSFORM CONFIG_HEADER_FLAGS REPLACE [[=1$]] [[=ON]])
|
||||
|
||||
set(CONFIG_HEADER_VALUES ${MACRO_LIST})
|
||||
list(FILTER CONFIG_HEADER_VALUES EXCLUDE REGEX "(^.+SUPPORT_)|(^//)")
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@ if (${PLATFORM} MATCHES "Android")
|
|||
|
||||
elseif (${PLATFORM} MATCHES "Web")
|
||||
set(example_sources) # clear example_sources
|
||||
list(APPEND example_sources others/web_basic_window.c)
|
||||
list(APPEND example_sources core/core_input_gestures_testbed.c)
|
||||
|
||||
elseif ("${PLATFORM}" STREQUAL "DRM")
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
# - Linux (X11 desktop mode)
|
||||
# - macOS/OSX (x64, arm64 (not tested))
|
||||
# - Others (not tested)
|
||||
# > PLATFORM_DESKTOP_WIN32 (native Win32):
|
||||
# - Windows (Win32, Win64)
|
||||
# > PLATFORM_WEB_RGFW:
|
||||
# - HTML5 (WebAssembly)
|
||||
# > PLATFORM_WEB:
|
||||
|
|
@ -794,6 +796,23 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
|||
rm -f *.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
del *.o *.exe /s
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
find . -type f -perm -ugo+x -delete
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
find . -type f -executable -delete
|
||||
rm -fv *.o
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "raygui.h" // Required for GUI controls
|
||||
|
||||
#define MAX_FILEPATH_SIZE 1024
|
||||
#define FILE_FILTER "DIRS*;.png;.c"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
|
|
@ -41,7 +42,7 @@ int main(void)
|
|||
// NOTE: LoadDirectoryFiles() loads files and directories by default,
|
||||
// use LoadDirectoryFilesEx() for custom filters and recursive directories loading
|
||||
//FilePathList files = LoadDirectoryFiles(directory);
|
||||
FilePathList files = LoadDirectoryFilesEx(directory, ".png;.c", false);
|
||||
FilePathList files = LoadDirectoryFilesEx(directory, FILE_FILTER, false);
|
||||
|
||||
int btnBackPressed = false;
|
||||
|
||||
|
|
@ -61,7 +62,22 @@ int main(void)
|
|||
{
|
||||
TextCopy(directory, GetPrevDirectoryPath(directory));
|
||||
UnloadDirectoryFiles(files);
|
||||
files = LoadDirectoryFiles(directory);
|
||||
files = LoadDirectoryFilesEx(directory, FILE_FILTER, false);
|
||||
|
||||
listScrollIndex = 0;
|
||||
listItemActive = -1;
|
||||
listItemFocused = -1;
|
||||
}
|
||||
|
||||
if ((listItemActive >= 0) && (listItemActive < (int)files.count) && DirectoryExists(files.paths[listItemActive]))
|
||||
{
|
||||
TextCopy(directory, files.paths[listItemActive]);
|
||||
UnloadDirectoryFiles(files);
|
||||
files = LoadDirectoryFilesEx(directory, FILE_FILTER, false);
|
||||
|
||||
listScrollIndex = 0;
|
||||
listItemActive = -1;
|
||||
listItemFocused = -1;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ int main(void)
|
|||
|
||||
// The target's height is flipped (in the source Rectangle), due to OpenGL reasons
|
||||
Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };
|
||||
Rectangle destRec = { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) };
|
||||
Rectangle destRec = { (screenWidth - screenWidth/1.25f)/2.0f, (screenHeight - screenHeight/1.25f)/2.0f, screenWidth/1.25f, screenHeight/1.25f };
|
||||
|
||||
Vector2 origin = { 0.0f, 0.0f };
|
||||
|
||||
|
|
@ -61,6 +61,9 @@ int main(void)
|
|||
float cameraX = 0.0f;
|
||||
float cameraY = 0.0f;
|
||||
|
||||
bool smoothOn = true;
|
||||
bool overscan = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -86,6 +89,18 @@ int main(void)
|
|||
worldSpaceCamera.target.y = truncf(screenSpaceCamera.target.y);
|
||||
screenSpaceCamera.target.y -= worldSpaceCamera.target.y;
|
||||
screenSpaceCamera.target.y *= virtualRatio;
|
||||
|
||||
if (IsKeyPressed(KEY_S)) smoothOn = !smoothOn;
|
||||
if (IsKeyPressed(KEY_O)) overscan = !overscan;
|
||||
|
||||
if (overscan)
|
||||
{
|
||||
destRec = (Rectangle) { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) };
|
||||
}
|
||||
else
|
||||
{
|
||||
destRec = (Rectangle) { (screenWidth - screenWidth/1.25f)/2.0f, (screenHeight - screenHeight/1.25f)/2.0f, screenWidth/1.25f, screenHeight/1.25f };
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
@ -101,14 +116,23 @@ int main(void)
|
|||
EndTextureMode();
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RED);
|
||||
ClearBackground(LIGHTGRAY);
|
||||
|
||||
BeginMode2D(screenSpaceCamera);
|
||||
if (smoothOn)
|
||||
{
|
||||
BeginMode2D(screenSpaceCamera);
|
||||
DrawTexturePro(target.texture, sourceRec, destRec, origin, 0.0f, WHITE);
|
||||
EndMode2D();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexturePro(target.texture, sourceRec, destRec, origin, 0.0f, WHITE);
|
||||
EndMode2D();
|
||||
}
|
||||
|
||||
DrawText(TextFormat("Screen resolution: %ix%i", screenWidth, screenHeight), 10, 10, 20, DARKBLUE);
|
||||
DrawText(TextFormat("World resolution: %ix%i", virtualScreenWidth, virtualScreenHeight), 10, 40, 20, DARKGREEN);
|
||||
DrawText(TextFormat("Smooth: %s", (smoothOn ? "ON" : "OFF")), 10, screenHeight - 60, 20, RED);
|
||||
DrawText(TextFormat("Overscan: %s", (overscan ? "ON" : "OFF")), 10, screenHeight - 30, 20, RED);
|
||||
DrawFPS(GetScreenWidth() - 95, 10);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -122,4 +146,4 @@ int main(void)
|
|||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 3.4 KiB |
1422
examples/example_resources.zon
Normal file
1422
examples/example_resources.zon
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -53,13 +53,19 @@ int main(void)
|
|||
Model model = LoadModel("resources/models/gltf/robot.glb"); // Load character model
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model world position
|
||||
|
||||
#if SUPPORT_GPU_SKINNING
|
||||
// WARNING: SUPPORT_GPU_SKINNING is required to be enabled at raylib compile time (disabled by default)
|
||||
// It will skip loading CPU required buffers to store animation updated data, so, both modes are exclusive
|
||||
|
||||
// Load skinning shader
|
||||
// WARNING: It requires SUPPORT_GPU_SKINNING enabled on raylib (disabled by default)
|
||||
// NOTE: It must be a valid shader, following raylib attribs/uniform conventions for GPU skinning
|
||||
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||
|
||||
// Assign skinning shader to all materials shaders
|
||||
//for (int i = 0; i < model.materialCount; i++) model.materials[i].shader = skinningShader;
|
||||
// Skinning shader could be required to be assigned to all materials shaders, just to make
|
||||
// sure required uniforms are being updated for the mesh using that material (and shader)
|
||||
for (int i = 0; i < model.materialCount; i++) model.materials[i].shader = skinningShader;
|
||||
#endif
|
||||
|
||||
// Load model animations
|
||||
int animCount = 0;
|
||||
|
|
@ -244,6 +250,12 @@ int main(void)
|
|||
if (GuiDropdownBox((Rectangle){ GetScreenWidth() - 170.0f, 10, 160, 24 }, TextJoin(animNames, animCount, ";"),
|
||||
&animIndex1, dropdownEditMode1)) dropdownEditMode1 = !dropdownEditMode1;
|
||||
|
||||
GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
|
||||
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize*2);
|
||||
GuiLabel((Rectangle){ 0, GetScreenHeight() - 100.0f, GetScreenWidth(), 40 }, "PRESS SPACE to START BLENDING");
|
||||
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize);
|
||||
GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
||||
|
||||
// Draw playing timeline with keyframes for anim0[]
|
||||
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 60.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 0",
|
||||
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
||||
|
|
@ -269,7 +281,9 @@ int main(void)
|
|||
//--------------------------------------------------------------------------------------
|
||||
UnloadModelAnimations(anims, animCount); // Unload model animation
|
||||
UnloadModel(model); // Unload model and meshes/material
|
||||
#if SUPPORT_GPU_SKINNING
|
||||
UnloadShader(skinningShader); // Unload GPU skinning shader
|
||||
#endif
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -52,12 +52,19 @@ int main(void)
|
|||
Model model = LoadModel("resources/models/gltf/greenman.glb"); // Load character model
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
|
||||
#if SUPPORT_GPU_SKINNING
|
||||
// WARNING: SUPPORT_GPU_SKINNING is required to be enabled at raylib compile time (disabled by default)
|
||||
// It will skip loading CPU required buffers to store animation updated data, so, both modes are exclusive
|
||||
|
||||
// Load skinning shader
|
||||
// WARNING: GPU skinning must be enabled in raylib with a compilation flag,
|
||||
// if not enabled, CPU skinning will be used instead
|
||||
// NOTE: It must be a valid shader, following raylib attribs/uniform conventions for GPU skinning
|
||||
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||
model.materials[1].shader = skinningShader;
|
||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||
|
||||
// Skinning shader could be required to be assigned to all materials shaders, just to make
|
||||
// sure required uniforms are being updated for the mesh using that material (and shader)
|
||||
model.materials[1].shader = skinningShader; // Just assigning to materials[1] for this model
|
||||
#endif
|
||||
|
||||
// Load gltf model animations
|
||||
int animCount = 0;
|
||||
|
|
@ -111,7 +118,9 @@ int main(void)
|
|||
//--------------------------------------------------------------------------------------
|
||||
UnloadModelAnimations(anims, animCount); // Unload model animation
|
||||
UnloadModel(model); // Unload model and meshes/material
|
||||
#if SUPPORT_GPU_SKINNING
|
||||
UnloadShader(skinningShader); // Unload GPU skinning shader
|
||||
#endif
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ int main(void)
|
|||
{
|
||||
// Cast a ray from the screen center (where crosshair would be)
|
||||
Vector2 screenCenter = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||
Ray ray = GetMouseRay(screenCenter, camera);
|
||||
Ray ray = GetScreenToWorldRay(screenCenter, camera);
|
||||
|
||||
// Check ray collision with all voxels
|
||||
float closestDistance = 99999.0f;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "raylib.h"
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) || defined(PLATFORM_DESKTOP_RGFW)
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
#include "glad_gles2.h" // Required for: OpenGL functionality
|
||||
#define glGenVertexArrays glGenVertexArraysOES
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
#include <stdlib.h> // Required for: malloc(), free()
|
||||
#include <math.h> // Required for: hypot()
|
||||
|
||||
|
|
@ -68,6 +70,8 @@ int main(void)
|
|||
Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd
|
||||
|
||||
float gravity = 100; // World gravity
|
||||
|
||||
Vector2 windowPosition = GetWindowPosition();
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
|
@ -128,6 +132,17 @@ int main(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Get window position change for shaking
|
||||
Vector2 windowPositionDelta = Vector2Subtract(windowPosition, GetWindowPosition());
|
||||
|
||||
if (Vector2Length(windowPositionDelta) > 5.0f)
|
||||
{
|
||||
for (int i = 0; i < ballCount; i++)
|
||||
{
|
||||
if (!balls[i].grabbed) balls[i].speed = Vector2Add(balls[i].speed, Vector2Scale(windowPositionDelta, 10.0f));
|
||||
}
|
||||
}
|
||||
|
||||
// Shake balls
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE))
|
||||
{
|
||||
|
|
@ -194,6 +209,8 @@ int main(void)
|
|||
ball->prevPosition = ball->position;
|
||||
}
|
||||
}
|
||||
|
||||
windowPosition = GetWindowPosition();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
@ -222,8 +239,9 @@ int main(void)
|
|||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
RL_FREE(balls);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ int main(void)
|
|||
Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
|
||||
|
||||
// Draw one image over the other with a scaling of 1.5f
|
||||
ImageDraw(&parrots, cat, (Rectangle){ 0, 0, (float)cat.width, (float)cat.height }, (Rectangle){ 30, 40, cat.width*1.5f, cat.height*1.5f }, WHITE);
|
||||
ImageDrawImagePro(&parrots, cat, (Rectangle){ 0, 0, (float)cat.width, (float)cat.height },
|
||||
(Rectangle){ 30, 40, cat.width*1.5f, cat.height*1.5f }, (Vector2){ 0 }, 0.0f, WHITE);
|
||||
ImageCrop(&parrots, (Rectangle){ 0, 50, (float)parrots.width, (float)parrots.height - 100 }); // Crop resulting image
|
||||
|
||||
// Draw on the image with a few image draw methods
|
||||
|
|
|
|||
|
|
@ -1,569 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug.DLL|ARM64">
|
||||
<Configuration>Debug.DLL</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug.DLL|Win32">
|
||||
<Configuration>Debug.DLL</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug.DLL|x64">
|
||||
<Configuration>Debug.DLL</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release.DLL|ARM64">
|
||||
<Configuration>Release.DLL</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release.DLL|Win32">
|
||||
<Configuration>Release.DLL</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release.DLL|x64">
|
||||
<Configuration>Release.DLL</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>web_basic_window</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>web_basic_window</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\others</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||
<Message>Copy Debug DLL to output directory</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||
<Message>Copy Debug DLL to output directory</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||
<Message>Copy Debug DLL to output directory</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Copy Release DLL to output directory</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Copy Release DLL to output directory</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Copy Release DLL to output directory</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\examples\others\web_basic_window.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\..\examples\examples.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\raylib\raylib.vcxproj">
|
||||
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -30,14 +30,22 @@ set(raylib_public_headers
|
|||
|
||||
# Sources to be compiled
|
||||
set(raylib_sources
|
||||
raudio.c
|
||||
rcore.c
|
||||
rmodels.c
|
||||
rshapes.c
|
||||
rtext.c
|
||||
rtextures.c
|
||||
)
|
||||
|
||||
# Only build raudio if it's enabled
|
||||
if (NOT DEFINED SUPPORT_MODULE_RAUDIO OR SUPPORT_MODULE_RAUDIO)
|
||||
list(APPEND raylib_sources raudio.c)
|
||||
endif()
|
||||
|
||||
# Only build rmodels if it's enabled
|
||||
if (NOT DEFINED SUPPORT_MODULE_RMODELS OR SUPPORT_MODULE_RMODELS)
|
||||
list(APPEND raylib_sources rmodels.c)
|
||||
endif()
|
||||
|
||||
# <root>/cmake/GlfwImport.cmake handles the details around the inclusion of glfw
|
||||
if (NOT ${PLATFORM} MATCHES "Web")
|
||||
include(GlfwImport)
|
||||
|
|
@ -48,10 +56,10 @@ endif ()
|
|||
# Produces a variable LIBS_PRIVATE that will be used later
|
||||
include(LibraryConfigurations)
|
||||
|
||||
if (SUPPORT_MODULE_RAUDIO)
|
||||
MESSAGE(STATUS "Audio Backend: miniaudio")
|
||||
else ()
|
||||
if (DEFINED SUPPORT_MODULE_RAUDIO AND NOT SUPPORT_MODULE_RAUDIO)
|
||||
MESSAGE(STATUS "Audio Backend: None (-DCUSTOMIZE_BUILD=ON -DSUPPORT_MODULE_RAUDIO=OFF)")
|
||||
else ()
|
||||
MESSAGE(STATUS "Audio Backend: miniaudio")
|
||||
endif ()
|
||||
|
||||
add_library(raylib ${raylib_sources} ${raylib_public_headers})
|
||||
|
|
|
|||
|
|
@ -240,6 +240,9 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
|
|||
ifeq ($(ANDROID_ARCH),x86_64)
|
||||
ANDROID_COMPILER_ARCH = x86_64
|
||||
endif
|
||||
ifndef ANDROID_COMPILER_ARCH
|
||||
$(error ANDROID_COMPILER_ARCH: Unknown ANDROID_ARCH=$(ANDROID_ARCH))
|
||||
endif
|
||||
endif
|
||||
|
||||
# Define raylib graphics api depending on selected platform
|
||||
|
|
|
|||
24
src/config.h
24
src/config.h
|
|
@ -173,20 +173,22 @@
|
|||
//#define RL_CULL_DISTANCE_FAR 4000.0 // Default projection matrix far cull distance
|
||||
|
||||
// Default shader vertex attribute locations
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES 7
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
|
||||
// NOTE: Locations can be redefined by user if required
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES 7
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM 9
|
||||
|
||||
// Default shader vertex attribute/uniform names to set location points
|
||||
// NOTE: When a new shader is loaded, locations are tried to be set for convenience, looking for the names defined here
|
||||
// In case custom shader names are used, it's up to the user to set locations with GetShaderLocation*() functions
|
||||
// WARNING: Location pre-defined names can not be changed, they are used by default shaders and all raylib examples shaders, they are just listed here for reference
|
||||
// WARNING: In case custom shader names are used, it's up to the user to set locations with GetShaderLocation*() functions
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
|
||||
|
|
@ -196,6 +198,7 @@
|
|||
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
|
||||
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
|
||||
|
||||
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
||||
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
|
||||
|
|
@ -203,6 +206,7 @@
|
|||
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
|
||||
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (tint color, multiplied by texture color)
|
||||
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices
|
||||
|
||||
//#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
||||
//#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
|
||||
//#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
|
||||
|
|
|
|||
4340
src/external/RGFW/RGFW.h
vendored
4340
src/external/RGFW/RGFW.h
vendored
File diff suppressed because it is too large
Load Diff
68
src/external/dr_flac.h
vendored
68
src/external/dr_flac.h
vendored
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
|
||||
dr_flac - v0.13.3 - 2026-01-17
|
||||
dr_flac - v0.13.4 - TBD
|
||||
|
||||
David Reid - mackron@gmail.com
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ extern "C" {
|
|||
|
||||
#define DRFLAC_VERSION_MAJOR 0
|
||||
#define DRFLAC_VERSION_MINOR 13
|
||||
#define DRFLAC_VERSION_REVISION 3
|
||||
#define DRFLAC_VERSION_REVISION 4
|
||||
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
|
||||
|
||||
#include <stddef.h> /* For size_t. */
|
||||
|
|
@ -1547,6 +1547,8 @@ static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
|
|||
#define DRFLAC_ZERO_OBJECT(p) DRFLAC_ZERO_MEMORY((p), sizeof(*(p)))
|
||||
#endif
|
||||
|
||||
#define DRFLAC_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */
|
||||
|
||||
/* Result Codes */
|
||||
|
|
@ -5980,8 +5982,6 @@ static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* p
|
|||
break; /* Failed to seek to FLAC frame. */
|
||||
}
|
||||
} else {
|
||||
const float approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);
|
||||
|
||||
if (pcmRangeLo > pcmFrameIndex) {
|
||||
/* We seeked too far forward. We need to move our target byte backward and try again. */
|
||||
byteRangeHi = lastSuccessfulSeekOffset;
|
||||
|
|
@ -6004,12 +6004,14 @@ static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* p
|
|||
break; /* Failed to seek to FLAC frame. */
|
||||
}
|
||||
} else {
|
||||
const double approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0);
|
||||
|
||||
byteRangeLo = lastSuccessfulSeekOffset;
|
||||
if (byteRangeHi < byteRangeLo) {
|
||||
byteRangeHi = byteRangeLo;
|
||||
}
|
||||
|
||||
targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);
|
||||
targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0) * approxCompressionRatio);
|
||||
if (targetByte > byteRangeHi) {
|
||||
targetByte = byteRangeHi;
|
||||
}
|
||||
|
|
@ -6402,7 +6404,7 @@ static void* drflac__realloc_from_callbacks(void* p, size_t szNew, size_t szOld,
|
|||
}
|
||||
|
||||
if (p != NULL) {
|
||||
DRFLAC_COPY_MEMORY(p2, p, szOld);
|
||||
DRFLAC_COPY_MEMORY(p2, p, DRFLAC_MIN(szNew, szOld));
|
||||
pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
|
||||
}
|
||||
|
||||
|
|
@ -6430,11 +6432,22 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||
We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that
|
||||
we'll be sitting on byte 42.
|
||||
*/
|
||||
drflac_uint64 runningFilePos = 42;
|
||||
drflac_uint64 seektablePos = 0;
|
||||
drflac_uint32 seektableSize = 0;
|
||||
drflac_uint64 runningFilePos = 42;
|
||||
drflac_uint64 seektablePos = 0;
|
||||
drflac_uint32 seektableSize = 0;
|
||||
drflac_int64 fileSize = 0;
|
||||
drflac_bool32 hasKnownFileSize = DRFLAC_FALSE;
|
||||
|
||||
(void)onTell;
|
||||
/* We'll be doing some memory allocations here against untrusted data. We'll do a basic validation check that they don't exceed the size of the file. */
|
||||
if (onTell != NULL && onSeek != NULL) {
|
||||
if (onSeek(pUserData, 0, DRFLAC_SEEK_END)) {
|
||||
if (onTell(pUserData, &fileSize)) {
|
||||
hasKnownFileSize = DRFLAC_TRUE;
|
||||
}
|
||||
|
||||
onSeek(pUserData, runningFilePos, DRFLAC_SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
drflac_metadata metadata;
|
||||
|
|
@ -6444,6 +6457,11 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||
if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
|
||||
return DRFLAC_FALSE;
|
||||
}
|
||||
|
||||
if (hasKnownFileSize && (blockSize > ((drflac_uint64)fileSize - runningFilePos))) {
|
||||
return DRFLAC_FALSE; /* Block size exceeds the size of the file. */
|
||||
}
|
||||
|
||||
runningFilePos += 4;
|
||||
|
||||
metadata.type = blockType;
|
||||
|
|
@ -6559,7 +6577,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
|
||||
return DRFLAC_FALSE;
|
||||
}
|
||||
metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
|
||||
metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
|
||||
metadata.data.vorbis_comment.commentCount = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
||||
|
||||
/* Need space for 'commentCount' comments after the block, which at minimum is a drflac_uint32 per comment */
|
||||
|
|
@ -6747,13 +6765,18 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||
blockSizeRemaining -= 4;
|
||||
metadata.data.picture.mimeLength = drflac__be2host_32(metadata.data.picture.mimeLength);
|
||||
|
||||
if (blockSizeRemaining < metadata.data.picture.mimeLength) {
|
||||
result = DRFLAC_FALSE;
|
||||
goto done_flac;
|
||||
}
|
||||
|
||||
pMime = (char*)drflac__malloc_from_callbacks(metadata.data.picture.mimeLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
|
||||
if (pMime == NULL) {
|
||||
result = DRFLAC_FALSE;
|
||||
goto done_flac;
|
||||
}
|
||||
|
||||
if (blockSizeRemaining < metadata.data.picture.mimeLength || onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) {
|
||||
if (onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) {
|
||||
result = DRFLAC_FALSE;
|
||||
goto done_flac;
|
||||
}
|
||||
|
|
@ -6769,13 +6792,18 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||
blockSizeRemaining -= 4;
|
||||
metadata.data.picture.descriptionLength = drflac__be2host_32(metadata.data.picture.descriptionLength);
|
||||
|
||||
if (blockSizeRemaining < metadata.data.picture.descriptionLength) {
|
||||
result = DRFLAC_FALSE;
|
||||
goto done_flac;
|
||||
}
|
||||
|
||||
pDescription = (char*)drflac__malloc_from_callbacks(metadata.data.picture.descriptionLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
|
||||
if (pDescription == NULL) {
|
||||
result = DRFLAC_FALSE;
|
||||
goto done_flac;
|
||||
}
|
||||
|
||||
if (blockSizeRemaining < metadata.data.picture.descriptionLength || onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) {
|
||||
if (onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) {
|
||||
result = DRFLAC_FALSE;
|
||||
goto done_flac;
|
||||
}
|
||||
|
|
@ -8094,11 +8122,17 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if ((0xFFFFFFFF - (seekpointCount * sizeof(drflac_seekpoint))) < allocationSize) {
|
||||
#ifndef DR_FLAC_NO_OGG
|
||||
drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
allocationSize += seekpointCount * sizeof(drflac_seekpoint);
|
||||
}
|
||||
|
||||
|
||||
pFlac = (drflac*)drflac__malloc_from_callbacks(allocationSize, &allocationCallbacks);
|
||||
pFlac = (drflac*)drflac__malloc_from_callbacks((size_t)allocationSize, &allocationCallbacks);
|
||||
if (pFlac == NULL) {
|
||||
#ifndef DR_FLAC_NO_OGG
|
||||
drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
|
||||
|
|
@ -12169,6 +12203,10 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
|
|||
/*
|
||||
REVISION HISTORY
|
||||
================
|
||||
v0.13.4 - TBD
|
||||
- Add a bounds check when allocating memory during metadata processing.
|
||||
- Fix a possible overflow error when parsing picture metadata.
|
||||
|
||||
v0.13.3 - 2026-01-17
|
||||
- Fix a compiler compatibility issue with some inlined assembly.
|
||||
- Fix a compilation warning.
|
||||
|
|
|
|||
61
src/external/dr_mp3.h
vendored
61
src/external/dr_mp3.h
vendored
|
|
@ -3188,6 +3188,10 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
|
|||
pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8);
|
||||
pTagData = pTagDataBeg;
|
||||
|
||||
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 8) {
|
||||
goto done_xing_info; /* Frame too small for a Xing/Info tag. */
|
||||
}
|
||||
|
||||
/* Check for both "Xing" and "Info" identifiers. */
|
||||
isXing = (pTagData[0] == 'X' && pTagData[1] == 'i' && pTagData[2] == 'n' && pTagData[3] == 'g');
|
||||
isInfo = (pTagData[0] == 'I' && pTagData[1] == 'n' && pTagData[2] == 'f' && pTagData[3] == 'o');
|
||||
|
|
@ -3199,42 +3203,60 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
|
|||
pTagData += 8; /* Skip past the ID and flags. */
|
||||
|
||||
if (flags & 0x01) { /* FRAMES flag. */
|
||||
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) {
|
||||
goto done_xing_info; /* Invalid Xing/Info tag. */
|
||||
}
|
||||
|
||||
detectedMP3FrameCount = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3];
|
||||
pTagData += 4;
|
||||
}
|
||||
|
||||
if (flags & 0x02) { /* BYTES flag. */
|
||||
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) {
|
||||
goto done_xing_info; /* Invalid Xing/Info tag. */
|
||||
}
|
||||
|
||||
bytes = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3];
|
||||
(void)bytes; /* <-- Just to silence a warning about `bytes` being assigned but unused. Want to leave this here in case I want to make use of it later. */
|
||||
pTagData += 4;
|
||||
}
|
||||
|
||||
if (flags & 0x04) { /* TOC flag. */
|
||||
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 100) {
|
||||
goto done_xing_info; /* Invalid Xing/Info tag. */
|
||||
}
|
||||
|
||||
/* TODO: Extract and bind seek points. */
|
||||
pTagData += 100;
|
||||
}
|
||||
|
||||
if (flags & 0x08) { /* SCALE flag. */
|
||||
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) {
|
||||
goto done_xing_info; /* Invalid Xing/Info tag. */
|
||||
}
|
||||
|
||||
pTagData += 4;
|
||||
}
|
||||
|
||||
/* At this point we're done with the Xing/Info header. Now we can look at the LAME data. */
|
||||
if (pTagData[0]) {
|
||||
int delayInPCMFrames;
|
||||
int paddingInPCMFrames;
|
||||
|
||||
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 36) {
|
||||
goto done_xing_info; /* Invalid Xing/Info tag. */
|
||||
}
|
||||
|
||||
pTagData += 21;
|
||||
|
||||
if (pTagData - pFirstFrameData + 14 < firstFrameInfo.frame_bytes) {
|
||||
int delayInPCMFrames;
|
||||
int paddingInPCMFrames;
|
||||
|
||||
delayInPCMFrames = (( (drmp3_uint32)pTagData[0] << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1);
|
||||
paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 0xF) << 8) | ((drmp3_uint32)pTagData[2] )) - (528 + 1);
|
||||
if (paddingInPCMFrames < 0) {
|
||||
paddingInPCMFrames = 0; /* Padding cannot be negative. Probably a malformed file. Ignore. */
|
||||
}
|
||||
|
||||
pMP3->delayInPCMFrames = (drmp3_uint32)delayInPCMFrames;
|
||||
pMP3->paddingInPCMFrames = (drmp3_uint32)paddingInPCMFrames;
|
||||
delayInPCMFrames = (( (drmp3_uint32)pTagData[0] << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1);
|
||||
paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 0xF) << 8) | ((drmp3_uint32)pTagData[2] )) - (528 + 1);
|
||||
if (paddingInPCMFrames < 0) {
|
||||
paddingInPCMFrames = 0; /* Padding cannot be negative. Probably a malformed file. Ignore. */
|
||||
}
|
||||
|
||||
pMP3->delayInPCMFrames = (drmp3_uint32)delayInPCMFrames;
|
||||
pMP3->paddingInPCMFrames = (drmp3_uint32)paddingInPCMFrames;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3273,6 +3295,8 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
|
|||
*/
|
||||
drmp3dec_init(&pMP3->decoder);
|
||||
}
|
||||
|
||||
done_xing_info:;
|
||||
} else {
|
||||
/* Failed to read the side info. */
|
||||
}
|
||||
|
|
@ -3285,7 +3309,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
|
|||
}
|
||||
|
||||
if (detectedMP3FrameCount != 0xFFFFFFFF) {
|
||||
pMP3->totalPCMFrameCount = detectedMP3FrameCount * firstFramePCMFrameCount;
|
||||
pMP3->totalPCMFrameCount = (drmp3_uint64)detectedMP3FrameCount * firstFramePCMFrameCount;
|
||||
}
|
||||
|
||||
pMP3->channels = pMP3->mp3FrameChannels;
|
||||
|
|
@ -4247,7 +4271,7 @@ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 frame
|
|||
#else
|
||||
/* Slow path. Convert from s16 to f32. */
|
||||
{
|
||||
drmp3_int16 pTempS16[8192];
|
||||
drmp3_int16 pTempS16[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
|
||||
drmp3_uint64 totalPCMFramesRead = 0;
|
||||
|
||||
while (totalPCMFramesRead < framesToRead) {
|
||||
|
|
@ -4284,7 +4308,7 @@ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 frame
|
|||
#else
|
||||
/* Slow path. Convert from f32 to s16. */
|
||||
{
|
||||
float pTempF32[4096];
|
||||
float pTempF32[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
|
||||
drmp3_uint64 totalPCMFramesRead = 0;
|
||||
|
||||
while (totalPCMFramesRead < framesToRead) {
|
||||
|
|
@ -4772,7 +4796,7 @@ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig,
|
|||
drmp3_uint64 totalFramesRead = 0;
|
||||
drmp3_uint64 framesCapacity = 0;
|
||||
float* pFrames = NULL;
|
||||
float temp[4096];
|
||||
float temp[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
|
||||
|
||||
DRMP3_ASSERT(pMP3 != NULL);
|
||||
|
||||
|
|
@ -4841,7 +4865,7 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC
|
|||
drmp3_uint64 totalFramesRead = 0;
|
||||
drmp3_uint64 framesCapacity = 0;
|
||||
drmp3_int16* pFrames = NULL;
|
||||
drmp3_int16 temp[4096];
|
||||
drmp3_int16 temp[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
|
||||
|
||||
DRMP3_ASSERT(pMP3 != NULL);
|
||||
|
||||
|
|
@ -5010,6 +5034,9 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3
|
|||
REVISION HISTORY
|
||||
================
|
||||
v0.7.4 - TBD
|
||||
- Fix an overflow error with "Xing" and "Info" tag parsing.
|
||||
- Add some validation checks for "Xing" and "Info" tag parsing.
|
||||
- Reduce size of some stack allocations.
|
||||
- Improvements to SIMD detection.
|
||||
|
||||
v0.7.3 - 2026-01-17
|
||||
|
|
|
|||
63
src/external/dr_wav.h
vendored
63
src/external/dr_wav.h
vendored
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file.
|
||||
dr_wav - v0.14.5 - 2026-03-03
|
||||
dr_wav - v0.14.6 - TBD
|
||||
|
||||
David Reid - mackron@gmail.com
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ extern "C" {
|
|||
|
||||
#define DRWAV_VERSION_MAJOR 0
|
||||
#define DRWAV_VERSION_MINOR 14
|
||||
#define DRWAV_VERSION_REVISION 5
|
||||
#define DRWAV_VERSION_REVISION 6
|
||||
#define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION)
|
||||
|
||||
#include <stddef.h> /* For size_t. */
|
||||
|
|
@ -1971,7 +1971,15 @@ DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void
|
|||
return DRWAV_INVALID_FILE;
|
||||
}
|
||||
|
||||
pHeaderOut->sizeInBytes = drwav_bytes_to_u64(sizeInBytes) - 24; /* <-- Subtract 24 because w64 includes the size of the header. */
|
||||
pHeaderOut->sizeInBytes = drwav_bytes_to_u64(sizeInBytes);
|
||||
|
||||
/* Subtract 24 from the size because with w64 the reported chunk size includes the size of the header itself. */
|
||||
if (pHeaderOut->sizeInBytes >= 24) {
|
||||
pHeaderOut->sizeInBytes -= 24;
|
||||
} else {
|
||||
return DRWAV_INVALID_FILE;
|
||||
}
|
||||
|
||||
pHeaderOut->paddingSize = drwav__chunk_padding_size_w64(pHeaderOut->sizeInBytes);
|
||||
*pRunningBytesReadOut += 24;
|
||||
} else {
|
||||
|
|
@ -2201,7 +2209,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_pars
|
|||
so it's consistent with how we do it in the first stage.
|
||||
*/
|
||||
loopCount = drwav_bytes_to_u32(smplHeaderData + 28);
|
||||
calculatedLoopCount = (pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES;
|
||||
calculatedLoopCount = (drwav_uint32)((pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES);
|
||||
if (loopCount != calculatedLoopCount) {
|
||||
return totalBytesRead;
|
||||
}
|
||||
|
|
@ -2580,8 +2588,10 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_bext_to_metadata_obj(drwav__metadata_pars
|
|||
pMetadata->data.bext.pCodingHistory = (char*)drwav__metadata_get_memory(pParser, extraBytes + 1, 1);
|
||||
DRWAV_ASSERT(pMetadata->data.bext.pCodingHistory != NULL);
|
||||
|
||||
bytesRead += drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
|
||||
pMetadata->data.bext.codingHistorySize = (drwav_uint32)drwav__strlen(pMetadata->data.bext.pCodingHistory);
|
||||
pMetadata->data.bext.codingHistorySize = (drwav_uint32)drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
|
||||
pMetadata->data.bext.pCodingHistory[pMetadata->data.bext.codingHistorySize] = '\0'; /* <-- Explicit null terminator in case of a badly formed file. */
|
||||
|
||||
bytesRead += pMetadata->data.bext.codingHistorySize;
|
||||
} else {
|
||||
pMetadata->data.bext.pCodingHistory = NULL;
|
||||
pMetadata->data.bext.codingHistorySize = 0;
|
||||
|
|
@ -2755,10 +2765,10 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
|
|||
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead);
|
||||
if (bytesJustRead == sizeof(buffer)) {
|
||||
drwav_uint32 loopCount = drwav_bytes_to_u32(buffer);
|
||||
drwav_uint64 calculatedLoopCount;
|
||||
drwav_uint32 calculatedLoopCount;
|
||||
|
||||
/* The loop count must be validated against the size of the chunk. */
|
||||
calculatedLoopCount = (pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES;
|
||||
calculatedLoopCount = (drwav_uint32)((pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES);
|
||||
if (calculatedLoopCount == loopCount) {
|
||||
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead);
|
||||
if (bytesJustRead == sizeof(buffer)) {
|
||||
|
|
@ -2860,7 +2870,9 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
|
|||
return bytesRead;
|
||||
}
|
||||
allocSizeNeeded += drwav__strlen(buffer) + 1;
|
||||
allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - DRWAV_BEXT_BYTES + 1; /* Coding history. */
|
||||
|
||||
/* Coding history. */
|
||||
allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - DRWAV_BEXT_BYTES + 1;
|
||||
|
||||
drwav__metadata_request_extra_memory_for_stage_2(pParser, allocSizeNeeded, 1);
|
||||
|
||||
|
|
@ -3321,6 +3333,10 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
|
|||
((pWav->container == drwav_container_w64) && drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT))) {
|
||||
drwav_uint8 fmtData[16];
|
||||
|
||||
if (header.sizeInBytes < sizeof(fmtData)) {
|
||||
return DRWAV_FALSE; /* Invalid fmt chunk. */
|
||||
}
|
||||
|
||||
foundChunk_fmt = DRWAV_TRUE;
|
||||
|
||||
if (pWav->onRead(pWav->pUserData, fmtData, sizeof(fmtData)) != sizeof(fmtData)) {
|
||||
|
|
@ -3833,6 +3849,11 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
|
|||
|
||||
/* We decode two samples per byte. There will be blockCount headers in the data chunk. This is enough to know how to calculate the total PCM frame count. */
|
||||
totalBlockHeaderSizeInBytes = blockCount * (6*fmt.channels);
|
||||
if (totalBlockHeaderSizeInBytes >= dataChunkSize) { /* <-- We'll be subtracting totalBlockHeaderSizeInBytes from dataChunkSize next so it must be validated. */
|
||||
drwav_free(pWav->pMetadata, &pWav->allocationCallbacks);
|
||||
return DRWAV_FALSE; /* Invalid file. */
|
||||
}
|
||||
|
||||
pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
|
||||
}
|
||||
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
|
||||
|
|
@ -3846,6 +3867,11 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
|
|||
|
||||
/* We decode two samples per byte. There will be blockCount headers in the data chunk. This is enough to know how to calculate the total PCM frame count. */
|
||||
totalBlockHeaderSizeInBytes = blockCount * (4*fmt.channels);
|
||||
if (totalBlockHeaderSizeInBytes >= dataChunkSize) { /* <-- We'll be subtracting totalBlockHeaderSizeInBytes from dataChunkSize next so it must be validated. */
|
||||
drwav_free(pWav->pMetadata, &pWav->allocationCallbacks);
|
||||
return DRWAV_FALSE; /* Invalid file. */
|
||||
}
|
||||
|
||||
pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
|
||||
|
||||
/* The header includes a decoded sample for each channel which acts as the initial predictor sample. */
|
||||
|
|
@ -6725,6 +6751,10 @@ DRWAV_PRIVATE void drwav__pcm_to_s16(drwav_int16* pOut, const drwav_uint8* pIn,
|
|||
shift += 8;
|
||||
}
|
||||
|
||||
if (!drwav__is_little_endian()) {
|
||||
sample = drwav__bswap64(sample);
|
||||
}
|
||||
|
||||
pIn += j;
|
||||
*pOut++ = (drwav_int16)((drwav_int64)sample >> 48);
|
||||
}
|
||||
|
|
@ -7166,6 +7196,10 @@ DRWAV_PRIVATE void drwav__pcm_to_f32(float* pOut, const drwav_uint8* pIn, size_t
|
|||
shift += 8;
|
||||
}
|
||||
|
||||
if (!drwav__is_little_endian()) {
|
||||
sample = drwav__bswap64(sample);
|
||||
}
|
||||
|
||||
pIn += j;
|
||||
*pOut++ = (float)((drwav_int64)sample / 9223372036854775807.0);
|
||||
}
|
||||
|
|
@ -7650,6 +7684,10 @@ DRWAV_PRIVATE void drwav__pcm_to_s32(drwav_int32* pOut, const drwav_uint8* pIn,
|
|||
shift += 8;
|
||||
}
|
||||
|
||||
if (!drwav__is_little_endian()) {
|
||||
sample = drwav__bswap64(sample);
|
||||
}
|
||||
|
||||
pIn += j;
|
||||
*pOut++ = (drwav_int32)((drwav_int64)sample >> 32);
|
||||
}
|
||||
|
|
@ -8557,6 +8595,13 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b)
|
|||
/*
|
||||
REVISION HISTORY
|
||||
================
|
||||
v0.14.6 - TBD
|
||||
- Fix an error when loading files with a malformed "bext" chunk.
|
||||
- Fix an error when loading files with a malformed "fmt" chunk.
|
||||
- Fix an underflow error with badly formed ADPCM encoded files.
|
||||
- Fix an underflow error with badly formed W64 files.
|
||||
- Fix an error when converting from >32 bit samples to s16/f32/s32 on big-endian architectures.
|
||||
|
||||
v0.14.5 - 2026-03-03
|
||||
- Fix a crash when loading files with a malformed "smpl" chunk.
|
||||
- Fix a signed overflow bug with the MS-ADPCM decoder.
|
||||
|
|
|
|||
4
src/external/jar_mod.h
vendored
4
src/external/jar_mod.h
vendored
|
|
@ -1538,10 +1538,10 @@ mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
|
|||
modctx->modfile = (muchar *) JARMOD_MALLOC(fsize);
|
||||
modctx->modfilesize = fsize;
|
||||
memset(modctx->modfile, 0, fsize);
|
||||
fread(modctx->modfile, fsize, 1, f);
|
||||
if(fread(modctx->modfile, fsize, 1, f) != 1) fsize = 0;
|
||||
fclose(f);
|
||||
|
||||
if(!jar_mod_load(modctx, (void *)modctx->modfile, fsize)) fsize = 0;
|
||||
if(fsize && !jar_mod_load(modctx, (void *)modctx->modfile, fsize)) fsize = 0;
|
||||
} else fsize = 0;
|
||||
}
|
||||
return fsize;
|
||||
|
|
|
|||
4
src/external/miniaudio.h
vendored
4
src/external/miniaudio.h
vendored
|
|
@ -41495,11 +41495,11 @@ Web Audio Backend
|
|||
#ifdef MA_HAS_WEBAUDIO
|
||||
#include <emscripten/emscripten.h>
|
||||
|
||||
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 32)))
|
||||
#if (__EMSCRIPTEN_MAJOR__ > 3) || (__EMSCRIPTEN_MAJOR__ == 3 && (__EMSCRIPTEN_MINOR__ > 1 || (__EMSCRIPTEN_MINOR__ == 1 && __EMSCRIPTEN_TINY__ >= 32)))
|
||||
#include <emscripten/webaudio.h>
|
||||
#define MA_SUPPORT_AUDIO_WORKLETS
|
||||
|
||||
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 70)))
|
||||
#if (__EMSCRIPTEN_MAJOR__ > 3) || (__EMSCRIPTEN_MAJOR__ == 3 && (__EMSCRIPTEN_MINOR__ > 1 || (__EMSCRIPTEN_MINOR__ == 1 && __EMSCRIPTEN_TINY__ >= 70)))
|
||||
#define MA_SUPPORT_AUDIO_WORKLETS_VARIABLE_BUFFER_SIZE
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
338
src/external/rlsw.h
vendored
338
src/external/rlsw.h
vendored
|
|
@ -153,7 +153,7 @@
|
|||
#define SW_MAX_TEXTURES 128
|
||||
#endif
|
||||
|
||||
// Enables the use of a lookup table for uint8_t to float conversion
|
||||
// Enable the use of a lookup table for uint8_t to float conversion
|
||||
// Requires an additional 1KB of global memory
|
||||
// Disabled when SIMD intrinsics are enabled
|
||||
#ifndef SW_USE_COLOR_LUT
|
||||
|
|
@ -164,6 +164,11 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Full NPOT texture support (enabled by default)
|
||||
// When disabled, SW_REPEAT requires POT on its axis (fast bitmask wrap)
|
||||
// SW_CLAMP remains supported for any dimension, per-axis
|
||||
#define SW_SUPPORT_NPOT_TEXTURE true
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// OpenGL Compatibility Types
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -200,6 +205,7 @@ typedef double GLclampd;
|
|||
#define GL_RENDERER 0x1F01
|
||||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||
|
||||
//#define GL_ATTRIB_STACK_DEPTH 0x0BB0
|
||||
//#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
|
||||
|
|
@ -507,6 +513,7 @@ typedef enum {
|
|||
SW_RENDERER = GL_RENDERER,
|
||||
SW_VERSION = GL_VERSION,
|
||||
SW_EXTENSIONS = GL_EXTENSIONS,
|
||||
SW_SHADING_LANGUAGE_VERSION = GL_SHADING_LANGUAGE_VERSION,
|
||||
SW_COLOR_CLEAR_VALUE = GL_COLOR_CLEAR_VALUE,
|
||||
SW_DEPTH_CLEAR_VALUE = GL_DEPTH_CLEAR_VALUE,
|
||||
SW_CURRENT_COLOR = GL_CURRENT_COLOR,
|
||||
|
|
@ -844,6 +851,15 @@ SWAPI void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWatta
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// ESP-DSP acceleration: ESP-IDF ships an optimized math library that includes
|
||||
// `dspm_mult_4x4x4_f32` (4x4 matrix multiply) and `dspm_mult_4x4x1_f32` (matrix * vector)
|
||||
// These are S3-tuned hand-vectorized kernels that beat the scalar versions for both throughput and code-size
|
||||
// Detection is opt-in to keep the dependency optional: define SW_USE_ESP_DSP from your build system
|
||||
#if defined(ESP_PLATFORM) && defined(SW_USE_ESP_DSP)
|
||||
#define SW_HAS_ESP_DSP
|
||||
#include "dspm_mult.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define SW_CURLY_INIT(name) name
|
||||
#else
|
||||
|
|
@ -858,41 +874,41 @@ SWAPI void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWatta
|
|||
#define SW_DEG2RAD (SW_PI/180.0f)
|
||||
#define SW_RAD2DEG (180.0f/SW_PI)
|
||||
|
||||
// When clipping a convex polygon against a plane, at most one vertex is added.
|
||||
// When clipping a convex polygon against a plane, at most one vertex is added
|
||||
// Starting from a quadrilateral (4 vertices), clipped sequentially against
|
||||
// the frustum (6 planes) then the scissor rectangle (4 planes):
|
||||
// 4 + 6 + 4 = 14 vertices maximum.
|
||||
#define SW_MAX_CLIPPED_POLYGON_VERTICES 14
|
||||
#define SW_CLIP_EPSILON 1e-4f
|
||||
// 4 + 6 + 4 = 14 vertices maximum
|
||||
#define SW_MAX_CLIPPED_POLYGON_VERTICES 14
|
||||
#define SW_CLIP_EPSILON 1e-4f
|
||||
|
||||
#define SW_HANDLE_NULL 0u
|
||||
#define SW_POOL_SLOT_LIVE 0x80u // bit7 of the generation byte
|
||||
#define SW_POOL_SLOT_VER_MASK 0x7Fu // bits6:0 = anti-ABA counter
|
||||
#define SW_HANDLE_NULL 0u
|
||||
#define SW_POOL_SLOT_LIVE 0x80u // bit7 of the generation byte
|
||||
#define SW_POOL_SLOT_VER_MASK 0x7Fu // bits6:0 = anti-ABA counter
|
||||
|
||||
#define SW_CONCAT(a, b) a##b
|
||||
#define SW_CONCATX(a, b) SW_CONCAT(a, b)
|
||||
#define SW_CONCAT(a, b) a##b
|
||||
#define SW_CONCATX(a, b) SW_CONCAT(a, b)
|
||||
|
||||
#define SW_FRAMEBUFFER_COLOR8_GET(c,p,o) SW_CONCATX(sw_pixel_read_color8_, SW_FRAMEBUFFER_COLOR_TYPE)((c),(p),(o))
|
||||
#define SW_FRAMEBUFFER_COLOR_GET(c,p,o) SW_CONCATX(sw_pixel_read_color_, SW_FRAMEBUFFER_COLOR_TYPE)((c),(p),(o))
|
||||
#define SW_FRAMEBUFFER_COLOR_SET(p,c,o) SW_CONCATX(sw_pixel_write_color_, SW_FRAMEBUFFER_COLOR_TYPE)((p),(c),(o))
|
||||
#define SW_FRAMEBUFFER_COLOR8_GET(c,p,o) SW_CONCATX(sw_pixel_read_color8_, SW_FRAMEBUFFER_COLOR_TYPE)((c),(p),(o))
|
||||
#define SW_FRAMEBUFFER_COLOR_GET(c,p,o) SW_CONCATX(sw_pixel_read_color_, SW_FRAMEBUFFER_COLOR_TYPE)((c),(p),(o))
|
||||
#define SW_FRAMEBUFFER_COLOR_SET(p,c,o) SW_CONCATX(sw_pixel_write_color_, SW_FRAMEBUFFER_COLOR_TYPE)((p),(c),(o))
|
||||
|
||||
#define SW_FRAMEBUFFER_DEPTH_GET(p,o) SW_CONCATX(sw_pixel_read_depth_, SW_FRAMEBUFFER_DEPTH_TYPE)((p),(o))
|
||||
#define SW_FRAMEBUFFER_DEPTH_SET(p,d,o) SW_CONCATX(sw_pixel_write_depth_, SW_FRAMEBUFFER_DEPTH_TYPE)((p),(d),(o))
|
||||
#define SW_FRAMEBUFFER_DEPTH_GET(p,o) SW_CONCATX(sw_pixel_read_depth_, SW_FRAMEBUFFER_DEPTH_TYPE)((p),(o))
|
||||
#define SW_FRAMEBUFFER_DEPTH_SET(p,d,o) SW_CONCATX(sw_pixel_write_depth_, SW_FRAMEBUFFER_DEPTH_TYPE)((p),(d),(o))
|
||||
|
||||
#define SW_FRAMEBUFFER_COLOR_FORMAT SW_CONCATX(SW_PIXELFORMAT_COLOR_, SW_FRAMEBUFFER_COLOR_TYPE)
|
||||
#define SW_FRAMEBUFFER_DEPTH_FORMAT SW_CONCATX(SW_PIXELFORMAT_DEPTH_, SW_FRAMEBUFFER_DEPTH_TYPE)
|
||||
#define SW_FRAMEBUFFER_COLOR_FORMAT SW_CONCATX(SW_PIXELFORMAT_COLOR_, SW_FRAMEBUFFER_COLOR_TYPE)
|
||||
#define SW_FRAMEBUFFER_DEPTH_FORMAT SW_CONCATX(SW_PIXELFORMAT_DEPTH_, SW_FRAMEBUFFER_DEPTH_TYPE)
|
||||
|
||||
#define SW_FRAMEBUFFER_COLOR_SIZE SW_PIXELFORMAT_SIZE[SW_FRAMEBUFFER_COLOR_FORMAT]
|
||||
#define SW_FRAMEBUFFER_DEPTH_SIZE SW_PIXELFORMAT_SIZE[SW_FRAMEBUFFER_DEPTH_FORMAT]
|
||||
#define SW_FRAMEBUFFER_COLOR_SIZE SW_PIXELFORMAT_SIZE[SW_FRAMEBUFFER_COLOR_FORMAT]
|
||||
#define SW_FRAMEBUFFER_DEPTH_SIZE SW_PIXELFORMAT_SIZE[SW_FRAMEBUFFER_DEPTH_FORMAT]
|
||||
|
||||
#define SW_STATE_SCISSOR_TEST (1 << 0)
|
||||
#define SW_STATE_TEXTURE_2D (1 << 1)
|
||||
#define SW_STATE_DEPTH_TEST (1 << 2)
|
||||
#define SW_STATE_CULL_FACE (1 << 3)
|
||||
#define SW_STATE_BLEND (1 << 4)
|
||||
#define SW_STATE_SCISSOR_TEST (1 << 0)
|
||||
#define SW_STATE_TEXTURE_2D (1 << 1)
|
||||
#define SW_STATE_DEPTH_TEST (1 << 2)
|
||||
#define SW_STATE_CULL_FACE (1 << 3)
|
||||
#define SW_STATE_BLEND (1 << 4)
|
||||
|
||||
#define SW_BLEND_FLAG_NOOP (1 << 0)
|
||||
#define SW_BLEND_FLAG_NEEDS_ALPHA (1 << 1)
|
||||
#define SW_BLEND_FLAG_NOOP (1 << 0)
|
||||
#define SW_BLEND_FLAG_NEEDS_ALPHA (1 << 1)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Types and Structures Definition
|
||||
|
|
@ -1038,6 +1054,9 @@ typedef struct {
|
|||
SWmatrix currentMatrixMode; // Current matrix mode (e.g., sw_MODELVIEW, sw_PROJECTION)
|
||||
sw_matrix_t *currentMatrix; // Pointer to the currently used matrix according to the mode
|
||||
sw_matrix_t matMVP; // Model view projection matrix, calculated and used internally
|
||||
#ifdef SW_HAS_ESP_DSP
|
||||
float matMVP_rm[16]; // Row-major MVP, kept in sync for esp-dsp dspm_mult_4x4x1_f32 vertex transform
|
||||
#endif
|
||||
bool isDirtyMVP; // Indicates if the MVP matrix should be rebuilt
|
||||
|
||||
sw_handle_t boundFramebufferId; // Framebuffer currently bound
|
||||
|
|
@ -1141,6 +1160,14 @@ static inline void sw_matrix_id(sw_matrix_t dst)
|
|||
|
||||
static inline void sw_matrix_mul_rst(float *SW_RESTRICT dst, const float *SW_RESTRICT left, const float *SW_RESTRICT right)
|
||||
{
|
||||
#ifdef SW_HAS_ESP_DSP
|
||||
// dspm_mult_4x4x4_f32 treats its operands as row-major. rlsw stores matrices
|
||||
// column-major, so passing them flat is equivalent to passing transposes:
|
||||
// dspm_mult(L^T, R^T) computes (L^T)*(R^T) = (R*L)^T, written back into a
|
||||
// flat array gives the same bit pattern as the column-major product (R*L)
|
||||
// -- exactly the semantic the scalar fallback below has
|
||||
dspm_mult_4x4x4_f32(left, right, dst);
|
||||
#else
|
||||
float l00 = left[0], l01 = left[1], l02 = left[2], l03 = left[3];
|
||||
float l10 = left[4], l11 = left[5], l12 = left[6], l13 = left[7];
|
||||
float l20 = left[8], l21 = left[9], l22 = left[10], l23 = left[11];
|
||||
|
|
@ -1165,6 +1192,7 @@ static inline void sw_matrix_mul_rst(float *SW_RESTRICT dst, const float *SW_RES
|
|||
dst[7] = l10*right[3] + l11*right[7] + l12*right[11] + l13*right[15];
|
||||
dst[11] = l20*right[3] + l21*right[7] + l22*right[11] + l23*right[15];
|
||||
dst[15] = l30*right[3] + l31*right[7] + l32*right[11] + l33*right[15];
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void sw_matrix_mul(sw_matrix_t dst, const sw_matrix_t left, const sw_matrix_t right)
|
||||
|
|
@ -1210,6 +1238,33 @@ static inline float sw_fract(float x)
|
|||
return (x - floorf(x));
|
||||
}
|
||||
|
||||
// Xtensa architecture optimization
|
||||
// Fast reciprocal: 1-ULP accurate in ~7 instructions using the
|
||||
// hardware `recip0.s` seed + two Newton-Raphson refinement steps
|
||||
// All work stays in FPU registers — no `__divsf3` software call
|
||||
// Hot-path divisions in the rasterizer (span/triangle setup, perspective divide, etc.) call this
|
||||
// On non-Xtensa targets it transparently expands to `1.0f / x`, so generated code is identical to before
|
||||
#if defined(__XTENSA__)
|
||||
__attribute__((always_inline))
|
||||
static inline float sw_rcp(float x)
|
||||
{
|
||||
float result, temp;
|
||||
__asm__(
|
||||
"recip0.s %0, %2\n"
|
||||
"const.s %1, 1\n"
|
||||
"msub.s %1, %2, %0\n"
|
||||
"madd.s %0, %0, %1\n"
|
||||
"const.s %1, 1\n"
|
||||
"msub.s %1, %2, %0\n"
|
||||
"maddn.s %0, %0, %1\n"
|
||||
: "=&f"(result), "=&f"(temp) : "f"(x)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
static inline float sw_rcp(float x) { return 1.0f/x; }
|
||||
#endif
|
||||
|
||||
static inline uint8_t sw_luminance8(const uint8_t *color)
|
||||
{
|
||||
return (uint8_t)((color[0]*77 + color[1]*150 + color[2]*29) >> 8);
|
||||
|
|
@ -2344,6 +2399,14 @@ static inline bool sw_texture_alloc(sw_texture_t *texture, const void *data, int
|
|||
int bpp = SW_PIXELFORMAT_SIZE[format];
|
||||
int newSize = w*h*bpp;
|
||||
|
||||
if (texture->pixels == NULL)
|
||||
{
|
||||
texture->minFilter = SW_NEAREST;
|
||||
texture->magFilter = SW_NEAREST;
|
||||
texture->sWrap = SW_CLAMP;
|
||||
texture->tWrap = SW_CLAMP;
|
||||
}
|
||||
|
||||
if (newSize > texture->allocSz)
|
||||
{
|
||||
void *ptr = SW_REALLOC(texture->pixels, newSize);
|
||||
|
|
@ -2406,20 +2469,27 @@ static inline void sw_texture_free(sw_texture_t *texture)
|
|||
|
||||
static inline void sw_texture_sample_nearest(float *SW_RESTRICT color, const sw_texture_t *SW_RESTRICT tex, float u, float v)
|
||||
{
|
||||
u = (tex->sWrap == SW_REPEAT)? sw_fract(u) : sw_saturate(u);
|
||||
v = (tex->tWrap == SW_REPEAT)? sw_fract(v) : sw_saturate(v);
|
||||
int x, y;
|
||||
|
||||
int x = u*tex->width;
|
||||
int y = v*tex->height;
|
||||
#if SW_SUPPORT_NPOT_TEXTURE
|
||||
if (tex->sWrap == SW_REPEAT) x = (int)(sw_fract(u)*tex->width);
|
||||
else x = (int)(sw_saturate(u)*tex->width);
|
||||
|
||||
if (tex->tWrap == SW_REPEAT) y = (int)(sw_fract(v)*tex->height);
|
||||
else y = (int)(sw_saturate(v)*tex->height);
|
||||
#else
|
||||
if (tex->sWrap == SW_REPEAT) x = (int)(u*tex->width) & tex->wMinus1;
|
||||
else x = (int)(sw_saturate(u)*tex->width);
|
||||
|
||||
if (tex->tWrap == SW_REPEAT) y = (int)(v*tex->height) & tex->hMinus1;
|
||||
else y = (int)(sw_saturate(v)*tex->height);
|
||||
#endif
|
||||
|
||||
tex->readColor(color, tex->pixels, y*tex->width + x);
|
||||
}
|
||||
|
||||
static inline void sw_texture_sample_linear(float *SW_RESTRICT color, const sw_texture_t *SW_RESTRICT tex, float u, float v)
|
||||
{
|
||||
// TODO: With a bit more cleverness the number of operations can
|
||||
// be clearly reduced, but for now it works fine
|
||||
|
||||
float xf = (u*tex->width) - 0.5f;
|
||||
float yf = (v*tex->height) - 0.5f;
|
||||
|
||||
|
|
@ -2432,28 +2502,36 @@ static inline void sw_texture_sample_linear(float *SW_RESTRICT color, const sw_t
|
|||
int x1 = x0 + 1;
|
||||
int y1 = y0 + 1;
|
||||
|
||||
// NOTE: If the textures are POT, avoid the division for SW_REPEAT
|
||||
|
||||
if (tex->sWrap == SW_CLAMP)
|
||||
{
|
||||
x0 = (x0 > tex->wMinus1)? tex->wMinus1 : x0;
|
||||
x1 = (x1 > tex->wMinus1)? tex->wMinus1 : x1;
|
||||
}
|
||||
else
|
||||
if (tex->sWrap == SW_REPEAT)
|
||||
{
|
||||
#if SW_SUPPORT_NPOT_TEXTURE
|
||||
x0 = (x0%tex->width + tex->width)%tex->width;
|
||||
x1 = (x1%tex->width + tex->width)%tex->width;
|
||||
}
|
||||
|
||||
if (tex->tWrap == SW_CLAMP)
|
||||
{
|
||||
y0 = (y0 > tex->hMinus1)? tex->hMinus1 : y0;
|
||||
y1 = (y1 > tex->hMinus1)? tex->hMinus1 : y1;
|
||||
#else
|
||||
x0 = x0 & tex->wMinus1;
|
||||
x1 = x1 & tex->wMinus1;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
x0 = sw_clamp_int(x0, 0, tex->wMinus1);
|
||||
x1 = sw_clamp_int(x1, 0, tex->wMinus1);
|
||||
}
|
||||
|
||||
if (tex->tWrap == SW_REPEAT)
|
||||
{
|
||||
#if SW_SUPPORT_NPOT_TEXTURE
|
||||
y0 = (y0%tex->height + tex->height)%tex->height;
|
||||
y1 = (y1%tex->height + tex->height)%tex->height;
|
||||
#else
|
||||
y0 = y0 & tex->hMinus1;
|
||||
y1 = y1 & tex->hMinus1;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
y0 = sw_clamp_int(y0, 0, tex->hMinus1);
|
||||
y1 = sw_clamp_int(y1, 0, tex->hMinus1);
|
||||
}
|
||||
|
||||
float c00[4], c10[4], c01[4], c11[4];
|
||||
|
|
@ -3366,7 +3444,7 @@ static void sw_triangle_clip_and_project(void)
|
|||
|
||||
// Calculation of the reciprocal of W for normalization
|
||||
// as well as perspective-correct attributes
|
||||
const float wRcp = 1.0f/v->position[3];
|
||||
const float wRcp = sw_rcp(v->position[3]);
|
||||
|
||||
// Division of XYZ coordinates by weight
|
||||
v->position[0] *= wRcp;
|
||||
|
|
@ -3460,8 +3538,8 @@ static inline bool sw_quad_face_culling(void)
|
|||
// winding in the projected space when all w > 0
|
||||
// A value of 0 for sgnArea means P0, P1, P2 are collinear in (x, y, w)
|
||||
// space, which corresponds to a degenerate triangle projection
|
||||
// Such quads might also be degenerate or non-planar. They are typically
|
||||
// not culled by this test (0 < 0 is false, 0 > 0 is false)
|
||||
// Such quads might also be degenerate or non-planar
|
||||
// They are typically not culled by this test (0 < 0 is false, 0 > 0 is false)
|
||||
// and should be handled by the clipper if necessary
|
||||
|
||||
return (RLSW.cullFace == SW_FRONT)? (sgnArea < 0.0f) : (sgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise"
|
||||
|
|
@ -3481,7 +3559,7 @@ static void sw_quad_clip_and_project(void)
|
|||
|
||||
// Calculation of the reciprocal of W for normalization
|
||||
// as well as perspective-correct attributes
|
||||
const float wRcp = 1.0f/v->position[3];
|
||||
const float wRcp = sw_rcp(v->position[3]);
|
||||
|
||||
// Division of XYZ coordinates by weight
|
||||
v->position[0] *= wRcp;
|
||||
|
|
@ -3659,8 +3737,8 @@ static bool sw_line_clip_and_project(sw_vertex_t *v0, sw_vertex_t *v1)
|
|||
if (!sw_line_clip(v0, v1)) return false;
|
||||
|
||||
// Convert clip coordinates to NDC
|
||||
v0->position[3] = 1.0f/v0->position[3];
|
||||
v1->position[3] = 1.0f/v1->position[3];
|
||||
v0->position[3] = sw_rcp(v0->position[3]);
|
||||
v1->position[3] = sw_rcp(v1->position[3]);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
v0->position[i] *= v0->position[3];
|
||||
|
|
@ -3709,7 +3787,7 @@ static bool sw_point_clip_and_project(sw_vertex_t *v)
|
|||
if ((v->position[i] < -v->position[3]) || (v->position[i] > v->position[3])) return false;
|
||||
}
|
||||
|
||||
v->position[3] = 1.0f/v->position[3];
|
||||
v->position[3] = sw_rcp(v->position[3]);
|
||||
v->position[0] *= v->position[3];
|
||||
v->position[1] *= v->position[3];
|
||||
v->position[2] *= v->position[3];
|
||||
|
|
@ -3781,8 +3859,7 @@ static inline void sw_poly_fill_render(uint32_t state)
|
|||
//-------------------------------------------------------------------------------------------
|
||||
static void sw_immediate_begin(SWdraw mode)
|
||||
{
|
||||
// NOTE: Any checks to ensure command recording can start
|
||||
// must be performed before calling this function.
|
||||
// NOTE: Any checks to ensure command recording can start must be performed before calling this function
|
||||
|
||||
// Recalculate the MVP if this is needed
|
||||
if (RLSW.isDirtyMVP)
|
||||
|
|
@ -3791,6 +3868,19 @@ static void sw_immediate_begin(SWdraw mode)
|
|||
RLSW.stackModelview[RLSW.stackModelviewCounter - 1],
|
||||
RLSW.stackProjection[RLSW.stackProjectionCounter - 1]);
|
||||
|
||||
#ifdef SW_HAS_ESP_DSP
|
||||
// Pre-transpose to row-major so dspm_mult_4x4x1_f32(matMVP_rm, v, out)
|
||||
// computes M*v directly in the per-vertex hot path; 16 scalar copies
|
||||
// per MVP update vs saving ~20 cycles per vertex transform
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
RLSW.matMVP_rm[4*i + j] = RLSW.matMVP[4*j + i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
RLSW.isDirtyMVP = false;
|
||||
}
|
||||
|
||||
|
|
@ -3842,11 +3932,17 @@ static void sw_immediate_push_vertex(const float position[4])
|
|||
sw_vertex_t *vertex = &RLSW.primitive.buffer[RLSW.primitive.vertexCount++];
|
||||
|
||||
// Calculate clip coordinates
|
||||
#ifdef SW_HAS_ESP_DSP
|
||||
// dspm_mult_4x4x1_f32 declares its inputs non-const; rlsw treats them as
|
||||
// read-only and the cast is safe (the kernel only loads from B)
|
||||
dspm_mult_4x4x1_f32(RLSW.matMVP_rm, (float *)position, vertex->position);
|
||||
#else
|
||||
const float *m = RLSW.matMVP;
|
||||
vertex->position[0] = m[0]*position[0] + m[4]*position[1] + m[8]*position[2] + m[12]*position[3];
|
||||
vertex->position[1] = m[1]*position[0] + m[5]*position[1] + m[9]*position[2] + m[13]*position[3];
|
||||
vertex->position[2] = m[2]*position[0] + m[6]*position[1] + m[10]*position[2] + m[14]*position[3];
|
||||
vertex->position[3] = m[3]*position[0] + m[7]*position[1] + m[11]*position[2] + m[15]*position[3];
|
||||
#endif
|
||||
|
||||
// Copy the attributes in the current vertex
|
||||
for (int i = 0; i < 4; i++) vertex->color[i] = RLSW.primitive.color[i];
|
||||
|
|
@ -4164,6 +4260,7 @@ const char *swGetString(SWget name)
|
|||
case SW_RENDERER: result = "RLSW OpenGL Software Renderer"; break;
|
||||
case SW_VERSION: result = RLSW_VERSION; break;
|
||||
case SW_EXTENSIONS: result = "None"; break;
|
||||
case SW_SHADING_LANGUAGE_VERSION: result = "Not supported"; break;
|
||||
default: RLSW.errCode = SW_INVALID_ENUM; break;
|
||||
}
|
||||
|
||||
|
|
@ -5073,11 +5170,25 @@ void swTexParameteri(int param, int value)
|
|||
case SW_TEXTURE_WRAP_S:
|
||||
{
|
||||
if (!sw_is_texture_wrap_valid(value)) { RLSW.errCode = SW_INVALID_ENUM; return; }
|
||||
#if !SW_SUPPORT_NPOT_TEXTURE
|
||||
if (value == SW_REPEAT && (RLSW.boundTexture->width & RLSW.boundTexture->wMinus1) != 0)
|
||||
{
|
||||
RLSW.errCode = SW_INVALID_OPERATION;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
RLSW.boundTexture->sWrap = (SWwrap)value;
|
||||
} break;
|
||||
case SW_TEXTURE_WRAP_T:
|
||||
{
|
||||
if (!sw_is_texture_wrap_valid(value)) { RLSW.errCode = SW_INVALID_ENUM; return; }
|
||||
#if !SW_SUPPORT_NPOT_TEXTURE
|
||||
if (value == SW_REPEAT && (RLSW.boundTexture->height & RLSW.boundTexture->hMinus1) != 0)
|
||||
{
|
||||
RLSW.errCode = SW_INVALID_OPERATION;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
RLSW.boundTexture->tWrap = (SWwrap)value;
|
||||
} break;
|
||||
default: RLSW.errCode = SW_INVALID_ENUM; break;
|
||||
|
|
@ -5271,8 +5382,18 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
int xEnd = (int)end->position[0];
|
||||
if (xStart == xEnd) return;
|
||||
|
||||
// Intercept the span bounds to ensure to not write before the framebuffer
|
||||
int xLoopStart = (xStart >= 0)? xStart : 0;
|
||||
int xLoopEnd = (xEnd <= RLSW.colorBuffer->width)? xEnd : RLSW.colorBuffer->width;
|
||||
if (xLoopStart >= xLoopEnd) return; // Nothing to draw
|
||||
|
||||
// Get the current row and skip if outside the framebuffer
|
||||
// Maybe this check is better suited elsewhere?
|
||||
int y = (int)start->position[1];
|
||||
if (y < 0 || y >= RLSW.colorBuffer->height) return;
|
||||
|
||||
// Compute the inverse horizontal distance along the X axis
|
||||
float dxRcp = 1.0f/(end->position[0] - start->position[0]);
|
||||
float dxRcp = sw_rcp(end->position[0] - start->position[0]);
|
||||
|
||||
// Compute the interpolation steps along the X axis
|
||||
float dWdx = (end->position[3] - start->position[3])*dxRcp;
|
||||
|
|
@ -5291,27 +5412,29 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
#endif
|
||||
|
||||
// Compute the subpixel distance to traverse before the first pixel
|
||||
// Also step further into them to move away from the colorbuffer edge
|
||||
float xSubstep = 1.0f - sw_fract(start->position[0]);
|
||||
float dxStart = (float)(xLoopStart - xStart);
|
||||
float xOffset = xSubstep + dxStart;
|
||||
|
||||
// Initializing the interpolation starting values
|
||||
float w = start->position[3] + dWdx*xSubstep;
|
||||
float w = start->position[3] + dWdx*xOffset;
|
||||
float color[4] = {
|
||||
start->color[0] + dCdx[0]*xSubstep,
|
||||
start->color[1] + dCdx[1]*xSubstep,
|
||||
start->color[2] + dCdx[2]*xSubstep,
|
||||
start->color[3] + dCdx[3]*xSubstep
|
||||
start->color[0] + dCdx[0]*xOffset,
|
||||
start->color[1] + dCdx[1]*xOffset,
|
||||
start->color[2] + dCdx[2]*xOffset,
|
||||
start->color[3] + dCdx[3]*xOffset
|
||||
};
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
float z = start->position[2] + dZdx*xSubstep;
|
||||
float z = start->position[2] + dZdx*xOffset;
|
||||
#endif
|
||||
#ifdef SW_ENABLE_TEXTURE
|
||||
float u = start->texcoord[0] + dUdx*xSubstep;
|
||||
float v = start->texcoord[1] + dVdx*xSubstep;
|
||||
float u = start->texcoord[0] + dUdx*xOffset;
|
||||
float v = start->texcoord[1] + dVdx*xOffset;
|
||||
#endif
|
||||
|
||||
// Pre-calculate the starting pointers for the framebuffer row
|
||||
int y = (int)start->position[1];
|
||||
int baseOffset = y*RLSW.colorBuffer->width + xStart;
|
||||
int baseOffset = y*RLSW.colorBuffer->width + xLoopStart;
|
||||
uint8_t *cPtr = (uint8_t *)(RLSW.colorBuffer->pixels) + baseOffset*SW_FRAMEBUFFER_COLOR_SIZE;
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
uint8_t *dPtr = (uint8_t *)(RLSW.depthBuffer->pixels) + baseOffset*SW_FRAMEBUFFER_DEPTH_SIZE;
|
||||
|
|
@ -5319,19 +5442,19 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
|
||||
#define SW_AFFINE_BLOCK 16
|
||||
|
||||
int x = xStart;
|
||||
while (x < xEnd)
|
||||
int x = xLoopStart;
|
||||
while (x < xLoopEnd)
|
||||
{
|
||||
// Clamp last block to remaining pixels
|
||||
int blockEnd = x + SW_AFFINE_BLOCK;
|
||||
if (blockEnd > xEnd) blockEnd = xEnd;
|
||||
if (blockEnd > xLoopEnd) blockEnd = xLoopEnd;
|
||||
float blockLenF = (float)(blockEnd - x);
|
||||
float blockLenRcp = 1.0f/blockLenF;
|
||||
float blockLenRcp = sw_rcp(blockLenF);
|
||||
|
||||
// Only 2 '1/w' here; none inside the pixel loop
|
||||
float wRcpA = 1.0f/w;
|
||||
float wRcpA = sw_rcp(w);
|
||||
float wB = w + dWdx*blockLenF;
|
||||
float wRcpB = 1.0f/wB;
|
||||
float wRcpB = sw_rcp(wB);
|
||||
|
||||
// Perspective-correct color at both block endpoints, then affine gradient
|
||||
float srcColor[4] = {
|
||||
|
|
@ -5402,7 +5525,9 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
discard:
|
||||
#endif
|
||||
srcColor[0] += dSrcColordx[0];
|
||||
srcColor[1] += dSrcColordx[1];
|
||||
srcColor[2] += dSrcColordx[2];
|
||||
|
|
@ -5446,10 +5571,10 @@ static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, con
|
|||
if (v1->position[1] > v2->position[1]) { const sw_vertex_t *tmp = v1; v1 = v2; v2 = tmp; }
|
||||
if (v0->position[1] > v1->position[1]) { const sw_vertex_t *tmp = v0; v0 = v1; v1 = tmp; }
|
||||
|
||||
// Extracting coordinates from the sorted vertices
|
||||
float x0 = v0->position[0], y0 = v0->position[1];
|
||||
float x1 = v1->position[0], y1 = v1->position[1];
|
||||
float x2 = v2->position[0], y2 = v2->position[1];
|
||||
// Extracting Y coordinates from the sorted vertices
|
||||
float y0 = v0->position[1];
|
||||
float y1 = v1->position[1];
|
||||
float y2 = v2->position[1];
|
||||
|
||||
// Compute height differences
|
||||
float h02 = y2 - y0;
|
||||
|
|
@ -5459,9 +5584,9 @@ static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, con
|
|||
if (h02 < 1e-6f) return;
|
||||
|
||||
// Inverse edge dy for per-edge dV/dy (scanline interpolation)
|
||||
float h02Rcp = 1.0f/h02;
|
||||
float h01Rcp = (h01 > 1e-6f)? 1.0f/h01 : 0.0f;
|
||||
float h12Rcp = (h12 > 1e-6f)? 1.0f/h12 : 0.0f;
|
||||
float h02Rcp = sw_rcp(h02);
|
||||
float h01Rcp = (h01 > 1e-6f)? sw_rcp(h01) : 0.0f;
|
||||
float h12Rcp = (h12 > 1e-6f)? sw_rcp(h12) : 0.0f;
|
||||
|
||||
// Compute gradients for each side of the triangle
|
||||
sw_vertex_t dVXdy02, dVXdy01, dVXdy12;
|
||||
|
|
@ -5556,12 +5681,20 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
int xMax = (int)br->position[0];
|
||||
int yMax = (int)br->position[1];
|
||||
|
||||
// Exit early if no pixels to draw. Use these later for loop boundaries
|
||||
int yLoopMin = (yMin >= 0)? yMin : 0;
|
||||
int xLoopMin = (xMin >= 0)? xMin : 0;
|
||||
int yLoopMax = (yMax <= RLSW.colorBuffer->height)? yMax : RLSW.colorBuffer->height;
|
||||
int xLoopMax = (xMax <= RLSW.colorBuffer->width)? xMax : RLSW.colorBuffer->width;
|
||||
|
||||
if (yLoopMin >= yLoopMax || xLoopMin >= xLoopMax) return;
|
||||
|
||||
float w = (float)(xMax - xMin);
|
||||
float h = (float)(yMax - yMin);
|
||||
if ((w <= 0) || (h <= 0)) return;
|
||||
|
||||
float wRcp = 1.0f/w;
|
||||
float hRcp = 1.0f/h;
|
||||
float wRcp = sw_rcp(w);
|
||||
float hRcp = sw_rcp(h);
|
||||
|
||||
// Subpixel corrections
|
||||
float xSubstep = 1.0f - sw_fract(tl->position[0]);
|
||||
|
|
@ -5609,21 +5742,44 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
uint8_t *dPixels = RLSW.depthBuffer->pixels;
|
||||
#endif
|
||||
|
||||
for (int y = yMin; y < yMax; y++)
|
||||
// Calculate the distance the in-bounds boundary is from the quad's edges, only on the left and top
|
||||
float dxMin = (float)(xLoopMin - xMin);
|
||||
float dyMin = (float)(yLoopMin - yMin);
|
||||
|
||||
// Correct our start by how far it's clipped outside the framebuffer
|
||||
cRow[0] += dCdx[0]*dxMin + dCdy[0]*dyMin;
|
||||
cRow[1] += dCdx[1]*dxMin + dCdy[1]*dyMin;
|
||||
cRow[2] += dCdx[2]*dxMin + dCdy[2]*dyMin;
|
||||
cRow[3] += dCdx[3]*dxMin + dCdy[3]*dyMin;
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
zRow += dZdy*dyMin + dZdx*dxMin;
|
||||
#endif
|
||||
#ifdef SW_ENABLE_TEXTURE
|
||||
uRow += dUdy*dyMin + dUdx*dxMin;
|
||||
vRow += dVdy*dyMin + dVdx*dxMin;
|
||||
#endif
|
||||
|
||||
for (int y = yLoopMin; y < yLoopMax; y++)
|
||||
{
|
||||
int baseOffset = y*stride + xMin;
|
||||
int baseOffset = y*stride + xLoopMin;
|
||||
uint8_t *cPtr = cPixels + baseOffset*SW_FRAMEBUFFER_COLOR_SIZE;
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
uint8_t *dPtr = dPixels + baseOffset*SW_FRAMEBUFFER_DEPTH_SIZE;
|
||||
// Copy the cursors without destroying the offset maths
|
||||
float z = zRow;
|
||||
#endif
|
||||
#ifdef SW_ENABLE_TEXTURE
|
||||
float u = uRow;
|
||||
float v = vRow;
|
||||
#endif
|
||||
float color[4] = { cRow[0], cRow[1], cRow[2], cRow[3] };
|
||||
float color[4] = {
|
||||
cRow[0],
|
||||
cRow[1],
|
||||
cRow[2],
|
||||
cRow[3]
|
||||
};
|
||||
|
||||
for (int x = xMin; x < xMax; x++)
|
||||
for (int x = xLoopMin; x < xLoopMax; x++)
|
||||
{
|
||||
float srcColor[4] = { color[0], color[1], color[2], color[3] };
|
||||
|
||||
|
|
@ -5659,7 +5815,10 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
discard:
|
||||
#endif
|
||||
// Move one pixel over without touching the original "start offset"
|
||||
color[0] += dCdx[0];
|
||||
color[1] += dCdx[1];
|
||||
color[2] += dCdx[2];
|
||||
|
|
@ -5682,6 +5841,9 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
cPtr += SW_FRAMEBUFFER_COLOR_SIZE;
|
||||
}
|
||||
|
||||
// The for loop is clamped to the right side of the screen
|
||||
// However, these cursor start vars are still on the left
|
||||
// That's fine, advancing to the next row
|
||||
cRow[0] += dCdy[0];
|
||||
cRow[1] += dCdy[1];
|
||||
cRow[2] += dCdy[2];
|
||||
|
|
@ -5746,7 +5908,7 @@ static void SW_RASTER_LINE(const sw_vertex_t *v0, const sw_vertex_t *v1)
|
|||
// Compute per pixel increments
|
||||
float xInc = dx/steps;
|
||||
float yInc = dy/steps;
|
||||
float stepRcp = 1.0f/steps;
|
||||
float stepRcp = sw_rcp(steps);
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
float zInc = (v1->position[2] - v0->position[2])*stepRcp;
|
||||
#endif
|
||||
|
|
@ -5812,7 +5974,9 @@ static void SW_RASTER_LINE(const sw_vertex_t *v0, const sw_vertex_t *v1)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
discard:
|
||||
#endif
|
||||
x += xInc;
|
||||
y += yInc;
|
||||
#ifdef SW_ENABLE_DEPTH_TEST
|
||||
|
|
|
|||
10
src/external/rprand.h
vendored
10
src/external/rprand.h
vendored
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* rprand v1.0 - A simple and easy-to-use pseudo-random numbers generator (PRNG)
|
||||
* rprand v1.1 - A simple and easy-to-use pseudo-random numbers generator (PRNG)
|
||||
*
|
||||
* FEATURES:
|
||||
* - Pseudo-random values generation, 32 bits: [0..4294967295]
|
||||
|
|
@ -118,6 +118,7 @@ extern "C" { // Prevents name mangling of functions
|
|||
//----------------------------------------------------------------------------------
|
||||
RPRANDAPI void rprand_set_seed(unsigned long long seed); // Set rprand_state for Xoshiro128**, seed is 64bit
|
||||
RPRANDAPI int rprand_get_value(int min, int max); // Get random value within a range, min and max included
|
||||
RPRANDAPI int rprand_get_value_raw(void); // Get random value, Xoshiro128** generator (uses global rprand_state)
|
||||
|
||||
RPRANDAPI int *rprand_load_sequence(unsigned int count, int min, int max); // Load pseudo-random numbers sequence with no duplicates
|
||||
RPRANDAPI void rprand_unload_sequence(int *sequence); // Unload pseudo-random numbers sequence
|
||||
|
|
@ -186,6 +187,13 @@ int rprand_get_value(int min, int max)
|
|||
return value;
|
||||
}
|
||||
|
||||
int rprand_get_value_raw(void)
|
||||
{
|
||||
int value = rprand_xoshiro();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Load pseudo-random numbers sequence with no duplicates, min and max included
|
||||
int *rprand_load_sequence(unsigned int count, int min, int max)
|
||||
{
|
||||
|
|
|
|||
12
src/external/win32_clipboard.h
vendored
12
src/external/win32_clipboard.h
vendored
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
#ifndef WIN32_CLIPBOARD_
|
||||
#define WIN32_CLIPBOARD_
|
||||
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize);
|
||||
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned int *dataSize);
|
||||
#endif // WIN32_CLIPBOARD_
|
||||
|
||||
#ifdef WIN32_CLIPBOARD_IMPLEMENTATION
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
// NOTE: These search for architecture is taken from "windows.h", and it's necessary to avoid including windows.h
|
||||
// and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. <minwindef.h>) can cause problems is these are not defined
|
||||
|
|
@ -213,7 +213,7 @@ static int GetPixelDataOffset(BITMAPINFOHEADER bih); // Get pixel data offset fr
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize)
|
||||
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned int *dataSize)
|
||||
{
|
||||
unsigned char *bmpData = NULL;
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
|
|||
*width = bmpInfoHeader->biWidth;
|
||||
*height = bmpInfoHeader->biHeight;
|
||||
SIZE_T clipDataSize = GlobalSize(clipHandle);
|
||||
if (clipDataSize >= sizeof(BITMAPINFOHEADER))
|
||||
if ((clipDataSize >= sizeof(BITMAPINFOHEADER)) && (clipDataSize < INT_MAX))
|
||||
{
|
||||
int pixelOffset = GetPixelDataOffset(*bmpInfoHeader);
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
|
|||
//------------------------------------------------------------------------
|
||||
BITMAPFILEHEADER bmpFileHeader = { 0 };
|
||||
SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize;
|
||||
*dataSize = bmpFileSize;
|
||||
*dataSize = (unsigned int)bmpFileSize;
|
||||
|
||||
bmpFileHeader.bfType = 0x4D42; // BMP fil type constant
|
||||
bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine
|
||||
|
|
@ -254,7 +254,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
|
|||
}
|
||||
else
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "Clipboard data is malformed");
|
||||
TRACELOG(LOG_WARNING, "Clipboard data is not supported (>2GB?)");
|
||||
GlobalUnlock(clipHandle);
|
||||
CloseClipboard();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -473,8 +473,7 @@ void SetWindowFocused(void)
|
|||
// Get native window handle
|
||||
void *GetWindowHandle(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform");
|
||||
return NULL;
|
||||
return (void *)platform.app->window; // Type: ANativeWindow*
|
||||
}
|
||||
|
||||
// Get number of monitors
|
||||
|
|
@ -616,13 +615,13 @@ void ShowCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
// Set cursor position in the middle
|
||||
|
|
@ -656,9 +655,9 @@ double GetTime(void)
|
|||
double time = 0.0;
|
||||
struct timespec ts = { 0 };
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
|
||||
unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
|
||||
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
|
||||
return time;
|
||||
}
|
||||
|
|
@ -1273,27 +1272,28 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
int32_t keycode = AKeyEvent_getKeyCode(event);
|
||||
//int32_t AKeyEvent_getMetaState(event);
|
||||
|
||||
// Handle gamepad button presses and releases
|
||||
// NOTE: Skip gamepad handling if this is a keyboard event, as some devices
|
||||
// report both AINPUT_SOURCE_KEYBOARD and AINPUT_SOURCE_GAMEPAD flags
|
||||
if ((FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) ||
|
||||
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) &&
|
||||
!FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD))
|
||||
// Handle gamepad button presses and releases. AOSP stamps the
|
||||
// KEYBOARD source bit on every key event from a gamepad, so
|
||||
// discriminate on the keycode rather than gating on source bits.
|
||||
if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) ||
|
||||
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD))
|
||||
{
|
||||
// Assuming a single gamepad, "detected" on its input event
|
||||
CORE.Input.Gamepad.ready[0] = true;
|
||||
|
||||
GamepadButton button = AndroidTranslateGamepadButton(keycode);
|
||||
|
||||
if (button == GAMEPAD_BUTTON_UNKNOWN) return 1;
|
||||
|
||||
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
|
||||
if (button != GAMEPAD_BUTTON_UNKNOWN)
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[0][button] = 1;
|
||||
}
|
||||
else CORE.Input.Gamepad.currentButtonState[0][button] = 0; // Key up
|
||||
// Assuming a single gamepad, "detected" on its input event
|
||||
CORE.Input.Gamepad.ready[0] = true;
|
||||
|
||||
return 1; // Handled gamepad button
|
||||
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[0][button] = 1;
|
||||
}
|
||||
else CORE.Input.Gamepad.currentButtonState[0][button] = 0; // Key up
|
||||
|
||||
return 1; // Handled gamepad button
|
||||
}
|
||||
// Unknown keycode: fall through to the keyboard handler below.
|
||||
}
|
||||
|
||||
KeyboardKey key = ((keycode > 0) && (keycode < KEYCODE_MAP_SIZE))? mapKeycode[keycode] : KEY_NULL;
|
||||
|
|
|
|||
|
|
@ -111,6 +111,12 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
GLFWwindow *handle; // GLFW window handle (graphic device)
|
||||
#if defined(__linux__) && defined(_GLFW_X11)
|
||||
// Local storage for the window handle returned by glfwGetX11Window
|
||||
// This is needed as X11 handles are integers and may not fit inside a pointer depending on platform
|
||||
// Storing the handle locally and returning a pointer in GetWindowHandle allows the code to work regardless of pointer width
|
||||
Window windowHandleX11; // Underlying type: unsigned long (XID, Window)
|
||||
#endif
|
||||
} PlatformData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -755,18 +761,13 @@ void SetWindowFocused(void)
|
|||
glfwFocusWindow(platform.handle);
|
||||
}
|
||||
|
||||
#if defined(__linux__) && defined(_GLFW_X11)
|
||||
// Local storage for the window handle returned by glfwGetX11Window
|
||||
// This is needed as X11 handles are integers and may not fit inside a pointer depending on platform
|
||||
// Storing the handle locally and returning a pointer in GetWindowHandle allows the code to work regardless of pointer width
|
||||
static XID X11WindowHandle;
|
||||
#endif
|
||||
// Get native window handle
|
||||
void *GetWindowHandle(void)
|
||||
{
|
||||
void *handle = NULL;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// NOTE: Returned handle is: void *HWND (windows.h)
|
||||
return glfwGetWin32Window(platform.handle);
|
||||
handle = glfwGetWin32Window(platform.handle); // Type: HWND
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
|
|
@ -774,29 +775,27 @@ void *GetWindowHandle(void)
|
|||
int platformID = glfwGetPlatform();
|
||||
if (platformID == GLFW_PLATFORM_WAYLAND)
|
||||
{
|
||||
return glfwGetWaylandWindow(platform.handle);
|
||||
handle = (void *)glfwGetWaylandWindow(platform.handle); // Type: struct wl_surface*
|
||||
}
|
||||
else
|
||||
{
|
||||
X11WindowHandle = glfwGetX11Window(platform.handle);
|
||||
return &X11WindowHandle;
|
||||
platform.windowHandleX11 = glfwGetX11Window(platform.handle); // Type: Window (unsigned long)
|
||||
handle = &platform.windowHandleX11;
|
||||
}
|
||||
#else
|
||||
return glfwGetWaylandWindow(platform.handle);
|
||||
handle = (void *)glfwGetWaylandWindow(platform.handle);
|
||||
#endif
|
||||
#elif defined(_GLFW_X11)
|
||||
// Store the window handle localy and return a pointer to the variable instead
|
||||
// Reasoning detailed in the declaration of X11WindowHandle
|
||||
X11WindowHandle = glfwGetX11Window(platform.handle);
|
||||
return &X11WindowHandle;
|
||||
// Store the window handle locally and return a pointer to the variable instead
|
||||
platform.windowHandleX11 = glfwGetX11Window(platform.handle);
|
||||
handle = &platform.windowHandleX11;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
// NOTE: Returned handle is: (objc_object *)
|
||||
return (void *)glfwGetCocoaWindow(platform.handle);
|
||||
handle = (void *)glfwGetCocoaWindow(platform.handle); // Type: NSWindow*
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
return handle;
|
||||
}
|
||||
|
||||
// Get number of monitors
|
||||
|
|
@ -840,7 +839,7 @@ int GetCurrentMonitor(void)
|
|||
// this is probably an overengineered solution for a side case
|
||||
// trying to match SDL behaviour
|
||||
|
||||
int closestDist = 0x7FFFFFFF;
|
||||
unsigned int closestDist = 0xFFFFFFFFu;
|
||||
|
||||
// Window center position
|
||||
int wcx = 0;
|
||||
|
|
@ -884,7 +883,14 @@ int GetCurrentMonitor(void)
|
|||
|
||||
int dx = wcx - xclosest;
|
||||
int dy = wcy - yclosest;
|
||||
int dist = (dx*dx) + (dy*dy);
|
||||
|
||||
// Unsigned to dodge signed overflow UB; (-x)^2 == x^2 mod 2^32 so sign drops out.
|
||||
// If |dx| or |dy| >= 65536, dist wraps and the wrong monitor may win.
|
||||
// Not a concern for realistic monitor layouts.
|
||||
unsigned int ux = (unsigned int)dx;
|
||||
unsigned int uy = (unsigned int)dy;
|
||||
unsigned int dist = ux*ux + uy*uy;
|
||||
|
||||
if (dist < closestDist)
|
||||
{
|
||||
index = i;
|
||||
|
|
@ -1043,11 +1049,6 @@ const char *GetClipboardText(void)
|
|||
return glfwGetClipboardString(platform.handle);
|
||||
}
|
||||
|
||||
#if SUPPORT_CLIPBOARD_IMAGE && defined(__linux__) && defined(_GLFW_X11)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#endif
|
||||
|
||||
// Get clipboard image
|
||||
Image GetClipboardImage(void)
|
||||
{
|
||||
|
|
@ -1055,43 +1056,42 @@ Image GetClipboardImage(void)
|
|||
|
||||
#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
|
||||
#if defined(_WIN32)
|
||||
unsigned long long int dataSize = 0;
|
||||
|
||||
unsigned int dataSize = 0;
|
||||
void *bmpData = NULL;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
bmpData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
|
||||
bmpData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
|
||||
|
||||
if (bmpData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
|
||||
else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize);
|
||||
|
||||
#elif defined(__linux__) && defined(_GLFW_X11)
|
||||
|
||||
// REF: https://github.com/ColleagueRiley/Clipboard-Copy-Paste/blob/main/x11.c
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
if (!dpy) return image;
|
||||
|
||||
Window root = DefaultRootWindow(dpy);
|
||||
Window win = XCreateSimpleWindow(
|
||||
dpy, // The connection to the X Server
|
||||
root, // The 'Parent' window (usually the desktop/root)
|
||||
0, 0, // X and Y position on the screen
|
||||
1, 1, // Width and Height (1x1 pixel)
|
||||
0, // Border width
|
||||
0, // Border color
|
||||
0 // Background color
|
||||
);
|
||||
static Atom clipboard = 0;
|
||||
static Atom targetType = 0;
|
||||
static Atom property = 0;
|
||||
|
||||
Atom clipboard = XInternAtom(dpy, "CLIPBOARD", False);
|
||||
Atom targetType = XInternAtom(dpy, "image/png", False); // Ask for PNG
|
||||
Atom property = XInternAtom(dpy, "RAYLIB_CLIPBOARD_MANAGER", False);
|
||||
Display *display = glfwGetX11Display();
|
||||
XID window = glfwGetX11Window(platform.handle);
|
||||
|
||||
// Request the data: "Convert whatever is in CLIPBOARD to image/png and put it in RAYLIB_CLIPBOARD_MANAGER"
|
||||
XConvertSelection(dpy, clipboard, targetType, property, win, CurrentTime);
|
||||
// Lazy-load X11 atoms
|
||||
if (clipboard == 0)
|
||||
{
|
||||
clipboard = XInternAtom(display, "CLIPBOARD", False);
|
||||
targetType = XInternAtom(display, "image/png", False);
|
||||
property = XInternAtom(display, "RAYLIB_CLIPBOARD_MANAGER", False);
|
||||
}
|
||||
|
||||
XConvertSelection(display, clipboard, targetType, property, window, CurrentTime);
|
||||
XSync(display, 0);
|
||||
|
||||
// Wait for the SelectionNotify event
|
||||
XEvent ev = { 0 };
|
||||
XNextEvent(dpy, &ev);
|
||||
|
||||
// Keep calling until we get SelectionNotify
|
||||
while (XCheckTypedEvent(display, SelectionNotify, &ev) == False);
|
||||
|
||||
Atom actualType = { 0 };
|
||||
int actualFormat = 0;
|
||||
|
|
@ -1099,9 +1099,8 @@ Image GetClipboardImage(void)
|
|||
unsigned long bytesAfter = 0;
|
||||
unsigned char *data = NULL;
|
||||
|
||||
// Read the data from our ghost window's property
|
||||
XGetWindowProperty(dpy, win, property, 0, ~0L, False, AnyPropertyType,
|
||||
&actualType, &actualFormat, &nitems, &bytesAfter, &data);
|
||||
XGetWindowProperty(display, window, property, 0, ~0L, False, AnyPropertyType,
|
||||
&actualType, &actualFormat, &nitems, &bytesAfter, &data);
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
|
|
@ -1109,11 +1108,9 @@ Image GetClipboardImage(void)
|
|||
XFree(data);
|
||||
}
|
||||
|
||||
XDestroyWindow(dpy, win);
|
||||
XCloseDisplay(dpy);
|
||||
#else
|
||||
TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform");
|
||||
#endif // defined(_WIN32)
|
||||
#endif // _WIN32
|
||||
#else
|
||||
TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly");
|
||||
#endif // SUPPORT_CLIPBOARD_IMAGE
|
||||
|
|
@ -1129,7 +1126,7 @@ void ShowCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
|
|
@ -1137,7 +1134,7 @@ void HideCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
|
|
@ -1151,7 +1148,7 @@ void EnableCursor(void)
|
|||
CORE.Input.Mouse.cursorLocked = false;
|
||||
}
|
||||
|
||||
// Disables cursor (lock cursor)
|
||||
// Disable cursor (lock cursor)
|
||||
void DisableCursor(void)
|
||||
{
|
||||
// Reset mouse position within the window area before disabling cursor
|
||||
|
|
|
|||
1030
src/platforms/rcore_desktop_rgfw.c
Executable file → Normal file
1030
src/platforms/rcore_desktop_rgfw.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -56,6 +56,7 @@
|
|||
#include "SDL3/SDL.h"
|
||||
#elif defined(USING_SDL2_PROJECT)
|
||||
#include "SDL2/SDL.h"
|
||||
#include "SDL2/SDL_syswm.h" // Required to get window handlers
|
||||
#else
|
||||
#include "SDL.h"
|
||||
#endif
|
||||
|
|
@ -101,6 +102,13 @@ typedef struct {
|
|||
SDL_GameController *gamepad[MAX_GAMEPADS];
|
||||
SDL_JoystickID gamepadId[MAX_GAMEPADS]; // Joystick instance ids, they do not start from 0
|
||||
SDL_Cursor *cursor;
|
||||
|
||||
#if defined(__linux__)
|
||||
// Local storage for the window handle (X11)
|
||||
// NOTE: On SDL is not possible to know windowing backend at compile time, so,
|
||||
// just in case, avoiding X11 specific types here
|
||||
unsigned long windowHandleX11; // Underlying type for: XID, Window
|
||||
#endif
|
||||
} PlatformData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -920,9 +928,60 @@ void SetWindowFocused(void)
|
|||
}
|
||||
|
||||
// Get native window handle
|
||||
// NOTE: Handle type depends on OS and windowing system
|
||||
void *GetWindowHandle(void)
|
||||
{
|
||||
return (void *)platform.window;
|
||||
void *handle = NULL;
|
||||
|
||||
#if defined(USING_SDL3_PROJECT)
|
||||
// REF: https://github.com/libsdl-org/SDL/blob/main/include/SDL3/SDL_video.h#L1590
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(platform.window);
|
||||
#if defined(_WIN32)
|
||||
handle = (void *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); // Type: HWND
|
||||
#elif defined(__linux__)
|
||||
unsigned long windowId = (unsigned long)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); // Type: unsigned long (XID, Window)
|
||||
if (windowId != 0)
|
||||
{
|
||||
// X11 window ID
|
||||
platform.windowHandleX11 = windowId;
|
||||
handle = &platform.windowHandleX11;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wayland, get display surface pointer
|
||||
// NOTE: Alternative SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER
|
||||
handle = (void *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL); // Type: struct wl_surface*
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
handle = (void *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL); // Type: NSWindow*
|
||||
#endif
|
||||
#elif defined(USING_SDL2_PROJECT)
|
||||
SDL_SysWMinfo wmInfo = { 0 };
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
if (SDL_GetWindowWMInfo(platform.window, &wmInfo))
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
handle = (void *)wmInfo.info.win.window; // Type: HWND
|
||||
#elif defined(__linux__)
|
||||
if (wmInfo.subsystem == SDL_SYSWM_X11)
|
||||
{
|
||||
// X11, get window ID (unsigned long)
|
||||
platform.windowHandleX11 = (unsigned long)wmInfo.info.x11.window;
|
||||
handle = &platform.windowHandleX11;
|
||||
}
|
||||
else if (wmInfo.subsystem == SDL_SYSWM_WAYLAND)
|
||||
{
|
||||
// Wayland, get display surface pointer
|
||||
// NOTE: Alternative: wmInfo.info.wl.display
|
||||
handle = (void *)wmInfo.info.wl.surface; // Type: struct wl_surface*
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
handle = (void *)wmInfo.info.cocoa.window; // Type: NSWindow*
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
// Get number of monitors
|
||||
|
|
@ -1144,7 +1203,7 @@ const char *GetClipboardText(void)
|
|||
|
||||
char *clipboard = SDL_GetClipboardText();
|
||||
|
||||
int clipboardSize = snprintf(buffer, sizeof(buffer), "%s", clipboard);
|
||||
int clipboardSize = snprintf(buffer, MAX_CLIPBOARD_BUFFER_LENGTH, "%s", clipboard);
|
||||
if (clipboardSize >= MAX_CLIPBOARD_BUFFER_LENGTH)
|
||||
{
|
||||
char *truncate = buffer + MAX_CLIPBOARD_BUFFER_LENGTH - 4;
|
||||
|
|
@ -1227,7 +1286,7 @@ void ShowCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
|
|
@ -1238,7 +1297,7 @@ void HideCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
|
|
@ -1247,7 +1306,7 @@ void EnableCursor(void)
|
|||
CORE.Input.Mouse.cursorLocked = false;
|
||||
}
|
||||
|
||||
// Disables cursor (lock cursor)
|
||||
// Disable cursor (lock cursor)
|
||||
void DisableCursor(void)
|
||||
{
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
|
|
@ -1675,8 +1734,13 @@ void PollInputEvents(void)
|
|||
} break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
CORE.Input.Mouse.currentWheelMove.x = (float)event.wheel.x;
|
||||
CORE.Input.Mouse.currentWheelMove.y = (float)event.wheel.y;
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
CORE.Input.Mouse.currentWheelMove.x = event.wheel.x;
|
||||
CORE.Input.Mouse.currentWheelMove.y = event.wheel.y;
|
||||
#else
|
||||
CORE.Input.Mouse.currentWheelMove.x = event.wheel.preciseX;
|
||||
CORE.Input.Mouse.currentWheelMove.y = event.wheel.preciseY;
|
||||
#endif
|
||||
} break;
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -566,100 +566,100 @@ static KeyboardKey GetKeyFromWparam(WPARAM wparam)
|
|||
case 'X': return KEY_X;
|
||||
case 'Y': return KEY_Y;
|
||||
case 'Z': return KEY_Z;
|
||||
/* case VK_LWIN: return KEY_; */
|
||||
/* case VK_RWIN: return KEY_; */
|
||||
/* case VK_APPS: return KEY_; */
|
||||
/* case VK_SLEEP: return KEY_; */
|
||||
/* case VK_NUMPAD0: return KEY_; */
|
||||
/* case VK_NUMPAD1: return KEY_; */
|
||||
/* case VK_NUMPAD2: return KEY_; */
|
||||
/* case VK_NUMPAD3: return KEY_; */
|
||||
/* case VK_NUMPAD4: return KEY_; */
|
||||
/* case VK_NUMPAD5: return KEY_; */
|
||||
/* case VK_NUMPAD6: return KEY_; */
|
||||
/* case VK_NUMPAD7: return KEY_; */
|
||||
/* case VK_NUMPAD8: return KEY_; */
|
||||
/* case VK_NUMPAD9: return KEY_; */
|
||||
/* case VK_MULTIPLY: return KEY_; */
|
||||
/* case VK_ADD: return KEY_; */
|
||||
/* case VK_SEPARATOR: return KEY_; */
|
||||
/* case VK_SUBTRACT: return KEY_; */
|
||||
/* case VK_DECIMAL: return KEY_; */
|
||||
/* case VK_DIVIDE: return KEY_; */
|
||||
/* case VK_F1: return KEY_; */
|
||||
/* case VK_F2: return KEY_; */
|
||||
/* case VK_F3: return KEY_; */
|
||||
/* case VK_F4: return KEY_; */
|
||||
/* case VK_F5: return KEY_; */
|
||||
/* case VK_F6: return KEY_; */
|
||||
/* case VK_F7: return KEY_; */
|
||||
/* case VK_F8: return KEY_; */
|
||||
/* case VK_F9: return KEY_; */
|
||||
/* case VK_F10: return KEY_; */
|
||||
/* case VK_F11: return KEY_; */
|
||||
/* case VK_F12: return KEY_; */
|
||||
/* case VK_F13: return KEY_; */
|
||||
/* case VK_F14: return KEY_; */
|
||||
/* case VK_F15: return KEY_; */
|
||||
/* case VK_F16: return KEY_; */
|
||||
/* case VK_F17: return KEY_; */
|
||||
/* case VK_F18: return KEY_; */
|
||||
/* case VK_F19: return KEY_; */
|
||||
/* case VK_F20: return KEY_; */
|
||||
/* case VK_F21: return KEY_; */
|
||||
/* case VK_F22: return KEY_; */
|
||||
/* case VK_F23: return KEY_; */
|
||||
/* case VK_F24: return KEY_; */
|
||||
/* case VK_NUMLOCK: return KEY_; */
|
||||
/* case VK_SCROLL: return KEY_; */
|
||||
/* case VK_LSHIFT: return KEY_; */
|
||||
/* case VK_RSHIFT: return KEY_; */
|
||||
/* case VK_LCONTROL: return KEY_; */
|
||||
/* case VK_RCONTROL: return KEY_; */
|
||||
/* case VK_LMENU: return KEY_; */
|
||||
/* case VK_RMENU: return KEY_; */
|
||||
/* case VK_BROWSER_BACK: return KEY_; */
|
||||
/* case VK_BROWSER_FORWARD: return KEY_; */
|
||||
/* case VK_BROWSER_REFRESH: return KEY_; */
|
||||
/* case VK_BROWSER_STOP: return KEY_; */
|
||||
/* case VK_BROWSER_SEARCH: return KEY_; */
|
||||
/* case VK_BROWSER_FAVORITES: return KEY_; */
|
||||
/* case VK_BROWSER_HOME: return KEY_; */
|
||||
/* case VK_VOLUME_MUTE: return KEY_; */
|
||||
/* case VK_VOLUME_DOWN: return KEY_; */
|
||||
/* case VK_VOLUME_UP: return KEY_; */
|
||||
/* case VK_MEDIA_NEXT_TRACK: return KEY_; */
|
||||
/* case VK_MEDIA_PREV_TRACK: return KEY_; */
|
||||
/* case VK_MEDIA_STOP: return KEY_; */
|
||||
/* case VK_MEDIA_PLAY_PAUSE: return KEY_; */
|
||||
/* case VK_LAUNCH_MAIL: return KEY_; */
|
||||
/* case VK_LAUNCH_MEDIA_SELECT: return KEY_; */
|
||||
/* case VK_LAUNCH_APP1: return KEY_; */
|
||||
/* case VK_LAUNCH_APP2: return KEY_; */
|
||||
/* case VK_OEM_1: return KEY_; */
|
||||
/* case VK_OEM_PLUS: return KEY_; */
|
||||
/* case VK_OEM_COMMA: return KEY_; */
|
||||
/* case VK_OEM_MINUS: return KEY_; */
|
||||
/* case VK_OEM_PERIOD: return KEY_; */
|
||||
/* case VK_OEM_2: return KEY_; */
|
||||
/* case VK_OEM_3: return KEY_; */
|
||||
/* case VK_OEM_4: return KEY_; */
|
||||
/* case VK_OEM_5: return KEY_; */
|
||||
/* case VK_OEM_6: return KEY_; */
|
||||
/* case VK_OEM_7: return KEY_; */
|
||||
/* case VK_OEM_8: return KEY_; */
|
||||
/* case VK_OEM_102: return KEY_; */
|
||||
/* case VK_PROCESSKEY: return KEY_; */
|
||||
/* case VK_PACKET: return KEY_; */
|
||||
/* case VK_ATTN: return KEY_; */
|
||||
/* case VK_CRSEL: return KEY_; */
|
||||
/* case VK_EXSEL: return KEY_; */
|
||||
/* case VK_EREOF: return KEY_; */
|
||||
/* case VK_PLAY: return KEY_; */
|
||||
/* case VK_ZOOM: return KEY_; */
|
||||
/* case VK_NONAME: return KEY_; */
|
||||
/* case VK_PA1: return KEY_; */
|
||||
/* case VK_OEM_CLEAR: return KEY_; */
|
||||
//case VK_LWIN: return KEY_;
|
||||
//case VK_RWIN: return KEY_;
|
||||
//case VK_APPS: return KEY_;
|
||||
//case VK_SLEEP: return KEY_;
|
||||
//case VK_NUMPAD0: return KEY_;
|
||||
//case VK_NUMPAD1: return KEY_;
|
||||
//case VK_NUMPAD2: return KEY_;
|
||||
//case VK_NUMPAD3: return KEY_;
|
||||
//case VK_NUMPAD4: return KEY_;
|
||||
//case VK_NUMPAD5: return KEY_;
|
||||
//case VK_NUMPAD6: return KEY_;
|
||||
//case VK_NUMPAD7: return KEY_;
|
||||
//case VK_NUMPAD8: return KEY_;
|
||||
//case VK_NUMPAD9: return KEY_;
|
||||
//case VK_MULTIPLY: return KEY_;
|
||||
//case VK_ADD: return KEY_;
|
||||
//case VK_SEPARATOR: return KEY_;
|
||||
//case VK_SUBTRACT: return KEY_;
|
||||
//case VK_DECIMAL: return KEY_;
|
||||
//case VK_DIVIDE: return KEY_;
|
||||
//case VK_F1: return KEY_;
|
||||
//case VK_F2: return KEY_;
|
||||
//case VK_F3: return KEY_;
|
||||
//case VK_F4: return KEY_;
|
||||
//case VK_F5: return KEY_;
|
||||
//case VK_F6: return KEY_;
|
||||
//case VK_F7: return KEY_;
|
||||
//case VK_F8: return KEY_;
|
||||
//case VK_F9: return KEY_;
|
||||
//case VK_F10: return KEY_;
|
||||
//case VK_F11: return KEY_;
|
||||
//case VK_F12: return KEY_;
|
||||
//case VK_F13: return KEY_;
|
||||
//case VK_F14: return KEY_;
|
||||
//case VK_F15: return KEY_;
|
||||
//case VK_F16: return KEY_;
|
||||
//case VK_F17: return KEY_;
|
||||
//case VK_F18: return KEY_;
|
||||
//case VK_F19: return KEY_;
|
||||
//case VK_F20: return KEY_;
|
||||
//case VK_F21: return KEY_;
|
||||
//case VK_F22: return KEY_;
|
||||
//case VK_F23: return KEY_;
|
||||
//case VK_F24: return KEY_;
|
||||
//case VK_NUMLOCK: return KEY_;
|
||||
//case VK_SCROLL: return KEY_;
|
||||
//case VK_LSHIFT: return KEY_;
|
||||
//case VK_RSHIFT: return KEY_;
|
||||
//case VK_LCONTROL: return KEY_;
|
||||
//case VK_RCONTROL: return KEY_;
|
||||
//case VK_LMENU: return KEY_;
|
||||
//case VK_RMENU: return KEY_;
|
||||
//case VK_BROWSER_BACK: return KEY_;
|
||||
//case VK_BROWSER_FORWARD: return KEY_;
|
||||
//case VK_BROWSER_REFRESH: return KEY_;
|
||||
//case VK_BROWSER_STOP: return KEY_;
|
||||
//case VK_BROWSER_SEARCH: return KEY_;
|
||||
//case VK_BROWSER_FAVORITES: return KEY_;
|
||||
//case VK_BROWSER_HOME: return KEY_;
|
||||
//case VK_VOLUME_MUTE: return KEY_;
|
||||
//case VK_VOLUME_DOWN: return KEY_;
|
||||
//case VK_VOLUME_UP: return KEY_;
|
||||
//case VK_MEDIA_NEXT_TRACK: return KEY_;
|
||||
//case VK_MEDIA_PREV_TRACK: return KEY_;
|
||||
//case VK_MEDIA_STOP: return KEY_;
|
||||
//case VK_MEDIA_PLAY_PAUSE: return KEY_;
|
||||
//case VK_LAUNCH_MAIL: return KEY_;
|
||||
//case VK_LAUNCH_MEDIA_SELECT: return KEY_;
|
||||
//case VK_LAUNCH_APP1: return KEY_;
|
||||
//case VK_LAUNCH_APP2: return KEY_;
|
||||
//case VK_OEM_1: return KEY_;
|
||||
//case VK_OEM_PLUS: return KEY_;
|
||||
//case VK_OEM_COMMA: return KEY_;
|
||||
//case VK_OEM_MINUS: return KEY_;
|
||||
//case VK_OEM_PERIOD: return KEY_;
|
||||
//case VK_OEM_2: return KEY_;
|
||||
//case VK_OEM_3: return KEY_;
|
||||
//case VK_OEM_4: return KEY_;
|
||||
//case VK_OEM_5: return KEY_;
|
||||
//case VK_OEM_6: return KEY_;
|
||||
//case VK_OEM_7: return KEY_;
|
||||
//case VK_OEM_8: return KEY_;
|
||||
//case VK_OEM_102: return KEY_;
|
||||
//case VK_PROCESSKEY: return KEY_;
|
||||
//case VK_PACKET: return KEY_;
|
||||
//case VK_ATTN: return KEY_;
|
||||
//case VK_CRSEL: return KEY_;
|
||||
//case VK_EXSEL: return KEY_;
|
||||
//case VK_EREOF: return KEY_;
|
||||
//case VK_PLAY: return KEY_;
|
||||
//case VK_ZOOM: return KEY_;
|
||||
//case VK_NONAME: return KEY_;
|
||||
//case VK_PA1: return KEY_;
|
||||
//case VK_OEM_CLEAR: return KEY_;
|
||||
default: return KEY_NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1023,7 +1023,7 @@ void SetWindowFocused(void)
|
|||
// Get native window handle
|
||||
void *GetWindowHandle(void)
|
||||
{
|
||||
return platform.hwnd;
|
||||
return (void *)platform.hwnd;
|
||||
}
|
||||
|
||||
int GetMonitorCount(void)
|
||||
|
|
@ -1146,7 +1146,7 @@ void ShowCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
// NOTE: Using SetCursor() instead of ShowCursor() because
|
||||
|
|
@ -1155,7 +1155,7 @@ void HideCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
if (CORE.Input.Mouse.cursorLocked)
|
||||
|
|
@ -1257,8 +1257,9 @@ void OpenURL(const char *url)
|
|||
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
|
||||
else
|
||||
{
|
||||
char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char));
|
||||
sprintf(cmd, "explorer \"%s\"", url);
|
||||
int len = strlen(url) + 32;
|
||||
char *cmd = (char *)RL_CALLOC(len, sizeof(char));
|
||||
snprintf(cmd, len, "explorer \"%s\"", url);
|
||||
int result = system(cmd);
|
||||
if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created");
|
||||
RL_FREE(cmd);
|
||||
|
|
@ -1526,7 +1527,6 @@ int InitPlatform(void)
|
|||
if (hr < 0) TRACELOG(LOG_ERROR, "%s failed, hresult=0x%lx", "SetProcessDpiAwareness", (DWORD)hr);
|
||||
}
|
||||
*/
|
||||
|
||||
HINSTANCE hInstance = GetModuleHandleW(0);
|
||||
|
||||
// Define window class
|
||||
|
|
@ -1775,9 +1775,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
|
|||
// WARNING: Don't trust the docs, they say this message can not be obtained if not calling DefWindowProc()
|
||||
// in response to WM_WINDOWPOSCHANGED but looks like when a window is created,
|
||||
// this message can be obtained without getting WM_WINDOWPOSCHANGED
|
||||
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
||||
// WARNING: Waiting two frames before resizing because software-renderer backend is initilized with swInit() later
|
||||
// WARNING: Waiting two frames before resizing because software-renderer backend is initilized with swInit() later
|
||||
// than InitPlatform(), that triggers WM_SIZE, so avoid crashing
|
||||
if (CORE.Time.frameCounter > 2) HandleWindowResize(hwnd, &platform.appScreenWidth, &platform.appScreenHeight);
|
||||
#else
|
||||
|
|
@ -2034,7 +2034,7 @@ static void HandleKey(WPARAM wparam, LPARAM lparam, char state)
|
|||
{
|
||||
CORE.Input.Keyboard.currentKeyState[key] = state;
|
||||
|
||||
if ((key == KEY_ESCAPE) && (state == 1)) CORE.Window.shouldClose = true;
|
||||
if ((key == CORE.Input.Keyboard.exitKey) && (state == 1)) CORE.Window.shouldClose = true;
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "INPUT: Unknown (or currently unhandled) virtual keycode %d (0x%x)", wparam, wparam);
|
||||
|
||||
|
|
@ -2053,8 +2053,11 @@ static void HandleMouseButton(int button, char state)
|
|||
static void HandleRawInput(LPARAM lparam)
|
||||
{
|
||||
RAWINPUT input = { 0 };
|
||||
UINT inputSize = 0;
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL, &inputSize, sizeof(RAWINPUTHEADER)) != 0) return;
|
||||
if (inputSize > sizeof(input)) return;
|
||||
|
||||
UINT inputSize = sizeof(input);
|
||||
UINT size = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &input, &inputSize, sizeof(RAWINPUTHEADER));
|
||||
|
||||
if (size == (UINT)-1) TRACELOG(LOG_ERROR, "WIN32: Failed to get raw input data [ERROR: %lu]", GetLastError());
|
||||
|
|
@ -2271,4 +2274,4 @@ static bool IsWglExtensionAvailable(HDC hdc, const char *extension)
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -266,9 +266,12 @@ static void PollKeyboardEvents(void); // Process evdev keyboard events
|
|||
static void PollGamepadEvents(void); // Process evdev gamepad events
|
||||
static void PollMouseEvents(void); // Process evdev mouse events
|
||||
|
||||
// Not used by software rendering.
|
||||
#if !defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
||||
static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list
|
||||
static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list
|
||||
static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list
|
||||
#endif
|
||||
|
||||
static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform())
|
||||
|
||||
|
|
@ -561,13 +564,13 @@ void ShowCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
// Set cursor position in the middle
|
||||
|
|
@ -577,7 +580,7 @@ void EnableCursor(void)
|
|||
CORE.Input.Mouse.cursorLocked = false;
|
||||
}
|
||||
|
||||
// Disables cursor (lock cursor)
|
||||
// Disable cursor (lock cursor)
|
||||
void DisableCursor(void)
|
||||
{
|
||||
// Set cursor position in the middle
|
||||
|
|
@ -1003,9 +1006,9 @@ double GetTime(void)
|
|||
double time = 0.0;
|
||||
struct timespec ts = { 0 };
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
|
||||
unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
|
||||
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
|
||||
return time;
|
||||
}
|
||||
|
|
@ -2560,6 +2563,7 @@ static void PollMouseEvents(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
||||
// Search matching DRM mode in connector's mode list
|
||||
static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode)
|
||||
{
|
||||
|
|
@ -2648,6 +2652,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
|||
|
||||
return nearestIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Compute framebuffer size relative to screen size and display size
|
||||
// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ bool InitGraphicsDevice(void); // Initialize graphics device
|
|||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
#if !defined(_WIN32)
|
||||
static int kbhit(void); // Check if a key has been pressed
|
||||
static int kbhit(void); // Check if key has been pressed
|
||||
static char getch(void) { return getchar(); } // Get pressed character
|
||||
#endif
|
||||
|
||||
|
|
@ -324,13 +324,13 @@ void ShowCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
// Set cursor position in the middle
|
||||
|
|
@ -339,7 +339,7 @@ void EnableCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Disables cursor (lock cursor)
|
||||
// Disable cursor (lock cursor)
|
||||
void DisableCursor(void)
|
||||
{
|
||||
// Set cursor position in the middle
|
||||
|
|
@ -364,14 +364,18 @@ double GetTime(void)
|
|||
{
|
||||
double time = 0.0;
|
||||
#if defined(_WIN32)
|
||||
LARGE_INTEGER now = { 0 };
|
||||
QueryPerformanceCounter(&now);
|
||||
return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart;
|
||||
LARGE_INTEGER currentTicks = { 0 };
|
||||
QueryPerformanceCounter(¤tTicks);
|
||||
|
||||
time = (double)(currentTicks.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart;
|
||||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
|
||||
struct timespec ts = { 0 };
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
|
||||
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
#elif defined(PICO_RP2350)
|
||||
time = (double)to_ms_since_boot(get_absolute_time())/1000.0;
|
||||
#endif
|
||||
return time;
|
||||
}
|
||||
|
|
@ -558,7 +562,7 @@ void ClosePlatform(void)
|
|||
// Module Internal Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
#if !defined(_WIN32)
|
||||
// Check if a key has been pressed
|
||||
// Check if key has been pressed
|
||||
static int kbhit(void)
|
||||
{
|
||||
struct termios oldt = { 0 };
|
||||
|
|
|
|||
|
|
@ -303,13 +303,13 @@ void ShowCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
// Set cursor position in the middle
|
||||
|
|
@ -318,7 +318,7 @@ void EnableCursor(void)
|
|||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Disables cursor (lock cursor)
|
||||
// Disable cursor (lock cursor)
|
||||
void DisableCursor(void)
|
||||
{
|
||||
// Set cursor position in the middle
|
||||
|
|
@ -341,10 +341,12 @@ void SwapScreenBuffer(void)
|
|||
double GetTime(void)
|
||||
{
|
||||
double time = 0.0;
|
||||
|
||||
struct timespec ts = { 0 };
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
|
||||
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
|
||||
return time;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ typedef struct {
|
|||
|
||||
char canvasId[64]; // Keep current canvas id where wasm app is running
|
||||
// NOTE: Useful when trying to run multiple wasms in different canvases in same webpage
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
||||
unsigned int *pixels; // Pointer to pixel data buffer (RGBA 32bit format)
|
||||
#endif
|
||||
|
|
@ -913,7 +912,7 @@ void ShowCursor(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
if (!CORE.Input.Mouse.cursorHidden)
|
||||
|
|
@ -924,7 +923,7 @@ void HideCursor(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
emscripten_exit_pointerlock();
|
||||
|
|
@ -935,7 +934,7 @@ void EnableCursor(void)
|
|||
// NOTE: CORE.Input.Mouse.cursorLocked handled by EmscriptenPointerlockCallback()
|
||||
}
|
||||
|
||||
// Disables cursor (lock cursor)
|
||||
// Disable cursor (lock cursor)
|
||||
void DisableCursor(void)
|
||||
{
|
||||
emscripten_request_pointerlock(platform.canvasId, 1);
|
||||
|
|
|
|||
|
|
@ -633,7 +633,7 @@ void SetWindowSize(int width, int height)
|
|||
// When resizing the canvas, several elements must be considered:
|
||||
// - CSS canvas size: Web layout size, logical pixels
|
||||
// - Canvas contained framebuffer resolution
|
||||
// * Browser monitor, device pixel ratio (HighDPI)
|
||||
// - Browser monitor, device pixel ratio (HighDPI)
|
||||
|
||||
double canvasCssWidth = 0.0;
|
||||
double canvasCssHeight = 0.0;
|
||||
|
|
@ -891,7 +891,7 @@ void ShowCursor(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
// Hide mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
if (!CORE.Input.Mouse.cursorHidden)
|
||||
|
|
@ -902,7 +902,7 @@ void HideCursor(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
// Enable cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
emscripten_exit_pointerlock();
|
||||
|
|
@ -913,7 +913,7 @@ void EnableCursor(void)
|
|||
// NOTE: CORE.Input.Mouse.cursorLocked handled by EmscriptenPointerlockCallback()
|
||||
}
|
||||
|
||||
// Disables cursor (lock cursor)
|
||||
// Disable cursor (lock cursor)
|
||||
void DisableCursor(void)
|
||||
{
|
||||
emscripten_request_pointerlock(platform.canvasId, 1);
|
||||
|
|
|
|||
36
src/raudio.c
36
src/raudio.c
|
|
@ -344,7 +344,7 @@ typedef enum {
|
|||
// Audio buffer struct
|
||||
struct rAudioBuffer {
|
||||
ma_data_converter converter; // Audio data converter
|
||||
unsigned char* converterResidual; // Cached residual input frames for use by the converter
|
||||
unsigned char *converterResidual; // Cached residual input frames for use by the converter
|
||||
unsigned int converterResidualCount; // The number of valid frames sitting in converterResidual
|
||||
|
||||
AudioCallback callback; // Audio buffer callback for buffer filling on audio threads
|
||||
|
|
@ -378,7 +378,7 @@ struct rAudioProcessor {
|
|||
rAudioProcessor *prev; // Previous audio processor on the list
|
||||
};
|
||||
|
||||
#define AudioBuffer rAudioBuffer // HACK: To avoid CoreAudio (macOS) symbol collision
|
||||
#define AudioBuffer rAudioBuffer // WARNING: Renamed to avoid symbol collision with CoreAudio (macOS) AudioBuffer type
|
||||
|
||||
// Audio data context
|
||||
typedef struct AudioData {
|
||||
|
|
@ -434,6 +434,7 @@ static const char *GetFileName(const char *filePath); // Get point
|
|||
static const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)
|
||||
|
||||
static unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read)
|
||||
static void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
|
||||
static bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write)
|
||||
static bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated
|
||||
#endif
|
||||
|
|
@ -857,7 +858,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
|
|||
else if ((strcmp(fileType, ".mp3") == 0) || (strcmp(fileType, ".MP3") == 0))
|
||||
{
|
||||
drmp3_config config = { 0 };
|
||||
unsigned long long int totalFrameCount = 0;
|
||||
unsigned long long totalFrameCount = 0;
|
||||
|
||||
// NOTE: Forcing conversion to 32bit float sample size on reading
|
||||
wave.data = drmp3_open_memory_and_read_pcm_frames_f32(fileData, dataSize, &config, &totalFrameCount, NULL);
|
||||
|
|
@ -867,7 +868,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
|
|||
{
|
||||
wave.channels = config.channels;
|
||||
wave.sampleRate = config.sampleRate;
|
||||
wave.frameCount = (int)totalFrameCount;
|
||||
wave.frameCount = (unsigned int)totalFrameCount; // WARNING: Potential loss of data
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "WAVE: Failed to load MP3 data");
|
||||
|
||||
|
|
@ -895,13 +896,13 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
|
|||
#if SUPPORT_FILEFORMAT_FLAC
|
||||
else if ((strcmp(fileType, ".flac") == 0) || (strcmp(fileType, ".FLAC") == 0))
|
||||
{
|
||||
unsigned long long int totalFrameCount = 0;
|
||||
unsigned long long totalFrameCount = 0;
|
||||
|
||||
// NOTE: Forcing conversion to 16bit sample size on reading
|
||||
wave.data = drflac_open_memory_and_read_pcm_frames_s16(fileData, dataSize, &wave.channels, &wave.sampleRate, &totalFrameCount, NULL);
|
||||
wave.sampleSize = 16;
|
||||
|
||||
if (wave.data != NULL) wave.frameCount = (unsigned int)totalFrameCount;
|
||||
if (wave.data != NULL) wave.frameCount = (unsigned int)totalFrameCount; // WARNING: Potential loss of data
|
||||
else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data");
|
||||
}
|
||||
#endif
|
||||
|
|
@ -912,7 +913,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
|
|||
return wave;
|
||||
}
|
||||
|
||||
// Checks if wave data is valid (data loaded and parameters)
|
||||
// Check if wave data is valid (data loaded and parameters)
|
||||
bool IsWaveValid(Wave wave)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -980,7 +981,7 @@ Sound LoadSoundFromWave(Wave wave)
|
|||
return sound;
|
||||
}
|
||||
|
||||
// Clone sound from existing sound data, clone does not own wave data
|
||||
// Load sound alias, clone sound from existing sound data, clone does not own wave data
|
||||
// NOTE: Wave data must be unallocated manually and will be shared across all clones
|
||||
Sound LoadSoundAlias(Sound source)
|
||||
{
|
||||
|
|
@ -1012,7 +1013,7 @@ Sound LoadSoundAlias(Sound source)
|
|||
return sound;
|
||||
}
|
||||
|
||||
// Checks if a sound is valid (data loaded and buffers initialized)
|
||||
// Check if sound is valid (data loaded and buffers initialized)
|
||||
bool IsSoundValid(Sound sound)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -1047,6 +1048,7 @@ void UnloadSoundAlias(Sound alias)
|
|||
{
|
||||
UntrackAudioBuffer(alias.stream.buffer);
|
||||
ma_data_converter_uninit(&alias.stream.buffer->converter, NULL);
|
||||
RL_FREE(alias.stream.buffer->converterResidual);
|
||||
RL_FREE(alias.stream.buffer);
|
||||
}
|
||||
}
|
||||
|
|
@ -1213,7 +1215,7 @@ void StopSound(Sound sound)
|
|||
StopAudioBuffer(sound.stream.buffer);
|
||||
}
|
||||
|
||||
// Check if a sound is playing
|
||||
// Check if sound is playing
|
||||
bool IsSoundPlaying(Sound sound)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -1749,7 +1751,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
|
|||
return music;
|
||||
}
|
||||
|
||||
// Checks if a music stream is valid (context and buffers initialized)
|
||||
// Check if music stream is valid (context and buffers initialized)
|
||||
bool IsMusicValid(Music music)
|
||||
{
|
||||
return ((music.ctxData != NULL) && // Validate context loaded
|
||||
|
|
@ -1782,7 +1784,7 @@ void UnloadMusicStream(Music music)
|
|||
else if (music.ctxType == MUSIC_AUDIO_QOA) qoaplay_close((qoaplay_desc *)music.ctxData);
|
||||
#endif
|
||||
#if SUPPORT_FILEFORMAT_FLAC
|
||||
else if (music.ctxType == MUSIC_AUDIO_FLAC) { drflac_close((drflac *)music.ctxData); drflac_free((drflac *)music.ctxData, NULL); }
|
||||
else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_close((drflac *)music.ctxData);
|
||||
#endif
|
||||
#if SUPPORT_FILEFORMAT_XM
|
||||
else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData);
|
||||
|
|
@ -2066,7 +2068,7 @@ void SetMusicPitch(Music music, float pitch)
|
|||
SetAudioBufferPitch(music.stream.buffer, pitch);
|
||||
}
|
||||
|
||||
// Set pan for a music
|
||||
// Set pan for music
|
||||
void SetMusicPan(Music music, float pan)
|
||||
{
|
||||
SetAudioBufferPan(music.stream.buffer, pan);
|
||||
|
|
@ -2154,7 +2156,7 @@ AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
|
|||
return stream;
|
||||
}
|
||||
|
||||
// Checks if an audio stream is valid (buffers initialized)
|
||||
// Check if an audio stream is valid (buffers initialized)
|
||||
bool IsAudioStreamValid(AudioStream stream)
|
||||
{
|
||||
return ((stream.buffer != NULL) && // Validate stream buffer
|
||||
|
|
@ -2882,6 +2884,12 @@ static unsigned char *LoadFileData(const char *fileName, int *dataSize)
|
|||
return data;
|
||||
}
|
||||
|
||||
// Unload file data allocated by LoadFileData()
|
||||
static void UnloadFileData(unsigned char *data)
|
||||
{
|
||||
RL_FREE(data);
|
||||
}
|
||||
|
||||
// Save data to file from buffer
|
||||
static bool SaveFileData(const char *fileName, void *data, int dataSize)
|
||||
{
|
||||
|
|
|
|||
259
src/raylib.h
259
src/raylib.h
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib v6.0 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
* raylib v6.1-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
*
|
||||
* FEATURES:
|
||||
* - NO external dependencies, all required libraries included with raylib
|
||||
|
|
@ -87,9 +87,9 @@
|
|||
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
|
||||
|
||||
#define RAYLIB_VERSION_MAJOR 6
|
||||
#define RAYLIB_VERSION_MINOR 0
|
||||
#define RAYLIB_VERSION_MINOR 1
|
||||
#define RAYLIB_VERSION_PATCH 0
|
||||
#define RAYLIB_VERSION "6.0"
|
||||
#define RAYLIB_VERSION "6.1-dev"
|
||||
|
||||
// Function specifiers in case library is build/used as a shared library
|
||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||
|
|
@ -203,12 +203,14 @@
|
|||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Boolean type
|
||||
#if !defined(__cplusplus)
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__cplusplus) && !defined(bool)
|
||||
#elif !defined(bool)
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#define RL_BOOL_TYPE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Vector2, 2 components
|
||||
typedef struct Vector2 {
|
||||
|
|
@ -963,10 +965,10 @@ typedef enum {
|
|||
|
||||
// Callbacks to hook some internal functions
|
||||
// WARNING: These callbacks are intended for advanced users
|
||||
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
|
||||
typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data
|
||||
typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data
|
||||
typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data
|
||||
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
|
||||
typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data
|
||||
typedef bool (*SaveFileDataCallback)(const char *fileName, const void *data, int dataSize); // FileIO: Save binary data
|
||||
typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data
|
||||
typedef bool (*SaveFileTextCallback)(const char *fileName, const char *text); // FileIO: Save text data
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
|
@ -1034,23 +1036,23 @@ RLAPI void EnableEventWaiting(void); // Enable wait
|
|||
RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling
|
||||
|
||||
// Cursor-related functions
|
||||
RLAPI void ShowCursor(void); // Shows cursor
|
||||
RLAPI void HideCursor(void); // Hides cursor
|
||||
RLAPI void ShowCursor(void); // Show cursor
|
||||
RLAPI void HideCursor(void); // Hide cursor
|
||||
RLAPI bool IsCursorHidden(void); // Check if cursor is not visible
|
||||
RLAPI void EnableCursor(void); // Enables cursor (unlock cursor)
|
||||
RLAPI void DisableCursor(void); // Disables cursor (lock cursor)
|
||||
RLAPI void EnableCursor(void); // Enable cursor (unlock cursor)
|
||||
RLAPI void DisableCursor(void); // Disable cursor (lock cursor)
|
||||
RLAPI bool IsCursorOnScreen(void); // Check if cursor is on the screen
|
||||
|
||||
// Drawing-related functions
|
||||
RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
|
||||
RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing
|
||||
RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering)
|
||||
RLAPI void ClearBackground(Color color); // Clear background (framebuffer) to color
|
||||
RLAPI void BeginDrawing(void); // Begin canvas (framebuffer) drawing
|
||||
RLAPI void EndDrawing(void); // End canvas (framebuffer) drawing and swap buffers (double buffering)
|
||||
RLAPI void BeginMode2D(Camera2D camera); // Begin 2D mode with custom camera (2D)
|
||||
RLAPI void EndMode2D(void); // Ends 2D mode with custom camera
|
||||
RLAPI void EndMode2D(void); // End 2D mode with custom camera
|
||||
RLAPI void BeginMode3D(Camera3D camera); // Begin 3D mode with custom camera (3D)
|
||||
RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode
|
||||
RLAPI void EndMode3D(void); // End 3D mode and returns to default 2D orthographic mode
|
||||
RLAPI void BeginTextureMode(RenderTexture2D target); // Begin drawing to render texture
|
||||
RLAPI void EndTextureMode(void); // Ends drawing to render texture
|
||||
RLAPI void EndTextureMode(void); // End drawing to render texture
|
||||
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
|
||||
RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
|
||||
RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied, subtract, custom)
|
||||
|
|
@ -1068,7 +1070,7 @@ RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR s
|
|||
// NOTE: Shader functionality is not available on OpenGL 1.1
|
||||
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
|
||||
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
|
||||
RLAPI bool IsShaderValid(Shader shader); // Check if a shader is valid (loaded on GPU)
|
||||
RLAPI bool IsShaderValid(Shader shader); // Check if shader is valid (loaded on GPU)
|
||||
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
||||
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
|
||||
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
|
||||
|
|
@ -1078,13 +1080,12 @@ RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture)
|
|||
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
|
||||
|
||||
// Screen-space-related functions
|
||||
#define GetMouseRay GetScreenToWorldRay // Compatibility hack for previous raylib versions
|
||||
RLAPI Ray GetScreenToWorldRay(Vector2 position, Camera camera); // Get a ray trace from screen position (i.e mouse)
|
||||
RLAPI Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height); // Get a ray trace from screen position (i.e mouse) in a viewport
|
||||
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position
|
||||
RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position
|
||||
RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position
|
||||
RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position
|
||||
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get screen space position for a 3d world space position
|
||||
RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get sized screen space position for a 3d world space position
|
||||
RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get screen space position for a 2d camera world space position
|
||||
RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get world space position for a 2d camera screen space position
|
||||
RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix)
|
||||
RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix
|
||||
|
||||
|
|
@ -1110,7 +1111,7 @@ RLAPI void UnloadRandomSequence(int *sequence); // Unload random values
|
|||
|
||||
// Misc. functions
|
||||
RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format)
|
||||
RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS)
|
||||
RLAPI void SetConfigFlags(unsigned int flags); // Set up init configuration flags (view FLAGS)
|
||||
RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available)
|
||||
|
||||
// Logging system
|
||||
|
|
@ -1126,7 +1127,7 @@ RLAPI void MemFree(void *ptr); // Internal memo
|
|||
// File system management functions
|
||||
RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read)
|
||||
RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
|
||||
RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success
|
||||
RLAPI bool SaveFileData(const char *fileName, const void *data, int dataSize); // Save data to file from byte array (write), returns true on success
|
||||
RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); // Export data to code (.h), returns true on success
|
||||
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
|
||||
RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText()
|
||||
|
|
@ -1139,14 +1140,14 @@ RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custo
|
|||
RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader
|
||||
RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver
|
||||
|
||||
RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists)
|
||||
RLAPI int FileRemove(const char *fileName); // Remove file (if exists)
|
||||
RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist
|
||||
RLAPI int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist
|
||||
RLAPI int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file
|
||||
RLAPI int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file
|
||||
RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists), returns 0 on success
|
||||
RLAPI int FileRemove(const char *fileName); // Remove file (if exists), returns 0 on success
|
||||
RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist, returns 0 on success
|
||||
RLAPI int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist, returns 0 on success
|
||||
RLAPI int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file, returns 0 on success
|
||||
RLAPI int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file, returns -1 if index not found or index otherwise
|
||||
RLAPI bool FileExists(const char *fileName); // Check if file exists
|
||||
RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists
|
||||
RLAPI bool DirectoryExists(const char *dirPath); // Check if directory path exists
|
||||
RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (recommended include point: .png, .wav)
|
||||
RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h)
|
||||
RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time)
|
||||
|
|
@ -1158,13 +1159,13 @@ RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previ
|
|||
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
|
||||
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
|
||||
RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success
|
||||
RLAPI bool ChangeDirectory(const char *dirPath); // Change working directory, return true on success
|
||||
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
|
||||
RLAPI int ChangeDirectory(const char *dirPath); // Change working directory, returns 0 on success
|
||||
RLAPI bool IsPathFile(const char *path); // Check if given path is a file or a directory
|
||||
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
|
||||
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan
|
||||
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"
|
||||
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'
|
||||
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
|
||||
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
|
||||
RLAPI bool IsFileDropped(void); // Check if file has been dropped into window
|
||||
RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths
|
||||
RLAPI void UnloadDroppedFiles(FilePathList files); // Unload dropped filepaths
|
||||
RLAPI unsigned int GetDirectoryFileCount(const char *dirPath); // Get the file count in a directory
|
||||
|
|
@ -1175,10 +1176,10 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
|
|||
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
|
||||
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
|
||||
RLAPI unsigned char *DecodeDataBase64(const char *text, int *outputSize); // Decode Base64 string (expected NULL terminated), memory must be MemFree()
|
||||
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
|
||||
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||
RLAPI unsigned int *ComputeSHA256(unsigned char *data, int dataSize); // Compute SHA256 hash code, returns static int[8] (32 bytes)
|
||||
RLAPI unsigned int ComputeCRC32(const unsigned char *data, int dataSize); // Compute CRC32 hash code
|
||||
RLAPI unsigned int *ComputeMD5(const unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||
RLAPI unsigned int *ComputeSHA1(const unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||
RLAPI unsigned int *ComputeSHA256(const unsigned char *data, int dataSize); // Compute SHA256 hash code, returns static int[8] (32 bytes)
|
||||
|
||||
// Automation events functionality
|
||||
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
||||
|
|
@ -1195,23 +1196,23 @@ RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a reco
|
|||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Input-related functions: keyboard
|
||||
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
|
||||
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again
|
||||
RLAPI bool IsKeyDown(int key); // Check if a key is being pressed
|
||||
RLAPI bool IsKeyReleased(int key); // Check if a key has been released once
|
||||
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
|
||||
RLAPI bool IsKeyPressed(int key); // Check if key has been pressed once
|
||||
RLAPI bool IsKeyPressedRepeat(int key); // Check if key has been pressed again
|
||||
RLAPI bool IsKeyDown(int key); // Check if key is being pressed
|
||||
RLAPI bool IsKeyReleased(int key); // Check if key has been released once
|
||||
RLAPI bool IsKeyUp(int key); // Check if key is NOT being pressed
|
||||
RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
|
||||
RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
|
||||
RLAPI const char *GetKeyName(int key); // Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)
|
||||
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
|
||||
|
||||
// Input-related functions: gamepads
|
||||
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
|
||||
RLAPI bool IsGamepadAvailable(int gamepad); // Check if gamepad is available
|
||||
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
|
||||
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
|
||||
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
|
||||
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
|
||||
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
|
||||
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if gamepad button has been pressed once
|
||||
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if gamepad button is being pressed
|
||||
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if gamepad button has been released once
|
||||
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if gamepad button is NOT being pressed
|
||||
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
|
||||
RLAPI int GetGamepadAxisCount(int gamepad); // Get axis count for a gamepad
|
||||
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get movement value for a gamepad axis
|
||||
|
|
@ -1219,10 +1220,10 @@ RLAPI int SetGamepadMappings(const char *mappings); // Set internal ga
|
|||
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds)
|
||||
|
||||
// Input-related functions: mouse
|
||||
RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once
|
||||
RLAPI bool IsMouseButtonDown(int button); // Check if a mouse button is being pressed
|
||||
RLAPI bool IsMouseButtonReleased(int button); // Check if a mouse button has been released once
|
||||
RLAPI bool IsMouseButtonUp(int button); // Check if a mouse button is NOT being pressed
|
||||
RLAPI bool IsMouseButtonPressed(int button); // Check if mouse button has been pressed once
|
||||
RLAPI bool IsMouseButtonDown(int button); // Check if mouse button is being pressed
|
||||
RLAPI bool IsMouseButtonReleased(int button); // Check if mouse button has been released once
|
||||
RLAPI bool IsMouseButtonUp(int button); // Check if mouse button is NOT being pressed
|
||||
RLAPI int GetMouseX(void); // Get mouse position X
|
||||
RLAPI int GetMouseY(void); // Get mouse position Y
|
||||
RLAPI Vector2 GetMousePosition(void); // Get mouse position XY
|
||||
|
|
@ -1245,7 +1246,7 @@ RLAPI int GetTouchPointCount(void); // Get number of t
|
|||
// Gestures and Touch Handling Functions (Module: rgestures)
|
||||
//------------------------------------------------------------------------------------
|
||||
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
|
||||
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if gesture has been detected
|
||||
RLAPI int GetGestureDetected(void); // Get latest detected gesture
|
||||
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
|
||||
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
|
|
@ -1265,7 +1266,7 @@ RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, f
|
|||
// Set texture and rectangle to be used on shapes drawing
|
||||
// NOTE: It can be useful when using basic shapes and one single font,
|
||||
// defining a font char white rectangle would allow drawing everything in a single draw call
|
||||
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
|
||||
RLAPI void SetShapesTexture(Texture2D texture, Rectangle rec); // Set texture and rectangle to be used on shapes drawing
|
||||
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
|
||||
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
|
||||
|
||||
|
|
@ -1278,6 +1279,26 @@ RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color
|
|||
RLAPI void DrawLineStrip(const Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines)
|
||||
RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation
|
||||
RLAPI void DrawLineDashed(Vector2 startPos, Vector2 endPos, int dashSize, int spaceSize, Color color); // Draw a dashed line
|
||||
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle, counter-clockwise vertex order
|
||||
RLAPI void DrawTriangleGradient(Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors, counter-clockwise vertex/color order
|
||||
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline, counter-clockwise vertex order
|
||||
RLAPI void DrawTriangleFan(const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
|
||||
RLAPI void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
|
||||
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
|
||||
RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
|
||||
RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
|
||||
RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
|
||||
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color top, Color bottom); // Draw a vertical-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color left, Color right); // Draw a horizontal-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors, counter-clockwise color order
|
||||
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
|
||||
RLAPI void DrawRectangleLinesEx(Rectangle rec, float thick, Color color); // Draw rectangle outline with line thickness
|
||||
RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges
|
||||
RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle lines with rounded edges
|
||||
RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float thick, Color color); // Draw rectangle lines with rounded edges outline and line thickness
|
||||
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon of n sides
|
||||
RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides
|
||||
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float thick, Color color); // Draw a polygon outline of n sides with line thickness
|
||||
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
|
||||
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
|
||||
RLAPI void DrawCircleGradient(Vector2 center, float radius, Color inner, Color outer); // Draw a gradient-filled circle
|
||||
|
|
@ -1285,31 +1306,13 @@ RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, floa
|
|||
RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline
|
||||
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
|
||||
RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version)
|
||||
RLAPI void DrawCircleLinesEx(Vector2 center, float radius, float thick, Color color); // Draw circle outline with line thickness
|
||||
RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse
|
||||
RLAPI void DrawEllipseV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse (Vector version)
|
||||
RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline
|
||||
RLAPI void DrawEllipseLinesV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse outline (Vector version)
|
||||
RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring
|
||||
RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline
|
||||
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
|
||||
RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
|
||||
RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
|
||||
RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
|
||||
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color top, Color bottom); // Draw a vertical-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color left, Color right); // Draw a horizontal-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color topLeft, Color bottomLeft, Color bottomRight, Color topRight); // Draw a gradient-filled rectangle with custom vertex colors
|
||||
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
|
||||
RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters
|
||||
RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges
|
||||
RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle lines with rounded edges
|
||||
RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline
|
||||
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
|
||||
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!)
|
||||
RLAPI void DrawTriangleFan(const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
|
||||
RLAPI void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
|
||||
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
|
||||
RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides
|
||||
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
|
||||
|
||||
// Splines drawing functions
|
||||
RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
|
||||
|
|
@ -1327,14 +1330,14 @@ RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vect
|
|||
RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear
|
||||
RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline
|
||||
RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom
|
||||
RLAPI Vector2 GetSplinePointBezierQuad(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier
|
||||
RLAPI Vector2 GetSplinePointBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier
|
||||
RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier
|
||||
|
||||
// Basic shapes collision detection functions
|
||||
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
|
||||
RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
|
||||
RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
|
||||
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
|
||||
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created between two points [p1] and [p2]
|
||||
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
|
||||
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
|
||||
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
|
||||
|
|
@ -1355,7 +1358,7 @@ RLAPI Image LoadImageAnim(const char *fileName, int *frames);
|
|||
RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer
|
||||
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'
|
||||
RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data
|
||||
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot)
|
||||
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer (screenshot)
|
||||
RLAPI bool IsImageValid(Image image); // Check if an image is valid (data and parameters)
|
||||
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
|
||||
|
|
@ -1401,7 +1404,7 @@ RLAPI void ImageRotateCCW(Image *image);
|
|||
RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
|
||||
RLAPI void ImageColorInvert(Image *image); // Modify image color: invert
|
||||
RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale
|
||||
RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
|
||||
RLAPI void ImageColorContrast(Image *image, int contrast); // Modify image color: contrast (-100 to 100)
|
||||
RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
|
||||
RLAPI void ImageColorReplace(Image *image, Color color, Color replace); // Modify image color: replace color
|
||||
RLAPI Color *LoadImageColors(Image image); // Load color data from image as a Color array (RGBA - 32bit)
|
||||
|
|
@ -1419,20 +1422,26 @@ RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color);
|
|||
RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image
|
||||
RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version)
|
||||
RLAPI void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color color); // Draw a line defining thickness within an image
|
||||
RLAPI void ImageDrawLineStrip(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a lines sequence within an image
|
||||
RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image
|
||||
RLAPI void ImageDrawTriangleGradient(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image
|
||||
RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image
|
||||
RLAPI void ImageDrawTriangleFan(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
|
||||
RLAPI void ImageDrawTriangleStrip(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
|
||||
RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image
|
||||
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
|
||||
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
|
||||
RLAPI void ImageDrawRectangleLines(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle lines within an image
|
||||
RLAPI void ImageDrawRectangleLinesEx(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image with line thickness
|
||||
RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image
|
||||
RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version)
|
||||
RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image
|
||||
RLAPI void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color); // Draw circle outline within an image (Vector version)
|
||||
RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image
|
||||
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
|
||||
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
|
||||
RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image
|
||||
RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image
|
||||
RLAPI void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image
|
||||
RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image
|
||||
RLAPI void ImageDrawTriangleFan(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
|
||||
RLAPI void ImageDrawTriangleStrip(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
|
||||
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source)
|
||||
RLAPI void ImageDrawCircleGradient(Image *dst, Vector2 center, float radius, Color inner, Color outer); // Draw a gradient-filled circle within an image
|
||||
|
||||
RLAPI void ImageDrawImage(Image *dst, Image src, int posX, int posY, Color tint); // Draw an image within an image
|
||||
RLAPI void ImageDrawImageRec(Image *dst, Image src, Rectangle srcRec, Vector2 position, Color tint); // Draw a part of an image defined by a rectangle within an image
|
||||
RLAPI void ImageDrawImagePro(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Vector2 origin, float rotation, Color tint); // Draw a part of an image defined by a rectangle into destination rectangle, with scaling and rotation, within an image
|
||||
RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination)
|
||||
RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination)
|
||||
|
||||
|
|
@ -1442,9 +1451,9 @@ RLAPI Texture2D LoadTexture(const char *fileName);
|
|||
RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
|
||||
RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported
|
||||
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
|
||||
RLAPI bool IsTextureValid(Texture2D texture); // Check if a texture is valid (loaded in GPU)
|
||||
RLAPI bool IsTextureValid(Texture2D texture); // Check if texture is valid (loaded in GPU)
|
||||
RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
|
||||
RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if a render texture is valid (loaded in GPU)
|
||||
RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if render texture is valid (loaded in GPU)
|
||||
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
|
||||
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data (pixels should be able to fill texture)
|
||||
RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data (pixels and rec should fit in texture)
|
||||
|
|
@ -1457,10 +1466,10 @@ RLAPI void SetTextureWrap(Texture2D texture, int wrap);
|
|||
// Texture drawing functions
|
||||
RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
|
||||
RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
|
||||
RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
|
||||
RLAPI void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
|
||||
RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
|
||||
RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely
|
||||
RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with rotation and scale
|
||||
RLAPI void DrawTextureRec(Texture2D texture, Rectangle rec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
|
||||
RLAPI void DrawTexturePro(Texture2D texture, Rectangle srcrec, Rectangle dstrec, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a source rectangle to destination rectangle, with scaling and rotation
|
||||
RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dstrec, Vector2 origin, float rotation, Color tint); // Draw a texture (or part of it) that stretches or shrinks nicely
|
||||
|
||||
// Color/pixel related functions
|
||||
RLAPI bool ColorIsEqual(Color col1, Color col2); // Check if two colors are equal
|
||||
|
|
@ -1477,7 +1486,7 @@ RLAPI Color ColorAlpha(Color color, float alpha); // G
|
|||
RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint
|
||||
RLAPI Color ColorLerp(Color color1, Color color2, float factor); // Get color lerp interpolation between two colors, factor [0.0f..1.0f]
|
||||
RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value
|
||||
RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
|
||||
RLAPI Color GetPixelColor(const void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
|
||||
RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer
|
||||
RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes for certain format
|
||||
|
||||
|
|
@ -1488,10 +1497,10 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
|
|||
// Font loading/unloading functions
|
||||
RLAPI Font GetFontDefault(void); // Get the default Font
|
||||
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
|
||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
|
||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, int codepointCount); // Load font from file with defined codepoints and generation size, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
|
||||
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
|
||||
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
|
||||
RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked)
|
||||
RLAPI bool IsFontValid(Font font); // Check if font is valid (font data loaded, WARNING: GPU texture not checked)
|
||||
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount, int type, int *glyphCount); // Load font data for further use
|
||||
RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
|
||||
RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM)
|
||||
|
|
@ -1504,7 +1513,7 @@ RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color co
|
|||
RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters
|
||||
RLAPI void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation)
|
||||
RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint)
|
||||
RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint)
|
||||
RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple characters (codepoint)
|
||||
|
||||
// Text font info functions
|
||||
RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks
|
||||
|
|
@ -1532,7 +1541,7 @@ RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size);
|
|||
RLAPI char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
|
||||
RLAPI void UnloadTextLines(char **text, int lineCount); // Unload text lines
|
||||
RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied
|
||||
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
|
||||
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text strings are equal
|
||||
RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending
|
||||
RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style)
|
||||
RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string
|
||||
|
|
@ -1564,21 +1573,21 @@ RLAPI float TextToFloat(const char *text);
|
|||
RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
|
||||
RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line
|
||||
RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
|
||||
RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
|
||||
RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle, counter-clockwise vertex order
|
||||
RLAPI void DrawTriangleStrip3D(const Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points
|
||||
RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
|
||||
RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
|
||||
RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires
|
||||
RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version)
|
||||
RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
|
||||
RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
|
||||
RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with defined rings and slices
|
||||
RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
|
||||
RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
|
||||
RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color); // Draw a cylinder/cone
|
||||
RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos
|
||||
RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
|
||||
RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color); // Draw a cylinder/cone wires
|
||||
RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos
|
||||
RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos
|
||||
RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos
|
||||
RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int rings, int slices, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos
|
||||
RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int rings, int slices, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos
|
||||
RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
|
||||
RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line
|
||||
RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
|
||||
|
|
@ -1590,19 +1599,19 @@ RLAPI void DrawGrid(int slices, float spacing);
|
|||
// Model management functions
|
||||
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
|
||||
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
|
||||
RLAPI bool IsModelValid(Model model); // Check if a model is valid (loaded in GPU, VAO/VBOs)
|
||||
RLAPI bool IsModelValid(Model model); // Check if model is valid (loaded in GPU, VAO/VBOs)
|
||||
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
|
||||
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
|
||||
|
||||
// Model drawing functions
|
||||
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with custom transform
|
||||
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
|
||||
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
||||
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires with custom transform
|
||||
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
|
||||
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
|
||||
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
|
||||
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation
|
||||
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle rec, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by rectangle
|
||||
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle rec, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source rectangle with scaling and rotation
|
||||
|
||||
// Mesh management functions
|
||||
RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids
|
||||
|
|
@ -1631,7 +1640,7 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
|
|||
// Material loading/unloading functions
|
||||
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
|
||||
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
|
||||
RLAPI bool IsMaterialValid(Material material); // Check if a material is valid (shader assigned, map textures loaded in GPU)
|
||||
RLAPI bool IsMaterialValid(Material material); // Check if material is valid (shader assigned, map textures loaded in GPU)
|
||||
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
|
||||
RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
|
||||
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
|
||||
|
|
@ -1668,15 +1677,15 @@ RLAPI float GetMasterVolume(void); // Get mas
|
|||
// Wave/Sound loading/unloading functions
|
||||
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
|
||||
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
|
||||
RLAPI bool IsWaveValid(Wave wave); // Checks if wave data is valid (data loaded and parameters)
|
||||
RLAPI bool IsWaveValid(Wave wave); // Check if wave data is valid (data loaded and parameters)
|
||||
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
|
||||
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
|
||||
RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data
|
||||
RLAPI bool IsSoundValid(Sound sound); // Checks if a sound is valid (data loaded and buffers initialized)
|
||||
RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data (default data format: 32 bit float, stereo)
|
||||
RLAPI Sound LoadSoundAlias(Sound source); // Load sound alias, new sound that shares the same sample data as the source sound, does not own the sound data
|
||||
RLAPI bool IsSoundValid(Sound sound); // Check if sound is valid (data loaded and buffers initialized)
|
||||
RLAPI void UpdateSound(Sound sound, const void *data, int frameCount); // Update sound buffer with new data (default data format: 32 bit float, stereo)
|
||||
RLAPI void UnloadWave(Wave wave); // Unload wave data
|
||||
RLAPI void UnloadSound(Sound sound); // Unload sound
|
||||
RLAPI void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data)
|
||||
RLAPI void UnloadSoundAlias(Sound alias); // Unload sound alias (does not deallocate sample data)
|
||||
RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success
|
||||
RLAPI bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success
|
||||
|
||||
|
|
@ -1685,7 +1694,7 @@ RLAPI void PlaySound(Sound sound); // Play a
|
|||
RLAPI void StopSound(Sound sound); // Stop playing a sound
|
||||
RLAPI void PauseSound(Sound sound); // Pause a sound
|
||||
RLAPI void ResumeSound(Sound sound); // Resume a paused sound
|
||||
RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
|
||||
RLAPI bool IsSoundPlaying(Sound sound); // Check if sound is currently playing
|
||||
RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
|
||||
RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
|
||||
RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (-1.0 left, 0.0 center, 1.0 right)
|
||||
|
|
@ -1698,24 +1707,24 @@ RLAPI void UnloadWaveSamples(float *samples); // Unload
|
|||
// Music management functions
|
||||
RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
|
||||
RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data
|
||||
RLAPI bool IsMusicValid(Music music); // Checks if a music stream is valid (context and buffers initialized)
|
||||
RLAPI bool IsMusicValid(Music music); // Check if music stream is valid (context and buffers initialized)
|
||||
RLAPI void UnloadMusicStream(Music music); // Unload music stream
|
||||
RLAPI void PlayMusicStream(Music music); // Start music playing
|
||||
RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing
|
||||
RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming
|
||||
RLAPI void UpdateMusicStream(Music music); // Update buffers for music streaming
|
||||
RLAPI void StopMusicStream(Music music); // Stop music playing
|
||||
RLAPI void PauseMusicStream(Music music); // Pause music playing
|
||||
RLAPI void ResumeMusicStream(Music music); // Resume playing paused music
|
||||
RLAPI void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds)
|
||||
RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level)
|
||||
RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level)
|
||||
RLAPI void SetMusicPan(Music music, float pan); // Set pan for a music (-1.0 left, 0.0 center, 1.0 right)
|
||||
RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for music (1.0 is base level)
|
||||
RLAPI void SetMusicPan(Music music, float pan); // Set pan for music (-1.0 left, 0.0 center, 1.0 right)
|
||||
RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds)
|
||||
RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
|
||||
|
||||
// AudioStream management functions
|
||||
RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
|
||||
RLAPI bool IsAudioStreamValid(AudioStream stream); // Checks if an audio stream is valid (buffers initialized)
|
||||
RLAPI bool IsAudioStreamValid(AudioStream stream); // Check if an audio stream is valid (buffers initialized)
|
||||
RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
|
||||
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data
|
||||
RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
||||
|
|
@ -1726,7 +1735,7 @@ RLAPI bool IsAudioStreamPlaying(AudioStream stream); // Check i
|
|||
RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream
|
||||
RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level)
|
||||
RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level)
|
||||
RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (-1.0 to 1.0 range, 0.0 is centered)
|
||||
RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (-1.0 left, 0.0 center, 1.0 right)
|
||||
RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
|
||||
RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
||||
* raymath v2.0 - Math functions to work with Vector2, Vector3, Vector4, Matrix and Quaternions
|
||||
*
|
||||
* CONVENTIONS:
|
||||
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
|
||||
|
|
@ -2714,13 +2714,13 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
|||
stabilizer = fmaxf(stabilizer, fabsf(matColumns[i].y));
|
||||
stabilizer = fmaxf(stabilizer, fabsf(matColumns[i].z));
|
||||
}
|
||||
matColumns[0] = Vector3Scale(matColumns[0], 1.0f / stabilizer);
|
||||
matColumns[1] = Vector3Scale(matColumns[1], 1.0f / stabilizer);
|
||||
matColumns[2] = Vector3Scale(matColumns[2], 1.0f / stabilizer);
|
||||
matColumns[0] = Vector3Scale(matColumns[0], 1.0f/stabilizer);
|
||||
matColumns[1] = Vector3Scale(matColumns[1], 1.0f/stabilizer);
|
||||
matColumns[2] = Vector3Scale(matColumns[2], 1.0f/stabilizer);
|
||||
|
||||
// X Scale
|
||||
scl.x = Vector3Length(matColumns[0]);
|
||||
if (scl.x > eps) matColumns[0] = Vector3Scale(matColumns[0], 1.0f / scl.x);
|
||||
if (scl.x > eps) matColumns[0] = Vector3Scale(matColumns[0], 1.0f/scl.x);
|
||||
|
||||
// Compute XY shear and make col2 orthogonal
|
||||
shear[0] = Vector3DotProduct(matColumns[0], matColumns[1]);
|
||||
|
|
@ -2730,7 +2730,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
|||
scl.y = Vector3Length(matColumns[1]);
|
||||
if (scl.y > eps)
|
||||
{
|
||||
matColumns[1] = Vector3Scale(matColumns[1], 1.0f / scl.y);
|
||||
matColumns[1] = Vector3Scale(matColumns[1], 1.0f/scl.y);
|
||||
shear[0] /= scl.y; // Correct XY shear
|
||||
}
|
||||
|
||||
|
|
@ -2744,7 +2744,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
|||
scl.z = Vector3Length(matColumns[2]);
|
||||
if (scl.z > eps)
|
||||
{
|
||||
matColumns[2] = Vector3Scale(matColumns[2], 1.0f / scl.z);
|
||||
matColumns[2] = Vector3Scale(matColumns[2], 1.0f/scl.z);
|
||||
shear[1] /= scl.z; // Correct XZ shear
|
||||
shear[2] /= scl.z; // Correct YZ shear
|
||||
}
|
||||
|
|
@ -2802,6 +2802,11 @@ inline const Vector2& operator -= (Vector2& lhs, const Vector2& rhs)
|
|||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator * (const float& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Scale(rhs, lhs);
|
||||
}
|
||||
|
||||
inline Vector2 operator * (const Vector2& lhs, const float& rhs)
|
||||
{
|
||||
return Vector2Scale(lhs, rhs);
|
||||
|
|
@ -2896,6 +2901,11 @@ inline const Vector3& operator -= (Vector3& lhs, const Vector3& rhs)
|
|||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator * (const float& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Scale(rhs, lhs);
|
||||
}
|
||||
|
||||
inline Vector3 operator * (const Vector3& lhs, const float& rhs)
|
||||
{
|
||||
return Vector3Scale(lhs, rhs);
|
||||
|
|
@ -2991,6 +3001,11 @@ inline const Vector4& operator -= (Vector4& lhs, const Vector4& rhs)
|
|||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator * (const float& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Scale(rhs, lhs);
|
||||
}
|
||||
|
||||
inline Vector4 operator * (const Vector4& lhs, const float& rhs)
|
||||
{
|
||||
return Vector4Scale(lhs, rhs);
|
||||
|
|
|
|||
240
src/rcore.c
240
src/rcore.c
|
|
@ -106,7 +106,7 @@
|
|||
|
||||
#include "config.h" // Defines module configuration flags
|
||||
|
||||
#include <stdlib.h> // Required for: srand(), rand(), atexit(), exit()
|
||||
#include <stdlib.h> // Required for: srand(), rand(), exit()
|
||||
#include <stdio.h> // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose(), sprintf() [Used in OpenURL()]
|
||||
#include <string.h> // Required for: strlen(), strncpy(), strcmp(), strrchr(), memset(), strcat()
|
||||
#include <stdarg.h> // Required for: va_list, va_start(), va_end() [Used in TraceLog()]
|
||||
|
|
@ -385,7 +385,7 @@ typedef struct CoreData {
|
|||
double draw; // Time measure for frame draw (seconds)
|
||||
double frame; // Time measure for one frame (seconds)
|
||||
double target; // Desired time for one frame, if 0 not applied (seconds)
|
||||
unsigned long long int base; // Base time measure for hi-res timer (ticks or nanoseconds)
|
||||
unsigned long long base; // Base time measure for hi-res timer (ticks or nanoseconds)
|
||||
unsigned int frameCounter; // Frame counter (frames)
|
||||
|
||||
} Time;
|
||||
|
|
@ -442,18 +442,6 @@ typedef enum AutomationEventType {
|
|||
ACTION_SETTARGETFPS // param[0]: fps
|
||||
} AutomationEventType;
|
||||
|
||||
// Event type to config events flags
|
||||
// WARNING: Not used at the moment
|
||||
typedef enum {
|
||||
EVENT_INPUT_KEYBOARD = 0,
|
||||
EVENT_INPUT_MOUSE = 1,
|
||||
EVENT_INPUT_GAMEPAD = 2,
|
||||
EVENT_INPUT_TOUCH = 4,
|
||||
EVENT_INPUT_GESTURE = 8,
|
||||
EVENT_WINDOW = 16,
|
||||
EVENT_CUSTOM = 32
|
||||
} EventType;
|
||||
|
||||
// Event type name strings, required for export
|
||||
static const char *autoEventTypeName[] = {
|
||||
"EVENT_NONE",
|
||||
|
|
@ -482,16 +470,6 @@ static const char *autoEventTypeName[] = {
|
|||
"ACTION_SETTARGETFPS"
|
||||
};
|
||||
|
||||
/*
|
||||
// Automation event (24 bytes)
|
||||
// NOTE: Opaque struct, internal to raylib
|
||||
struct AutomationEvent {
|
||||
unsigned int frame; // Event frame
|
||||
unsigned int type; // Event type (AutomationEventType)
|
||||
int params[4]; // Event parameters (if required)
|
||||
};
|
||||
*/
|
||||
|
||||
static AutomationEventList *currentEventList = NULL; // Current automation events list, set by user, keep internal pointer
|
||||
static bool automationEventRecording = false; // Recording automation events flag
|
||||
//static short automationEventEnabled = 0b0000001111111111; // TODO: Automation events enabled for recording/playing
|
||||
|
|
@ -528,11 +506,11 @@ __declspec(dllimport) void __stdcall Sleep(unsigned long msTimeout); // Required
|
|||
const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
|
||||
#endif
|
||||
|
||||
// NOTE: PLATFORM_DESKTOP defaults to GLFW backend
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define PLATFORM_DESKTOP_GLFW
|
||||
#endif
|
||||
|
||||
|
||||
// Include platform-specific submodules
|
||||
#if defined(PLATFORM_DESKTOP_GLFW)
|
||||
#include "platforms/rcore_desktop_glfw.c"
|
||||
|
|
@ -869,14 +847,14 @@ bool IsCursorOnScreen(void)
|
|||
// Module Functions Definition: Screen Drawing
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Set background color (framebuffer clear color)
|
||||
// Clear background (framebuffer) to color
|
||||
void ClearBackground(Color color)
|
||||
{
|
||||
rlClearColor(color.r, color.g, color.b, color.a); // Set clear color
|
||||
rlClearScreenBuffers(); // Clear current framebuffers
|
||||
}
|
||||
|
||||
// Setup canvas (framebuffer) to start drawing
|
||||
// Begin canvas (framebuffer) drawing
|
||||
void BeginDrawing(void)
|
||||
{
|
||||
// WARNING: Previously to BeginDrawing() other render textures drawing could happen,
|
||||
|
|
@ -893,7 +871,7 @@ void BeginDrawing(void)
|
|||
// NOTE: Not required with OpenGL 3.3+
|
||||
}
|
||||
|
||||
// End canvas drawing and swap buffers (double buffering)
|
||||
// End canvas (framebuffer) drawing and swap buffers (double buffering)
|
||||
void EndDrawing(void)
|
||||
{
|
||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||
|
|
@ -949,7 +927,7 @@ void BeginMode2D(Camera2D camera)
|
|||
rlMultMatrixf(MatrixToFloat(GetCameraMatrix2D(camera)));
|
||||
}
|
||||
|
||||
// Ends 2D mode with custom camera
|
||||
// End 2D mode with custom camera
|
||||
void EndMode2D(void)
|
||||
{
|
||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||
|
|
@ -998,7 +976,7 @@ void BeginMode3D(Camera camera)
|
|||
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
|
||||
}
|
||||
|
||||
// Ends 3D mode and returns to default 2D orthographic mode
|
||||
// End 3D mode and returns to default 2D orthographic mode
|
||||
void EndMode3D(void)
|
||||
{
|
||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||
|
|
@ -1045,7 +1023,7 @@ void BeginTextureMode(RenderTexture2D target)
|
|||
CORE.Window.usingFbo = true;
|
||||
}
|
||||
|
||||
// Ends drawing to render texture
|
||||
// End drawing to render texture
|
||||
void EndTextureMode(void)
|
||||
{
|
||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||
|
|
@ -1315,7 +1293,7 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
|||
return shader;
|
||||
}
|
||||
|
||||
// Check if a shader is valid (loaded on GPU)
|
||||
// Check if shader is valid (loaded on GPU)
|
||||
bool IsShaderValid(Shader shader)
|
||||
{
|
||||
return ((shader.id > 0) && // Validate shader id (GPU loaded successfully)
|
||||
|
|
@ -1514,7 +1492,7 @@ Matrix GetCameraMatrix2D(Camera2D camera)
|
|||
return matTransform;
|
||||
}
|
||||
|
||||
// Get the screen space position from a 3d world space position
|
||||
// Get screen space position from a 3d world space position
|
||||
Vector2 GetWorldToScreen(Vector3 position, Camera camera)
|
||||
{
|
||||
Vector2 screenPosition = GetWorldToScreenEx(position, camera, GetScreenWidth(), GetScreenHeight());
|
||||
|
|
@ -1522,7 +1500,7 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera)
|
|||
return screenPosition;
|
||||
}
|
||||
|
||||
// Get size position for a 3d world space position (useful for texture drawing)
|
||||
// Get sized screen space position for a 3d world space position (useful for texture drawing)
|
||||
Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height)
|
||||
{
|
||||
// Calculate projection matrix (from perspective instead of frustum
|
||||
|
|
@ -1564,7 +1542,7 @@ Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int heigh
|
|||
return screenPosition;
|
||||
}
|
||||
|
||||
// Get the screen space position for a 2d camera world space position
|
||||
// Get screen space position for a 2d camera world space position
|
||||
Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera)
|
||||
{
|
||||
Matrix matCamera = GetCameraMatrix2D(camera);
|
||||
|
|
@ -1573,7 +1551,7 @@ Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera)
|
|||
return (Vector2){ transform.x, transform.y };
|
||||
}
|
||||
|
||||
// Get the world space position for a 2d camera screen space position
|
||||
// Get world space position for a 2d camera screen space position
|
||||
Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera)
|
||||
{
|
||||
Matrix invMatCamera = MatrixInvert(GetCameraMatrix2D(camera));
|
||||
|
|
@ -1757,9 +1735,9 @@ int GetRandomValue(int min, int max)
|
|||
else
|
||||
{
|
||||
// Rejection sampling to get a uniform integer in [min, max]
|
||||
unsigned long c = (unsigned long)RAND_MAX + 1UL; // number of possible rand() results
|
||||
unsigned long m = (unsigned long)range; // size of the target interval
|
||||
unsigned long t = c - (c%m); // largest multiple of m <= c
|
||||
unsigned long c = (unsigned long)RAND_MAX + 1UL; // Number of possible results
|
||||
unsigned long m = (unsigned long)range; // Size of the target interval
|
||||
unsigned long t = c - (c%m); // Largest multiple of m <= c
|
||||
unsigned long r = 0;
|
||||
|
||||
for (;;)
|
||||
|
|
@ -1853,7 +1831,7 @@ void TakeScreenshot(const char *fileName)
|
|||
#endif
|
||||
}
|
||||
|
||||
// Setup window configuration flags (view FLAGS)
|
||||
// Set up window configuration flags (view FLAGS)
|
||||
// NOTE: This function is expected to be called before window creation,
|
||||
// because it sets up some flags for the window creation process
|
||||
// To configure window states after creation, use SetWindowState()
|
||||
|
|
@ -1992,7 +1970,7 @@ unsigned char *LoadFileData(const char *fileName, int *dataSize)
|
|||
size_t count = fread(data, sizeof(unsigned char), size, file);
|
||||
|
||||
// WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation)
|
||||
// dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) there is a limitation
|
||||
// dataSize is unified along raylib as a 'int' type, so, for file-sizes >INT_MAX (2147483647 bytes) there is a limitation
|
||||
if (count > 2147483647)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName);
|
||||
|
|
@ -2004,7 +1982,7 @@ unsigned char *LoadFileData(const char *fileName, int *dataSize)
|
|||
{
|
||||
*dataSize = (int)count;
|
||||
|
||||
if ((*dataSize) != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded (%i bytes out of %i)", fileName, dataSize, count);
|
||||
if ((*dataSize) != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded (%i bytes out of %i)", fileName, *dataSize, size);
|
||||
else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName);
|
||||
}
|
||||
}
|
||||
|
|
@ -2028,7 +2006,7 @@ void UnloadFileData(unsigned char *data)
|
|||
}
|
||||
|
||||
// Save data to file from buffer
|
||||
bool SaveFileData(const char *fileName, void *data, int dataSize)
|
||||
bool SaveFileData(const char *fileName, const void *data, int dataSize)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
|
|
@ -2227,13 +2205,12 @@ void SetSaveFileTextCallback(SaveFileTextCallback callback)
|
|||
// NOTE: Only rename file name required, not full path
|
||||
int FileRename(const char *fileName, const char *fileRename)
|
||||
{
|
||||
int result = 0;
|
||||
int result = -1;
|
||||
|
||||
if (FileExists(fileName))
|
||||
{
|
||||
result = rename(fileName, fileRename);
|
||||
}
|
||||
else result = -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2241,13 +2218,12 @@ int FileRename(const char *fileName, const char *fileRename)
|
|||
// Remove file (if exists)
|
||||
int FileRemove(const char *fileName)
|
||||
{
|
||||
int result = 0;
|
||||
int result = -1;
|
||||
|
||||
if (FileExists(fileName))
|
||||
{
|
||||
result = remove(fileName);
|
||||
}
|
||||
else result = -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2256,18 +2232,21 @@ int FileRemove(const char *fileName)
|
|||
// NOTE: If destination path does not exist, it is created!
|
||||
int FileCopy(const char *srcPath, const char *dstPath)
|
||||
{
|
||||
int result = 0;
|
||||
int result = -1;
|
||||
int srcDataSize = 0;
|
||||
unsigned char *srcFileData = LoadFileData(srcPath, &srcDataSize);
|
||||
|
||||
// Create required paths if they do not exist
|
||||
if (!DirectoryExists(GetDirectoryPath(dstPath)))
|
||||
result = MakeDirectory(GetDirectoryPath(dstPath));
|
||||
if (DirectoryExists(GetDirectoryPath(dstPath))) result = 0; // Already exists
|
||||
else result = MakeDirectory(GetDirectoryPath(dstPath));
|
||||
|
||||
if (result == 0) // Directory created successfully (or already exists)
|
||||
if (result == 0) // Directory created successfully or already exists
|
||||
{
|
||||
if ((srcFileData != NULL) && (srcDataSize > 0))
|
||||
result = SaveFileData(dstPath, srcFileData, srcDataSize);
|
||||
{
|
||||
bool saved = SaveFileData(dstPath, srcFileData, srcDataSize);
|
||||
if (saved) result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
UnloadFileData(srcFileData);
|
||||
|
|
@ -2283,8 +2262,18 @@ int FileMove(const char *srcPath, const char *dstPath)
|
|||
|
||||
if (FileExists(srcPath))
|
||||
{
|
||||
if (FileCopy(srcPath, dstPath) == 0) result = FileRemove(srcPath);
|
||||
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to copy file to [%s]", srcPath, dstPath);
|
||||
result = FileCopy(srcPath, dstPath);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
// Make sure file has been correctly copied before removing
|
||||
if (FileExists(dstPath) && (GetFileLength(srcPath) == GetFileLength(dstPath)))
|
||||
{
|
||||
result = FileRemove(srcPath);
|
||||
if (result != 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to remove source file after copy", srcPath);
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to copy file to [%s]", srcPath, dstPath);
|
||||
}
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Source file does not exist", srcPath);
|
||||
|
||||
|
|
@ -2295,16 +2284,18 @@ int FileMove(const char *srcPath, const char *dstPath)
|
|||
// WARNING: DEPENDENCY: [rtext] module
|
||||
int FileTextReplace(const char *fileName, const char *search, const char *replacement)
|
||||
{
|
||||
int result = 0;
|
||||
int result = -1;
|
||||
|
||||
#if SUPPORT_MODULE_RTEXT
|
||||
char *fileText = NULL;
|
||||
char *fileTextUpdated = { 0 };
|
||||
|
||||
#if SUPPORT_MODULE_RTEXT
|
||||
if (FileExists(fileName))
|
||||
{
|
||||
fileText = LoadFileText(fileName);
|
||||
fileTextUpdated = TextReplaceAlloc(fileText, search, replacement);
|
||||
result = SaveFileText(fileName, fileTextUpdated);
|
||||
bool saved = SaveFileText(fileName, fileTextUpdated);
|
||||
if (saved) result = 0;
|
||||
MemFree(fileTextUpdated);
|
||||
UnloadFileText(fileText);
|
||||
}
|
||||
|
|
@ -2337,7 +2328,7 @@ bool FileExists(const char *fileName)
|
|||
{
|
||||
bool result = false;
|
||||
|
||||
if (ACCESS(fileName) != -1) result = true;
|
||||
if ((fileName != NULL) && (ACCESS(fileName) != -1)) result = true;
|
||||
|
||||
// NOTE: Alternatively, stat() can be used instead of access()
|
||||
//#include <sys/stat.h>
|
||||
|
|
@ -2362,8 +2353,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
|||
{
|
||||
int fileExtLength = (int)strlen(fileExt);
|
||||
char fileExtLower[16] = { 0 };
|
||||
char *fileExtLowerPtr = fileExtLower;
|
||||
for (int i = 0; (i < fileExtLength) && (i < 16); i++)
|
||||
for (int i = 0; (i < fileExtLength) && (i < 15); i++)
|
||||
{
|
||||
// Copy and convert to lower-case
|
||||
if ((fileExt[i] >= 'A') && (fileExt[i] <= 'Z')) fileExtLower[i] = fileExt[i] + 32;
|
||||
|
|
@ -2374,7 +2364,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
|||
int extLength = (int)strlen(ext);
|
||||
char *extList = (char *)RL_CALLOC(extLength + 1, 1);
|
||||
char *extListPtrs[MAX_FILE_EXTENSIONS] = { 0 };
|
||||
strncpy(extList, ext, extLength);
|
||||
memcpy(extList, ext, extLength);
|
||||
extListPtrs[0] = extList;
|
||||
|
||||
for (int i = 0; i < extLength; i++)
|
||||
|
|
@ -2383,11 +2373,15 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
|||
if ((extList[i] >= 'A') && (extList[i] <= 'Z')) extList[i] += 32;
|
||||
|
||||
// Get pointer to next extension and add null-terminator
|
||||
if ((extList[i] == ';') && (extCount < (MAX_FILE_EXTENSIONS - 1)))
|
||||
if (extList[i] == ';')
|
||||
{
|
||||
extList[i] = '\0';
|
||||
extListPtrs[extCount] = extList + i + 1;
|
||||
extCount++;
|
||||
|
||||
if (extCount < MAX_FILE_EXTENSIONS)
|
||||
{
|
||||
extListPtrs[extCount] = extList + i + 1;
|
||||
extCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2395,7 +2389,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
|||
{
|
||||
// Consider the case where extension provided
|
||||
// does not start with the '.'
|
||||
fileExtLowerPtr = fileExtLower;
|
||||
char *fileExtLowerPtr = fileExtLower;
|
||||
if (extListPtrs[i][0] != '.') fileExtLowerPtr++;
|
||||
|
||||
if (strcmp(fileExtLowerPtr, extListPtrs[i]) == 0)
|
||||
|
|
@ -2411,7 +2405,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
|||
return result;
|
||||
}
|
||||
|
||||
// Check if a directory path exists
|
||||
// Check if directory path exists
|
||||
bool DirectoryExists(const char *dirPath)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -2608,7 +2602,7 @@ const char *GetWorkingDirectory(void)
|
|||
static char currentDir[MAX_FILEPATH_LENGTH] = { 0 };
|
||||
memset(currentDir, 0, MAX_FILEPATH_LENGTH);
|
||||
|
||||
char *path = GETCWD(currentDir, MAX_FILEPATH_LENGTH - 1);
|
||||
char *path = GETCWD(currentDir, MAX_FILEPATH_LENGTH);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
|
@ -2816,17 +2810,19 @@ int MakeDirectory(const char *dirPath)
|
|||
}
|
||||
|
||||
// Change working directory, returns true on success
|
||||
bool ChangeDirectory(const char *dirPath)
|
||||
int ChangeDirectory(const char *dirPath)
|
||||
{
|
||||
bool result = CHDIR(dirPath);
|
||||
// NOTE: On success, CHDIR() return 0; on error, returns -1 and errno is set to indicate the error,
|
||||
// depending on the filesystem, other errors can be returned
|
||||
int result = CHDIR(dirPath);
|
||||
|
||||
if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dirPath);
|
||||
else TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", dirPath);
|
||||
|
||||
return (result == 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if a given path point to a file
|
||||
// Check if given path point to a file
|
||||
bool IsPathFile(const char *path)
|
||||
{
|
||||
struct stat result = { 0 };
|
||||
|
|
@ -2891,7 +2887,7 @@ bool IsFileNameValid(const char *fileName)
|
|||
return valid;
|
||||
}
|
||||
|
||||
// Check if a file has been dropped into window
|
||||
// Check if file has been dropped into window
|
||||
bool IsFileDropped(void)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -2955,9 +2951,9 @@ unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, b
|
|||
{
|
||||
// Construct new path from our base path
|
||||
#if defined(_WIN32)
|
||||
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, entity->d_name);
|
||||
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH, "%s\\%s", basePath, entity->d_name);
|
||||
#else
|
||||
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, entity->d_name);
|
||||
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH, "%s/%s", basePath, entity->d_name);
|
||||
#endif
|
||||
// Don't add to count if path too long
|
||||
if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH))
|
||||
|
|
@ -3160,7 +3156,7 @@ unsigned char *DecodeDataBase64(const char *text, int *outputSize)
|
|||
}
|
||||
|
||||
// Compute CRC32 hash code
|
||||
unsigned int ComputeCRC32(unsigned char *data, int dataSize)
|
||||
unsigned int ComputeCRC32(const unsigned char *data, int dataSize)
|
||||
{
|
||||
static unsigned int crcTable[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
|
|
@ -3206,7 +3202,7 @@ unsigned int ComputeCRC32(unsigned char *data, int dataSize)
|
|||
|
||||
// Compute MD5 hash code
|
||||
// NOTE: Returns a static int[4] array (16 bytes)
|
||||
unsigned int *ComputeMD5(unsigned char *data, int dataSize)
|
||||
unsigned int *ComputeMD5(const unsigned char *data, int dataSize)
|
||||
{
|
||||
#define ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
|
||||
|
||||
|
|
@ -3324,7 +3320,7 @@ unsigned int *ComputeMD5(unsigned char *data, int dataSize)
|
|||
|
||||
// Compute SHA-1 hash code
|
||||
// NOTE: Returns a static int[5] array (20 bytes)
|
||||
unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
|
||||
unsigned int *ComputeSHA1(const unsigned char *data, int dataSize)
|
||||
{
|
||||
#define SHA1_ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
|
||||
|
||||
|
|
@ -3352,15 +3348,15 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
|
|||
memcpy(msg, data, dataSize);
|
||||
msg[dataSize] = 128; // Write the '1' bit
|
||||
|
||||
unsigned long long bitsLen = 8ULL * dataSize;
|
||||
msg[newDataSize-1] = (unsigned char)(bitsLen);
|
||||
msg[newDataSize-2] = (unsigned char)(bitsLen >> 8);
|
||||
msg[newDataSize-3] = (unsigned char)(bitsLen >> 16);
|
||||
msg[newDataSize-4] = (unsigned char)(bitsLen >> 24);
|
||||
msg[newDataSize-5] = (unsigned char)(bitsLen >> 32);
|
||||
msg[newDataSize-6] = (unsigned char)(bitsLen >> 40);
|
||||
msg[newDataSize-7] = (unsigned char)(bitsLen >> 48);
|
||||
msg[newDataSize-8] = (unsigned char)(bitsLen >> 56);
|
||||
unsigned long long bitsLen = 8ULL*dataSize;
|
||||
msg[newDataSize - 1] = (unsigned char)(bitsLen);
|
||||
msg[newDataSize - 2] = (unsigned char)(bitsLen >> 8);
|
||||
msg[newDataSize - 3] = (unsigned char)(bitsLen >> 16);
|
||||
msg[newDataSize - 4] = (unsigned char)(bitsLen >> 24);
|
||||
msg[newDataSize - 5] = (unsigned char)(bitsLen >> 32);
|
||||
msg[newDataSize - 6] = (unsigned char)(bitsLen >> 40);
|
||||
msg[newDataSize - 7] = (unsigned char)(bitsLen >> 48);
|
||||
msg[newDataSize - 8] = (unsigned char)(bitsLen >> 56);
|
||||
|
||||
// Process the message in successive 512-bit chunks
|
||||
for (int offset = 0; offset < newDataSize; offset += (512/8))
|
||||
|
|
@ -3434,7 +3430,7 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
|
|||
|
||||
// Compute SHA-256 hash code
|
||||
// NOTE: Returns a static int[8] array (32 bytes)
|
||||
unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
|
||||
unsigned int *ComputeSHA256(const unsigned char *data, int dataSize)
|
||||
{
|
||||
#define SHA256_ROTATE_RIGHT(x, c) ((x >> c) | (x << ((sizeof(unsigned int)*8) - c)))
|
||||
#define SHA256_A0(x) (SHA256_ROTATE_RIGHT(x, 7) ^ SHA256_ROTATE_RIGHT(x, 18) ^ (x >> 3))
|
||||
|
|
@ -3469,8 +3465,8 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
|
|||
hash[6] = 0x1f83d9ab;
|
||||
hash[7] = 0x5be0cd19;
|
||||
|
||||
const unsigned long long int bitLen = ((unsigned long long int)dataSize)*8;
|
||||
unsigned long long int paddedSize = dataSize + sizeof(dataSize);
|
||||
const unsigned long long bitLen = 8ULL*dataSize;
|
||||
unsigned long long paddedSize = dataSize + sizeof(dataSize);
|
||||
paddedSize += (64 - (paddedSize%64));
|
||||
unsigned char *buffer = (unsigned char *)RL_CALLOC(paddedSize, sizeof(unsigned char));
|
||||
|
||||
|
|
@ -3481,7 +3477,7 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
|
|||
buffer[(paddedSize - sizeof(bitLen)) + (i - 1)] = (bitLen >> (8*(sizeof(bitLen) - i))) & 0xFF;
|
||||
}
|
||||
|
||||
for (unsigned long long int blockN = 0; blockN < paddedSize/64; blockN++)
|
||||
for (unsigned long long blockN = 0; blockN < paddedSize/64; blockN++)
|
||||
{
|
||||
unsigned int a = hash[0];
|
||||
unsigned int b = hash[1];
|
||||
|
|
@ -3503,7 +3499,7 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
|
|||
}
|
||||
for (int t = 16; t < 64; t++) w[t] = SHA256_A1(w[t - 2]) + w[t - 7] + SHA256_A0(w[t - 15]) + w[t - 16];
|
||||
|
||||
for (unsigned long long int t = 0; t < 64; t++)
|
||||
for (int t = 0; t < 64; t++)
|
||||
{
|
||||
unsigned int e1 = (SHA256_ROTATE_RIGHT(e, 6) ^ SHA256_ROTATE_RIGHT(e, 11) ^ SHA256_ROTATE_RIGHT(e, 25));
|
||||
unsigned int ch = ((e & f) ^ (~e & g));
|
||||
|
|
@ -3802,7 +3798,7 @@ void PlayAutomationEvent(AutomationEvent event)
|
|||
// Module Functions Definition: Input Handling: Keyboard
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Check if a key has been pressed once
|
||||
// Check if key has been pressed once
|
||||
bool IsKeyPressed(int key)
|
||||
{
|
||||
bool pressed = false;
|
||||
|
|
@ -3815,7 +3811,7 @@ bool IsKeyPressed(int key)
|
|||
return pressed;
|
||||
}
|
||||
|
||||
// Check if a key has been pressed again
|
||||
// Check if key has been pressed again
|
||||
bool IsKeyPressedRepeat(int key)
|
||||
{
|
||||
bool repeat = false;
|
||||
|
|
@ -3828,7 +3824,7 @@ bool IsKeyPressedRepeat(int key)
|
|||
return repeat;
|
||||
}
|
||||
|
||||
// Check if a key is being pressed (key held down)
|
||||
// Check if key is being pressed (key held down)
|
||||
bool IsKeyDown(int key)
|
||||
{
|
||||
bool down = false;
|
||||
|
|
@ -3841,7 +3837,7 @@ bool IsKeyDown(int key)
|
|||
return down;
|
||||
}
|
||||
|
||||
// Check if a key has been released once
|
||||
// Check if key has been released once
|
||||
bool IsKeyReleased(int key)
|
||||
{
|
||||
bool released = false;
|
||||
|
|
@ -3854,7 +3850,7 @@ bool IsKeyReleased(int key)
|
|||
return released;
|
||||
}
|
||||
|
||||
// Check if a key is NOT being pressed (key not held down)
|
||||
// Check if key is NOT being pressed (key not held down)
|
||||
bool IsKeyUp(int key)
|
||||
{
|
||||
bool up = false;
|
||||
|
|
@ -3925,12 +3921,12 @@ void SetExitKey(int key)
|
|||
// NOTE: Functions with a platform-specific implementation on rcore_<platform>.c
|
||||
//int SetGamepadMappings(const char *mappings)
|
||||
|
||||
// Check if a gamepad is available
|
||||
// Check if gamepad is available
|
||||
bool IsGamepadAvailable(int gamepad)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
|
||||
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -3938,15 +3934,19 @@ bool IsGamepadAvailable(int gamepad)
|
|||
// Get gamepad internal name id
|
||||
const char *GetGamepadName(int gamepad)
|
||||
{
|
||||
return CORE.Input.Gamepad.name[gamepad];
|
||||
const char *name = NULL;
|
||||
|
||||
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS)) name = CORE.Input.Gamepad.name[gamepad];
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
// Check if a gamepad button has been pressed once
|
||||
// Check if gamepad button has been pressed once
|
||||
bool IsGamepadButtonPressed(int gamepad, int button)
|
||||
{
|
||||
bool pressed = false;
|
||||
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
|
||||
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
|
||||
{
|
||||
if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) pressed = true;
|
||||
}
|
||||
|
|
@ -3954,12 +3954,12 @@ bool IsGamepadButtonPressed(int gamepad, int button)
|
|||
return pressed;
|
||||
}
|
||||
|
||||
// Check if a gamepad button is being pressed
|
||||
// Check if gamepad button is being pressed
|
||||
bool IsGamepadButtonDown(int gamepad, int button)
|
||||
{
|
||||
bool down = false;
|
||||
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
|
||||
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
|
||||
{
|
||||
if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1) down = true;
|
||||
}
|
||||
|
|
@ -3967,12 +3967,12 @@ bool IsGamepadButtonDown(int gamepad, int button)
|
|||
return down;
|
||||
}
|
||||
|
||||
// Check if a gamepad button has NOT been pressed once
|
||||
// Check if gamepad button has NOT been pressed once
|
||||
bool IsGamepadButtonReleased(int gamepad, int button)
|
||||
{
|
||||
bool released = false;
|
||||
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
|
||||
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
|
||||
{
|
||||
if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) released = true;
|
||||
}
|
||||
|
|
@ -3980,12 +3980,12 @@ bool IsGamepadButtonReleased(int gamepad, int button)
|
|||
return released;
|
||||
}
|
||||
|
||||
// Check if a gamepad button is NOT being pressed
|
||||
// Check if gamepad button is NOT being pressed
|
||||
bool IsGamepadButtonUp(int gamepad, int button)
|
||||
{
|
||||
bool up = false;
|
||||
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
|
||||
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
|
||||
{
|
||||
if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0) up = true;
|
||||
}
|
||||
|
|
@ -4003,7 +4003,11 @@ int GetGamepadButtonPressed(void)
|
|||
// Get gamepad axis count
|
||||
int GetGamepadAxisCount(int gamepad)
|
||||
{
|
||||
return CORE.Input.Gamepad.axisCount[gamepad];
|
||||
int result = 0;
|
||||
|
||||
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS)) result = CORE.Input.Gamepad.axisCount[gamepad];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get axis movement vector for a gamepad
|
||||
|
|
@ -4011,7 +4015,7 @@ float GetGamepadAxisMovement(int gamepad, int axis)
|
|||
{
|
||||
float value = ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))? -1.0f : 0.0f;
|
||||
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXES))
|
||||
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXES))
|
||||
{
|
||||
float movement = (value < 0.0f)? CORE.Input.Gamepad.axisState[gamepad][axis] : fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]);
|
||||
|
||||
|
|
@ -4029,7 +4033,7 @@ float GetGamepadAxisMovement(int gamepad, int axis)
|
|||
//void SetMousePosition(int x, int y)
|
||||
//void SetMouseCursor(int cursor)
|
||||
|
||||
// Check if a mouse button has been pressed once
|
||||
// Check if mouse button has been pressed once
|
||||
bool IsMouseButtonPressed(int button)
|
||||
{
|
||||
bool pressed = false;
|
||||
|
|
@ -4045,7 +4049,7 @@ bool IsMouseButtonPressed(int button)
|
|||
return pressed;
|
||||
}
|
||||
|
||||
// Check if a mouse button is being pressed
|
||||
// Check if mouse button is being pressed
|
||||
bool IsMouseButtonDown(int button)
|
||||
{
|
||||
bool down = false;
|
||||
|
|
@ -4061,7 +4065,7 @@ bool IsMouseButtonDown(int button)
|
|||
return down;
|
||||
}
|
||||
|
||||
// Check if a mouse button has been released once
|
||||
// Check if mouse button has been released once
|
||||
bool IsMouseButtonReleased(int button)
|
||||
{
|
||||
bool released = false;
|
||||
|
|
@ -4077,7 +4081,7 @@ bool IsMouseButtonReleased(int button)
|
|||
return released;
|
||||
}
|
||||
|
||||
// Check if a mouse button is NOT being pressed
|
||||
// Check if mouse button is NOT being pressed
|
||||
bool IsMouseButtonUp(int button)
|
||||
{
|
||||
bool up = false;
|
||||
|
|
@ -4235,7 +4239,7 @@ void InitTimer(void)
|
|||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success
|
||||
{
|
||||
CORE.Time.base = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec;
|
||||
CORE.Time.base = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "TIMER: Hi-resolution timer not available");
|
||||
#endif
|
||||
|
|
@ -4283,9 +4287,9 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
|
|||
{
|
||||
// Construct new path from our base path
|
||||
#if defined(_WIN32)
|
||||
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, dp->d_name);
|
||||
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH, "%s\\%s", basePath, dp->d_name);
|
||||
#else
|
||||
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, dp->d_name);
|
||||
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH, "%s/%s", basePath, dp->d_name);
|
||||
#endif
|
||||
|
||||
if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH))
|
||||
|
|
@ -4297,7 +4301,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
|
|||
if ((filter == NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL) ||
|
||||
(strstr(filter, FILE_FILTER_TAG_FILE_ONLY) != NULL) || IsFileExtension(path, filter))
|
||||
{
|
||||
strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1);
|
||||
memcpy(files->paths[files->count], path, pathLength);
|
||||
files->count++;
|
||||
}
|
||||
}
|
||||
|
|
@ -4305,7 +4309,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
|
|||
{
|
||||
if ((filter != NULL) && ((strstr(filter, FILE_FILTER_TAG_DIR_ONLY) != NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL)))
|
||||
{
|
||||
strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1);
|
||||
memcpy(files->paths[files->count], path, pathLength);
|
||||
files->count++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,10 +59,13 @@
|
|||
// NOTE: Below types are required for standalone usage
|
||||
//----------------------------------------------------------------------------------
|
||||
// Boolean type
|
||||
#if !defined(__cplusplus)
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
||||
#elif !defined(bool)
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#define RL_BOOL_TYPE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(RL_VECTOR2_TYPE)
|
||||
|
|
@ -124,7 +127,7 @@ void UpdateGestures(void); // Update gestures detec
|
|||
|
||||
#if defined(RGESTURES_STANDALONE)
|
||||
void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
bool IsGestureDetected(int gesture); // Check if a gesture has been detected
|
||||
bool IsGestureDetected(int gesture); // Check if gesture has been detected
|
||||
int GetGestureDetected(void); // Get latest detected gesture
|
||||
|
||||
float GetGestureHoldDuration(void); // Get gesture hold time in seconds
|
||||
|
|
@ -154,8 +157,8 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
|
|||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
// Functions required to query time on Windows
|
||||
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
|
||||
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
|
||||
int __stdcall QueryPerformanceCounter(unsigned long long *lpPerformanceCount);
|
||||
int __stdcall QueryPerformanceFrequency(unsigned long long *lpFrequency);
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
@ -254,7 +257,7 @@ void SetGesturesEnabled(unsigned int flags)
|
|||
GESTURES.enabledFlags = flags;
|
||||
}
|
||||
|
||||
// Check if a gesture have been detected
|
||||
// Check if gesture have been detected
|
||||
bool IsGestureDetected(unsigned int gesture)
|
||||
{
|
||||
if ((GESTURES.enabledFlags & GESTURES.current) == gesture) return true;
|
||||
|
|
@ -515,37 +518,36 @@ static double rgGetCurrentTime(void)
|
|||
time = GetTime();
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
unsigned long long int clockFrequency, currentTime;
|
||||
unsigned long long clockFrequency = 0;
|
||||
unsigned long long currentClockTicks = 0;
|
||||
|
||||
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
QueryPerformanceCounter(¤tClockTicks);
|
||||
|
||||
time = (double)currentTime/clockFrequency; // Time in seconds
|
||||
time = (double)currentClockTicks/clockFrequency; // Time in seconds
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
// NOTE: Only for Linux-based systems
|
||||
struct timespec now;
|
||||
struct timespec now = { 0 };
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
|
||||
unsigned long long nanoSeconds = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
|
||||
|
||||
time = ((double)nowTime*1e-9); // Time in seconds
|
||||
time = ((double)nanoSeconds*1e-9); // Time in seconds
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
//#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01
|
||||
//#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time
|
||||
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t now;
|
||||
clock_serv_t cclock = { 0 };
|
||||
mach_timespec_t now = { 0 };
|
||||
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
|
||||
|
||||
// NOTE: OS X does not have clock_gettime(), using clock_get_time()
|
||||
clock_get_time(cclock, &now);
|
||||
mach_port_deallocate(mach_task_self(), cclock);
|
||||
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
|
||||
unsigned long long nanoSeconds = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
|
||||
|
||||
time = ((double)nowTime*1e-9); // Time in seconds
|
||||
time = ((double)nanoSeconds*1e-9); // Time in seconds
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
|||
120
src/rlgl.h
120
src/rlgl.h
|
|
@ -56,8 +56,8 @@
|
|||
* #define RL_CULL_DISTANCE_NEAR 0.05 // Default projection matrix near cull distance
|
||||
* #define RL_CULL_DISTANCE_FAR 4000.0 // Default projection matrix far cull distance
|
||||
*
|
||||
* When loading a shader, the following vertex attributes and uniform
|
||||
* location names are tried to be set automatically:
|
||||
* When loading a shader, the following vertex attributes and uniform location names are tried to be set automatically:
|
||||
* WARNING: Pre-defined names can not be changed, they are used by default shaders and all raylib examples shaders, they are just listed here for reference
|
||||
*
|
||||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
|
||||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
|
||||
|
|
@ -67,6 +67,8 @@
|
|||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
|
||||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES
|
||||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
|
||||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
|
||||
*
|
||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
|
||||
|
|
@ -74,6 +76,7 @@
|
|||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)))
|
||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices
|
||||
*
|
||||
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
||||
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
|
||||
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
|
||||
|
|
@ -324,6 +327,7 @@
|
|||
#define RL_DRAW_FRAMEBUFFER 0x8CA9 // GL_DRAW_FRAMEBUFFER
|
||||
|
||||
// Default shader vertex attribute locations
|
||||
// NOTE: Locations can be redefined by user if required
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
|
||||
#endif
|
||||
|
|
@ -358,11 +362,13 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
#if !defined(__cplusplus)
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
||||
// Boolean type
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#elif !defined(bool)
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#define RL_BOOL_TYPE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(RL_MATRIX_TYPE)
|
||||
|
|
@ -894,7 +900,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
|||
// It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi
|
||||
// provided headers (despite being defined in official Khronos GLES2 headers)
|
||||
// TODO: Avoid raylib platform-dependent code on rlgl, it should be a completely portable library
|
||||
#if defined(PLATFORM_DRM)
|
||||
#if defined(PLATFORM_DRM) // Use CONFIG_DRM?
|
||||
typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
|
||||
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor);
|
||||
|
|
@ -991,65 +997,28 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
|||
#endif
|
||||
|
||||
// Default shader vertex attribute names to set location points
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
|
||||
#endif
|
||||
// WARNING: Pre-defined names can not be changed, they are used by default shaders and all raylib examples shaders, they are just listed here for reference
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
|
||||
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
|
||||
#endif
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices (required for GPU skinning)
|
||||
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices (required for GPU skinning)
|
||||
#endif
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Types and Structures Definition
|
||||
|
|
@ -1235,7 +1204,11 @@ void rlMatrixMode(int mode)
|
|||
// Push the current matrix into RLGL.State.stack
|
||||
void rlPushMatrix(void)
|
||||
{
|
||||
if (RLGL.State.stackCounter >= RL_MAX_MATRIX_STACK_SIZE) TRACELOG(RL_LOG_ERROR, "RLGL: Matrix stack overflow (RL_MAX_MATRIX_STACK_SIZE)");
|
||||
if (RLGL.State.stackCounter >= RL_MAX_MATRIX_STACK_SIZE)
|
||||
{
|
||||
TRACELOG(RL_LOG_ERROR, "RLGL: Matrix stack overflow (RL_MAX_MATRIX_STACK_SIZE)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (RLGL.State.currentMatrixMode == RL_MODELVIEW)
|
||||
{
|
||||
|
|
@ -3366,8 +3339,15 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
|
|||
// Texture parameters configuration
|
||||
// NOTE: glTexParameteri does NOT affect texture uploading
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
||||
// Check if texture is power-of-two (POT)
|
||||
bool texIsPOT = false;
|
||||
|
||||
if (((width > 0) && ((width & (width - 1)) == 0)) &&
|
||||
((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true;
|
||||
|
||||
// NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used
|
||||
if (RLGL.ExtSupported.texNPOT)
|
||||
if ((texIsPOT) || (RLGL.ExtSupported.texNPOT))
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis
|
||||
|
|
@ -3638,7 +3618,7 @@ void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned
|
|||
case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_ARB; break;
|
||||
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_ARB; break;
|
||||
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_ARB; break;
|
||||
#else // defined(GRAPHICS_API_OPENGL_ES2)
|
||||
#else // GRAPHICS_API_OPENGL_ES2
|
||||
case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
|
||||
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
|
||||
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
|
||||
|
|
@ -3768,9 +3748,17 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
|
|||
// Attach our texture to FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0);
|
||||
|
||||
#if defined(FBO_READ_TEXTURE_AS_RGBA)
|
||||
// Reading data as RGBA because FBO texture is configured as RGBA, despite binding another texture format
|
||||
pixels = RL_CALLOC(rlGetPixelDataSize(width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8), 1);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
#else
|
||||
// Reading data as original texture format, in some platforms (RPI, Wasm) it works
|
||||
pixels = (unsigned char *)RL_MALLOC(GetPixelDataSize(width, height, format));
|
||||
unsigned int glInternalFormat = 0, glFormat = 0, glType = 0;
|
||||
rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
|
||||
glReadPixels(0, 0, width, height, glFormat, glType, pixels);
|
||||
#endif
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
|
|
|
|||
224
src/rmodels.c
224
src/rmodels.c
|
|
@ -85,7 +85,7 @@
|
|||
#define VOX_FREE RL_FREE
|
||||
|
||||
#define VOX_LOADER_IMPLEMENTATION
|
||||
#include "external/vox_loader.h" // VOX file format loading (MagikaVoxel)
|
||||
#include "external/vox_loader.h" // VOX file format loading (MagicaVoxel)
|
||||
#endif
|
||||
|
||||
#if SUPPORT_FILEFORMAT_M3D
|
||||
|
|
@ -435,7 +435,7 @@ void DrawSphere(Vector3 centerPos, float radius, Color color)
|
|||
DrawSphereEx(centerPos, radius, 16, 16, color);
|
||||
}
|
||||
|
||||
// Draw sphere with extended parameters
|
||||
// Draw sphere with defined rings and slices
|
||||
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color)
|
||||
{
|
||||
#if 0
|
||||
|
|
@ -724,9 +724,9 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
|
|||
|
||||
// Draw a wired cylinder with base at startPos and top at endPos
|
||||
// NOTE: It could be also used for pyramid and cone
|
||||
void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color)
|
||||
void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int slices, Color color)
|
||||
{
|
||||
if (sides < 3) sides = 3;
|
||||
if (slices < 3) slices = 3;
|
||||
|
||||
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
|
||||
if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0)) return; // Security check
|
||||
|
|
@ -735,12 +735,12 @@ void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, fl
|
|||
Vector3 b1 = Vector3Normalize(Vector3Perpendicular(direction));
|
||||
Vector3 b2 = Vector3Normalize(Vector3CrossProduct(b1, direction));
|
||||
|
||||
float baseAngle = (2.0f*PI)/sides;
|
||||
float baseAngle = (2.0f*PI)/slices;
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
for (int i = 0; i < sides; i++)
|
||||
for (int i = 0; i < slices; i++)
|
||||
{
|
||||
// Compute the four vertices
|
||||
float s1 = sinf(baseAngle*(i + 0))*startRadius;
|
||||
|
|
@ -769,10 +769,10 @@ void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, fl
|
|||
}
|
||||
|
||||
// Draw a capsule with the center of its sphere caps at startPos and endPos
|
||||
void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color)
|
||||
void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int rings, int slices, Color color)
|
||||
{
|
||||
if (slices < 3) slices = 3;
|
||||
|
||||
if (rings < 1) rings = 1;
|
||||
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
|
||||
|
||||
// draw a sphere if start and end points are the same
|
||||
|
|
@ -908,10 +908,10 @@ void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int
|
|||
}
|
||||
|
||||
// Draw capsule wires with the center of its sphere caps at startPos and endPos
|
||||
void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color)
|
||||
void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int rings, int slices, Color color)
|
||||
{
|
||||
if (slices < 3) slices = 3;
|
||||
|
||||
if (rings < 1) rings = 1;
|
||||
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
|
||||
|
||||
// draw a sphere if start and end points are the same
|
||||
|
|
@ -1167,7 +1167,7 @@ Model LoadModelFromMesh(Mesh mesh)
|
|||
return model;
|
||||
}
|
||||
|
||||
// Check if a model is valid (loaded in GPU, VAO/VBOs)
|
||||
// Check if model is valid (loaded in GPU, VAO/VBOs)
|
||||
bool IsModelValid(Model model)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -1182,16 +1182,17 @@ bool IsModelValid(Model model)
|
|||
// but some VBOs could not be used, it depends on Mesh vertex data
|
||||
for (int i = 0; i < model.meshCount; i++)
|
||||
{
|
||||
if ((model.meshes[i].vertices != NULL) && (model.meshes[i].vboId[0] == 0)) { result = false; break; } // Vertex position buffer not uploaded to GPU
|
||||
if ((model.meshes[i].vertices != NULL) && (model.meshes[i].vboId[0] == 0)) { result = false; break; } // Vertex position buffer not uploaded to GPU
|
||||
if ((model.meshes[i].texcoords != NULL) && (model.meshes[i].vboId[1] == 0)) { result = false; break; } // Vertex textcoords buffer not uploaded to GPU
|
||||
if ((model.meshes[i].normals != NULL) && (model.meshes[i].vboId[2] == 0)) { result = false; break; } // Vertex normals buffer not uploaded to GPU
|
||||
if ((model.meshes[i].colors != NULL) && (model.meshes[i].vboId[3] == 0)) { result = false; break; } // Vertex colors buffer not uploaded to GPU
|
||||
if ((model.meshes[i].tangents != NULL) && (model.meshes[i].vboId[4] == 0)) { result = false; break; } // Vertex tangents buffer not uploaded to GPU
|
||||
if ((model.meshes[i].texcoords2 != NULL) && (model.meshes[i].vboId[5] == 0)) { result = false; break; } // Vertex texcoords2 buffer not uploaded to GPU
|
||||
if ((model.meshes[i].indices != NULL) && (model.meshes[i].vboId[6] == 0)) { result = false; break; } // Vertex indices buffer not uploaded to GPU
|
||||
if ((model.meshes[i].boneIndices != NULL) && (model.meshes[i].vboId[7] == 0)) { result = false; break; } // Vertex boneIndices buffer not uploaded to GPU
|
||||
if ((model.meshes[i].boneWeights != NULL) && (model.meshes[i].vboId[8] == 0)) { result = false; break; } // Vertex boneWeights buffer not uploaded to GPU
|
||||
|
||||
if ((model.meshes[i].normals != NULL) && (model.meshes[i].vboId[2] == 0)) { result = false; break; } // Vertex normals buffer not uploaded to GPU
|
||||
if ((model.meshes[i].colors != NULL) && (model.meshes[i].vboId[3] == 0)) { result = false; break; } // Vertex colors buffer not uploaded to GPU
|
||||
if ((model.meshes[i].tangents != NULL) && (model.meshes[i].vboId[4] == 0)) { result = false; break; } // Vertex tangents buffer not uploaded to GPU
|
||||
if ((model.meshes[i].texcoords2 != NULL) && (model.meshes[i].vboId[5] == 0)) { result = false; break; } // Vertex texcoords2 buffer not uploaded to GPU
|
||||
if ((model.meshes[i].indices != NULL) && (model.meshes[i].vboId[6] == 0)) { result = false; break; } // Vertex indices buffer not uploaded to GPU
|
||||
#if SUPPORT_GPU_SKINNING
|
||||
if ((model.meshes[i].boneIndices != NULL) && (model.meshes[i].vboId[7] == 0)) { result = false; break; } // Vertex boneIndices buffer not uploaded to GPU
|
||||
if ((model.meshes[i].boneWeights != NULL) && (model.meshes[i].vboId[8] == 0)) { result = false; break; } // Vertex boneWeights buffer not uploaded to GPU
|
||||
#endif
|
||||
// NOTE: Some OpenGL versions do not support VAO, so avoid below check
|
||||
//if (model.meshes[i].vaoId == 0) { result = false; break }
|
||||
}
|
||||
|
|
@ -1221,6 +1222,8 @@ void UnloadModel(Model model)
|
|||
// Unload animation data
|
||||
RL_FREE(model.skeleton.bones);
|
||||
RL_FREE(model.skeleton.bindPose);
|
||||
RL_FREE(model.currentPose);
|
||||
RL_FREE(model.boneMatrices);
|
||||
|
||||
TRACELOG(LOG_INFO, "MODEL: Unloaded model (and meshes) from RAM and VRAM");
|
||||
}
|
||||
|
|
@ -2227,7 +2230,7 @@ Material LoadMaterialDefault(void)
|
|||
return material;
|
||||
}
|
||||
|
||||
// Check if a material is valid (map textures loaded in GPU)
|
||||
// Check if material is valid (map textures loaded in GPU)
|
||||
bool IsMaterialValid(Material material)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -3139,6 +3142,8 @@ Mesh GenMeshCone(float radius, float height, int slices)
|
|||
}
|
||||
|
||||
// Generate torus mesh
|
||||
// NOTE: The distance between the center of the hole and the center of the
|
||||
// tube is half size of the radius of the tube (radius*size/2)
|
||||
Mesh GenMeshTorus(float radius, float size, int radSeg, int sides)
|
||||
{
|
||||
Mesh mesh = { 0 };
|
||||
|
|
@ -3915,7 +3920,7 @@ void DrawModel(Model model, Vector3 position, float scale, Color tint)
|
|||
DrawModelEx(model, position, rotationAxis, 0.0f, vScale, tint);
|
||||
}
|
||||
|
||||
// Draw a model with extended parameters
|
||||
// Draw a model with custom transform
|
||||
void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||
{
|
||||
// Calculate transformation matrix from function parameters
|
||||
|
|
@ -3935,7 +3940,7 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
|
|||
Color colDiffuse = mat.maps[MATERIAL_MAP_DIFFUSE].color;
|
||||
|
||||
// Applying color tint directly to material diffuse map,
|
||||
// because is comes as an input paramter to the function
|
||||
// because it comes as an input parameter to the function
|
||||
Color colTinted = { 0 };
|
||||
colTinted.r = (unsigned char)(((int)colDiffuse.r*(int)tint.r)/255);
|
||||
colTinted.g = (unsigned char)(((int)colDiffuse.g*(int)tint.g)/255);
|
||||
|
|
@ -3969,7 +3974,7 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
|
|||
rlDisableWireMode();
|
||||
}
|
||||
|
||||
// Draw a model wires (with texture if set) with extended parameters
|
||||
// Draw a model wires with custom transform
|
||||
void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||
{
|
||||
rlEnableWireMode();
|
||||
|
|
@ -3982,22 +3987,22 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float
|
|||
// Draw a billboard
|
||||
void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint)
|
||||
{
|
||||
Rectangle source = { 0.0f, 0.0f, (float)texture.width, (float)texture.height };
|
||||
Rectangle rec = { 0.0f, 0.0f, (float)texture.width, (float)texture.height };
|
||||
|
||||
DrawBillboardRec(camera, texture, source, position, (Vector2){ scale*fabsf((float)source.width/source.height), scale }, tint);
|
||||
DrawBillboardRec(camera, texture, rec, position, (Vector2){ scale*fabsf((float)rec.width/rec.height), scale }, tint);
|
||||
}
|
||||
|
||||
// Draw a billboard (part of a texture defined by a rectangle)
|
||||
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint)
|
||||
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle rec, Vector3 position, Vector2 size, Color tint)
|
||||
{
|
||||
// NOTE: Billboard locked on axis-Y
|
||||
Vector3 up = { 0.0f, 1.0f, 0.0f };
|
||||
|
||||
DrawBillboardPro(camera, texture, source, position, up, size, Vector2Scale(size, 0.5), 0.0f, tint);
|
||||
DrawBillboardPro(camera, texture, rec, position, up, size, Vector2Scale(size, 0.5), 0.0f, tint);
|
||||
}
|
||||
|
||||
// Draw a billboard with additional parameters
|
||||
void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint)
|
||||
// Draw a billboard texture defined by source rectangle with scaling and rotation
|
||||
void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle rec, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint)
|
||||
{
|
||||
// Compute the up vector and the right vector
|
||||
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
|
|
@ -4008,20 +4013,20 @@ void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector
|
|||
// Flip the content of the billboard while maintaining the counterclockwise edge rendering order
|
||||
if (size.x < 0.0f)
|
||||
{
|
||||
source.x -= size.x;
|
||||
source.width *= -1.0;
|
||||
rec.x -= size.x;
|
||||
rec.width *= -1.0;
|
||||
right = Vector3Negate(right);
|
||||
origin.x *= -1.0f;
|
||||
}
|
||||
if (size.y < 0.0f)
|
||||
{
|
||||
source.y -= size.y;
|
||||
source.height *= -1.0;
|
||||
rec.y -= size.y;
|
||||
rec.height *= -1.0;
|
||||
up = Vector3Negate(up);
|
||||
origin.y *= -1.0f;
|
||||
}
|
||||
|
||||
// Draw the texture region described by source on the following rectangle in 3D space:
|
||||
// Draw the texture region described by rec on the following rectangle in 3D space:
|
||||
//
|
||||
// size.x <--.
|
||||
// 3 ^---------------------------+ 2 \ rotation
|
||||
|
|
@ -4053,10 +4058,10 @@ void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector
|
|||
}
|
||||
|
||||
Vector2 texcoords[4];
|
||||
texcoords[0] = (Vector2){ (float)source.x/texture.width, (float)(source.y + source.height)/texture.height };
|
||||
texcoords[1] = (Vector2){ (float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height };
|
||||
texcoords[2] = (Vector2){ (float)(source.x + source.width)/texture.width, (float)source.y/texture.height };
|
||||
texcoords[3] = (Vector2){ (float)source.x/texture.width, (float)source.y/texture.height };
|
||||
texcoords[0] = (Vector2){ (float)rec.x/texture.width, (float)(rec.y + rec.height)/texture.height };
|
||||
texcoords[1] = (Vector2){ (float)(rec.x + rec.width)/texture.width, (float)(rec.y + rec.height)/texture.height };
|
||||
texcoords[2] = (Vector2){ (float)(rec.x + rec.width)/texture.width, (float)rec.y/texture.height };
|
||||
texcoords[3] = (Vector2){ (float)rec.x/texture.width, (float)rec.y/texture.height };
|
||||
|
||||
rlSetTexture(texture.id);
|
||||
rlBegin(RL_QUADS);
|
||||
|
|
@ -5374,16 +5379,18 @@ static BoneInfo *LoadBoneInfoGLTF(cgltf_skin skin, int *boneCount)
|
|||
cgltf_node node = *skin.joints[i];
|
||||
if (node.name != NULL) strncpy(bones[i].name, node.name, sizeof(bones[i].name) - 1);
|
||||
|
||||
// Find parent bone index
|
||||
// Find parent bone index by walking up the node tree past any
|
||||
// non-joint ancestors (intermediate transform nodes used by some
|
||||
// DCC exporters), until we hit a node that is also in skin.joints.
|
||||
int parentIndex = -1;
|
||||
|
||||
for (unsigned int j = 0; j < skin.joints_count; j++)
|
||||
cgltf_node *ancestor = node.parent;
|
||||
while (ancestor != NULL && parentIndex == -1)
|
||||
{
|
||||
if (skin.joints[j] == node.parent)
|
||||
for (unsigned int j = 0; j < skin.joints_count; j++)
|
||||
{
|
||||
parentIndex = (int)j;
|
||||
break;
|
||||
if (skin.joints[j] == ancestor) { parentIndex = (int)j; break; }
|
||||
}
|
||||
if (parentIndex == -1) ancestor = ancestor->parent;
|
||||
}
|
||||
|
||||
bones[i].parent = parentIndex;
|
||||
|
|
@ -6139,17 +6146,36 @@ static Model LoadGLTF(const char *fileName)
|
|||
|
||||
for (int i = 0; i < model.skeleton.boneCount; i++)
|
||||
{
|
||||
cgltf_node *node = skin.joints[i];
|
||||
cgltf_float worldTransform[16];
|
||||
cgltf_node_transform_world(node, worldTransform);
|
||||
Matrix worldMatrix = {
|
||||
worldTransform[0], worldTransform[4], worldTransform[8], worldTransform[12],
|
||||
worldTransform[1], worldTransform[5], worldTransform[9], worldTransform[13],
|
||||
worldTransform[2], worldTransform[6], worldTransform[10], worldTransform[14],
|
||||
worldTransform[3], worldTransform[7], worldTransform[11], worldTransform[15]
|
||||
};
|
||||
Matrix bindMatrix = { 0 };
|
||||
cgltf_float inverseBindTransform[16] = { 0 };
|
||||
|
||||
MatrixDecompose(worldMatrix,
|
||||
if ((skin.inverse_bind_matrices != NULL) &&
|
||||
(skin.inverse_bind_matrices->count >= skin.joints_count) &&
|
||||
cgltf_accessor_read_float(skin.inverse_bind_matrices, i, inverseBindTransform, 16))
|
||||
{
|
||||
Matrix inverseBindMatrix = {
|
||||
inverseBindTransform[0], inverseBindTransform[4], inverseBindTransform[8], inverseBindTransform[12],
|
||||
inverseBindTransform[1], inverseBindTransform[5], inverseBindTransform[9], inverseBindTransform[13],
|
||||
inverseBindTransform[2], inverseBindTransform[6], inverseBindTransform[10], inverseBindTransform[14],
|
||||
inverseBindTransform[3], inverseBindTransform[7], inverseBindTransform[11], inverseBindTransform[15]
|
||||
};
|
||||
bindMatrix = MatrixInvert(inverseBindMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
cgltf_float worldTransform[16] = { 0 };
|
||||
cgltf_node_transform_world(skin.joints[i], worldTransform);
|
||||
|
||||
Matrix worldMatrix = {
|
||||
worldTransform[0], worldTransform[4], worldTransform[8], worldTransform[12],
|
||||
worldTransform[1], worldTransform[5], worldTransform[9], worldTransform[13],
|
||||
worldTransform[2], worldTransform[6], worldTransform[10], worldTransform[14],
|
||||
worldTransform[3], worldTransform[7], worldTransform[11], worldTransform[15]
|
||||
};
|
||||
bindMatrix = worldMatrix;
|
||||
}
|
||||
|
||||
MatrixDecompose(bindMatrix,
|
||||
&(model.skeleton.bindPose[i].translation),
|
||||
&(model.skeleton.bindPose[i].rotation),
|
||||
&(model.skeleton.bindPose[i].scale));
|
||||
|
|
@ -6514,20 +6540,58 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
|
|||
if (data->skins_count > 0)
|
||||
{
|
||||
cgltf_skin skin = data->skins[0];
|
||||
|
||||
// Precompute, per joint, the static transform contributed by any
|
||||
// intermediate non-joint nodes between the joint and its nearest
|
||||
// joint ancestor. This handles exporters (e.g. wow.export) that
|
||||
// store bone offsets on dummy parent nodes rather than on the
|
||||
// joints themselves. Depends only on the skin, not the animation.
|
||||
int jointCount = (int)skin.joints_count;
|
||||
Matrix *extOffset = (Matrix *)RL_MALLOC(jointCount*sizeof(Matrix));
|
||||
|
||||
if (extOffset == NULL)
|
||||
{
|
||||
// Allocation failed: abort animation loading at the source rather than
|
||||
// propagating a NULL pointer into the per-frame transform loop below
|
||||
TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to allocate joint offset buffer", fileName);
|
||||
cgltf_free(data);
|
||||
UnloadFileData(fileData);
|
||||
*animCount = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*animCount = (int)data->animations_count;
|
||||
animations = (ModelAnimation *)RL_CALLOC(data->animations_count, sizeof(ModelAnimation));
|
||||
|
||||
Transform worldTransform = { 0 };
|
||||
cgltf_float cgltf_worldTransform[16] = { 0 };
|
||||
cgltf_node *node = skin.joints[0];
|
||||
cgltf_node_transform_world(node->parent, cgltf_worldTransform);
|
||||
Matrix worldMatrix = {
|
||||
cgltf_worldTransform[0], cgltf_worldTransform[4], cgltf_worldTransform[8], cgltf_worldTransform[12],
|
||||
cgltf_worldTransform[1], cgltf_worldTransform[5], cgltf_worldTransform[9], cgltf_worldTransform[13],
|
||||
cgltf_worldTransform[2], cgltf_worldTransform[6], cgltf_worldTransform[10], cgltf_worldTransform[14],
|
||||
cgltf_worldTransform[3], cgltf_worldTransform[7], cgltf_worldTransform[11], cgltf_worldTransform[15]
|
||||
};
|
||||
MatrixDecompose(worldMatrix, &worldTransform.translation, &worldTransform.rotation, &worldTransform.scale);
|
||||
for (int k = 0; k < jointCount; k++)
|
||||
{
|
||||
extOffset[k] = MatrixIdentity();
|
||||
cgltf_node *n = skin.joints[k]->parent;
|
||||
|
||||
while (n != NULL)
|
||||
{
|
||||
bool isJoint = false;
|
||||
for (int jj = 0; jj < jointCount; jj++)
|
||||
{
|
||||
if (skin.joints[jj] == n)
|
||||
{
|
||||
isJoint = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isJoint) break;
|
||||
|
||||
// Compose the intermediate node's local TRS (scale, then rotation, then translation)
|
||||
Matrix nodeScale = MatrixScale(n->scale[0], n->scale[1], n->scale[2]);
|
||||
Matrix nodeRotation = QuaternionToMatrix((Quaternion){ n->rotation[0], n->rotation[1], n->rotation[2], n->rotation[3] });
|
||||
Matrix nodeTranslation = MatrixTranslate(n->translation[0], n->translation[1], n->translation[2]);
|
||||
Matrix nodeTransform = MatrixMultiply(MatrixMultiply(nodeScale, nodeRotation), nodeTranslation);
|
||||
|
||||
extOffset[k] = MatrixMultiply(extOffset[k], nodeTransform);
|
||||
n = n->parent;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int a = 0; a < data->animations_count; a++)
|
||||
{
|
||||
|
|
@ -6636,19 +6700,19 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
|
|||
}
|
||||
}
|
||||
|
||||
animations[a].keyframePoses[j][k] = (Transform){
|
||||
.translation = translation,
|
||||
.rotation = rotation,
|
||||
.scale = scale
|
||||
};
|
||||
}
|
||||
// Compose joint local TRS, then prepend the static
|
||||
// intermediate non-joint offsets so the final TRS is
|
||||
// expressed relative to the joint's skeleton parent.
|
||||
Matrix S = MatrixScale(scale.x, scale.y, scale.z);
|
||||
Matrix R = QuaternionToMatrix(rotation);
|
||||
Matrix T = MatrixTranslate(translation.x, translation.y, translation.z);
|
||||
Matrix jointLocal = MatrixMultiply(MatrixMultiply(S, R), T);
|
||||
Matrix combined = MatrixMultiply(jointLocal, extOffset[k]);
|
||||
|
||||
Transform *root = &animations[a].keyframePoses[j][0];
|
||||
root->rotation = QuaternionMultiply(worldTransform.rotation, root->rotation);
|
||||
root->scale = Vector3Multiply(root->scale, worldTransform.scale);
|
||||
root->translation = Vector3Multiply(root->translation, worldTransform.scale);
|
||||
root->translation = Vector3RotateByQuaternion(root->translation, worldTransform.rotation);
|
||||
root->translation = Vector3Add(root->translation, worldTransform.translation);
|
||||
Transform tr;
|
||||
MatrixDecompose(combined, &tr.translation, &tr.rotation, &tr.scale);
|
||||
animations[a].keyframePoses[j][k] = tr;
|
||||
}
|
||||
|
||||
BuildPoseFromParentJoints(bones, animations[a].boneCount, animations[a].keyframePoses[j]);
|
||||
}
|
||||
|
|
@ -6657,6 +6721,8 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
|
|||
RL_FREE(boneChannels);
|
||||
RL_FREE(bones);
|
||||
}
|
||||
|
||||
RL_FREE(extOffset);
|
||||
}
|
||||
|
||||
if (data->skins_count > 1)
|
||||
|
|
@ -7148,7 +7214,7 @@ static Model LoadM3D(const char *fileName)
|
|||
return model;
|
||||
}
|
||||
|
||||
#define M3D_ANIMDELAY 17 // Animation frames delay, (~1000 ms/60 FPS = 16.666666* ms)
|
||||
#define M3D_ANIMDELAY 17 // Animation frames delay, (~1000 ms/60 FPS = 16.666666 ms)
|
||||
|
||||
// Load M3D animation data
|
||||
static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCount)
|
||||
|
|
|
|||
1057
src/rshapes.c
1057
src/rshapes.c
File diff suppressed because it is too large
Load Diff
45
src/rtext.c
45
src/rtext.c
|
|
@ -156,7 +156,7 @@ extern void LoadFontDefault(void)
|
|||
{
|
||||
#define BIT_CHECK(a,b) ((a) & (1u << (b)))
|
||||
|
||||
// Check to see if the font for an image has alreeady been allocated,
|
||||
// Check to see if the font for an image has already been allocated,
|
||||
// and if no need to upload, then return
|
||||
if (defaultFont.glyphs != NULL) return;
|
||||
|
||||
|
|
@ -327,7 +327,7 @@ extern void UnloadFontDefault(void)
|
|||
defaultFont.recs = NULL;
|
||||
}
|
||||
|
||||
// Get the default font, useful to be used with extended parameters
|
||||
// Get the default font
|
||||
Font GetFontDefault()
|
||||
{
|
||||
return defaultFont;
|
||||
|
|
@ -381,9 +381,9 @@ Font LoadFont(const char *fileName)
|
|||
return font;
|
||||
}
|
||||
|
||||
// Load Font from TTF or BDF font file with generation parameters
|
||||
// NOTE: You can pass an array with desired characters, those characters should be available in the font
|
||||
// if array is NULL, default char set is selected 32..126
|
||||
// Load font from file with defined codepoints and generation size
|
||||
// NOTE: NULL for codepoints and 0 for codepointCount to load the default character set (32..126),
|
||||
// font size is provided in pixels height
|
||||
Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, int codepointCount)
|
||||
{
|
||||
Font font = { 0 };
|
||||
|
|
@ -580,15 +580,20 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
|
|||
|
||||
TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", font.baseSize, font.glyphCount);
|
||||
}
|
||||
else font = GetFontDefault();
|
||||
else
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "FONT: Font is not supported by LoadFontEx/LoadFontFromMemory or no glyphs found, reverted to default font");
|
||||
font = GetFontDefault();
|
||||
}
|
||||
#else
|
||||
TRACELOG(LOG_WARNING, "FONT: Font is not supported by LoadFontEx/LoadFontFromMemory or no glyphs found, reverted to default font");
|
||||
font = GetFontDefault();
|
||||
#endif
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
// Check if a font is valid (font data loaded)
|
||||
// Check if font is valid (font data loaded)
|
||||
// WARNING: GPU texture not checked
|
||||
bool IsFontValid(Font font)
|
||||
{
|
||||
|
|
@ -678,7 +683,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
|||
// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
|
||||
// stbtt_MakeCodepointBitmap() -- renders into a provided bitmap
|
||||
|
||||
// Check if a glyph is available in the font
|
||||
// Check if glyph is available in the font
|
||||
// WARNING: if (index == 0), glyph not found, it could fallback to default .notdef glyph (if defined in font)
|
||||
int index = stbtt_FindGlyphIndex(&fontInfo, cp);
|
||||
|
||||
|
|
@ -942,8 +947,8 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp
|
|||
// Security fix: check both lower and upper bounds
|
||||
if (destX >= 0 && destX < atlas.width && destY >= 0 && destY < atlas.height)
|
||||
{
|
||||
((unsigned char *)atlas.data)[destY * atlas.width + destX] =
|
||||
((unsigned char *)glyphs[i].image.data)[y * glyphs[i].image.width + x];
|
||||
((unsigned char *)atlas.data)[destY*atlas.width + destX] =
|
||||
((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1279,7 +1284,7 @@ void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSiz
|
|||
DrawTexturePro(font.texture, srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint);
|
||||
}
|
||||
|
||||
// Draw multiple character (codepoints)
|
||||
// Draw multiple characters (codepoints)
|
||||
void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint)
|
||||
{
|
||||
float textOffsetY = 0; // Offset between lines (on linebreak '\n')
|
||||
|
|
@ -1674,7 +1679,7 @@ int TextCopy(char *dst, const char *src)
|
|||
return bytes;
|
||||
}
|
||||
|
||||
// Check if two text string are equal
|
||||
// Check if two text strings are equal
|
||||
// REQUIRES: strcmp()
|
||||
bool TextIsEqual(const char *text1, const char *text2)
|
||||
{
|
||||
|
|
@ -1724,7 +1729,7 @@ const char *TextRemoveSpaces(const char *text)
|
|||
if (text != NULL)
|
||||
{
|
||||
// Avoid copying the ' ' characters
|
||||
for (int i = 0, j = 0; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[j] != '\0'); i++)
|
||||
for (int i = 0, j = 0; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[i] != '\0'); i++)
|
||||
{
|
||||
if (text[i] != ' ') { buffer[j] = text[i]; j++; }
|
||||
}
|
||||
|
|
@ -1914,9 +1919,13 @@ char *TextReplaceBetween(const char *text, const char *begin, const char *end, c
|
|||
int replaceLen = (replacement == NULL)? 0 : TextLength(replacement);
|
||||
//int toreplaceLen = endIndex - beginIndex - beginLen;
|
||||
|
||||
strncpy(buffer, text, beginIndex + beginLen); // Copy first text part
|
||||
if (replacement != NULL) strncpy(buffer + beginIndex + beginLen, replacement, replaceLen); // Copy replacement (if provided)
|
||||
strncpy(buffer + beginIndex + beginLen + replaceLen, text + endIndex, textLen - endIndex); // Copy end text part
|
||||
if ((beginIndex + beginLen + replaceLen + (textLen - endIndex)) < (MAX_TEXT_BUFFER_LENGTH - 1))
|
||||
{
|
||||
strncpy(buffer, text, beginIndex + beginLen); // Copy first text part
|
||||
if (replacement != NULL) strncpy(buffer + beginIndex + beginLen, replacement, replaceLen); // Copy replacement (if provided)
|
||||
strncpy(buffer + beginIndex + beginLen + replaceLen, text + endIndex, textLen - endIndex); // Copy end text part
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "TEXT: Text with replaced string is longer than internal buffer (MAX_TEXT_BUFFER_LENGTH)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2667,8 +2676,8 @@ static Font LoadBMFont(const char *fileName)
|
|||
for (int i = 1; i < pageCount; i++)
|
||||
{
|
||||
Rectangle srcRec = { 0.0f, 0.0f, (float)imWidth, (float)imHeight };
|
||||
Rectangle destRec = { 0.0f, (float)imHeight*(float)i, (float)imWidth, (float)imHeight };
|
||||
ImageDraw(&fullFont, imFonts[i], srcRec, destRec, WHITE);
|
||||
Rectangle dstRec = { 0.0f, (float)imHeight*(float)i, (float)imWidth, (float)imHeight };
|
||||
ImageDrawImagePro(&fullFont, imFonts[i], srcRec, dstRec, (Vector2){ 0 }, 0.0f, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
452
src/rtextures.c
452
src/rtextures.c
|
|
@ -562,15 +562,18 @@ Image LoadImageFromTexture(Texture2D texture)
|
|||
{
|
||||
image.width = texture.width;
|
||||
image.height = texture.height;
|
||||
#if defined(FBO_READ_TEXTURE_AS_RGBA)
|
||||
// WARNING: On OpenGL ES 2.0/WebGL 1.0, there is no glGetTexImage() so,
|
||||
// texture data is retrieved by creating an RGBA fbo, binding the texture
|
||||
// to the fbo color attachment, and reading it as RGBA data with glReadPixels()
|
||||
// Returned data *should* be RGBA but it seems on some platforms (RPI, WASM)
|
||||
// original texture format is retrieved, so adding a define for this patch
|
||||
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
||||
#else
|
||||
image.format = texture.format;
|
||||
#endif
|
||||
image.mipmaps = 1;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: Data retrieved on OpenGL ES 2.0 should be RGBA,
|
||||
// coming from FBO color buffer attachment, but it seems
|
||||
// original texture format is retrieved on RPI...
|
||||
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
||||
#endif
|
||||
TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Pixel data retrieved successfully", texture.id);
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] Failed to retrieve pixel data", texture.id);
|
||||
|
|
@ -580,7 +583,7 @@ Image LoadImageFromTexture(Texture2D texture)
|
|||
return image;
|
||||
}
|
||||
|
||||
// Load image from screen buffer and (screenshot)
|
||||
// Load image from screen buffer (screenshot)
|
||||
Image LoadImageFromScreen(void)
|
||||
{
|
||||
Image image = { 0 };
|
||||
|
|
@ -1500,7 +1503,8 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
|
|||
if ((codepoint != ' ') && (codepoint != '\t'))
|
||||
{
|
||||
Rectangle rec = { (float)(textOffsetX + font.glyphs[index].offsetX), (float)(textOffsetY + font.glyphs[index].offsetY), (float)font.recs[index].width, (float)font.recs[index].height };
|
||||
ImageDraw(&imText, font.glyphs[index].image, (Rectangle){ 0, 0, (float)font.glyphs[index].image.width, (float)font.glyphs[index].image.height }, rec, tint);
|
||||
ImageDrawImagePro(&imText, font.glyphs[index].image, (Rectangle){ 0, 0, (float)font.glyphs[index].image.width, (float)font.glyphs[index].image.height },
|
||||
rec, (Vector2){ 0 }, 0.0f, tint);
|
||||
}
|
||||
|
||||
if (font.glyphs[index].advanceX == 0) textOffsetX += (int)(font.recs[index].width + spacing);
|
||||
|
|
@ -1744,7 +1748,7 @@ void ImageResize(Image *image, int newWidth, int newHeight)
|
|||
// Security check to avoid program crash
|
||||
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
|
||||
|
||||
// Check if a fast path can be used on image scaling
|
||||
// Check if fast path can be used on image scaling
|
||||
// It can be for 8 bit per channel images with 1 to 4 channels per pixel
|
||||
if ((image->format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) ||
|
||||
(image->format == PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) ||
|
||||
|
|
@ -2795,7 +2799,7 @@ void ImageColorGrayscale(Image *image)
|
|||
|
||||
// Modify image color: contrast
|
||||
// NOTE: Contrast values between -100 and 100
|
||||
void ImageColorContrast(Image *image, float contrast)
|
||||
void ImageColorContrast(Image *image, int contrast)
|
||||
{
|
||||
// Security check to avoid program crash
|
||||
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
|
||||
|
|
@ -2803,8 +2807,8 @@ void ImageColorContrast(Image *image, float contrast)
|
|||
if (contrast < -100) contrast = -100;
|
||||
if (contrast > 100) contrast = 100;
|
||||
|
||||
contrast = (100.0f + contrast)/100.0f;
|
||||
contrast *= contrast;
|
||||
float factor = (float)(100.0f + contrast)/100.0f;
|
||||
factor *= factor;
|
||||
|
||||
Color *pixels = LoadImageColors(*image);
|
||||
|
||||
|
|
@ -2812,7 +2816,7 @@ void ImageColorContrast(Image *image, float contrast)
|
|||
{
|
||||
float pR = (float)pixels[i].r/255.0f;
|
||||
pR -= 0.5f;
|
||||
pR *= contrast;
|
||||
pR *= factor;
|
||||
pR += 0.5f;
|
||||
pR *= 255;
|
||||
if (pR < 0) pR = 0;
|
||||
|
|
@ -2820,7 +2824,7 @@ void ImageColorContrast(Image *image, float contrast)
|
|||
|
||||
float pG = (float)pixels[i].g/255.0f;
|
||||
pG -= 0.5f;
|
||||
pG *= contrast;
|
||||
pG *= factor;
|
||||
pG += 0.5f;
|
||||
pG *= 255;
|
||||
if (pG < 0) pG = 0;
|
||||
|
|
@ -2828,7 +2832,7 @@ void ImageColorContrast(Image *image, float contrast)
|
|||
|
||||
float pB = (float)pixels[i].b/255.0f;
|
||||
pB -= 0.5f;
|
||||
pB *= contrast;
|
||||
pB *= factor;
|
||||
pB += 0.5f;
|
||||
pB *= 255;
|
||||
if (pB < 0) pB = 0;
|
||||
|
|
@ -3506,7 +3510,7 @@ void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int en
|
|||
}
|
||||
|
||||
// Initialize variables for drawing loop
|
||||
int endVal = longLen;
|
||||
int endVal = longLen + 1;
|
||||
int sgnInc = 1;
|
||||
|
||||
// Adjust direction increment based on longLen sign
|
||||
|
|
@ -3514,6 +3518,7 @@ void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int en
|
|||
{
|
||||
longLen = -longLen;
|
||||
sgnInc = -1;
|
||||
endVal -= 2;
|
||||
}
|
||||
|
||||
// Calculate fixed-point increment for shorter length
|
||||
|
|
@ -3523,7 +3528,8 @@ void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int en
|
|||
if (yLonger)
|
||||
{
|
||||
// If line is more vertical, iterate over y-axis
|
||||
for (int i = 0, j = 0; i != endVal; i += sgnInc, j += decInc)
|
||||
// Init j with 0.5 in 16-bit fixed point (1 << 15) for better rounding.
|
||||
for (int i = 0, j = (1 << 15); i != endVal; i += sgnInc, j += decInc)
|
||||
{
|
||||
// Calculate pixel position and draw it
|
||||
ImageDrawPixel(dst, startPosX + (j >> 16), startPosY + i, color);
|
||||
|
|
@ -3532,7 +3538,7 @@ void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int en
|
|||
else
|
||||
{
|
||||
// If line is more horizontal, iterate over x-axis
|
||||
for (int i = 0, j = 0; i != endVal; i += sgnInc, j += decInc)
|
||||
for (int i = 0, j = (1 << 15); i != endVal; i += sgnInc, j += decInc)
|
||||
{
|
||||
// Calculate pixel position and draw it
|
||||
ImageDrawPixel(dst, startPosX + i, startPosY + (j >> 16), color);
|
||||
|
|
@ -3607,137 +3613,15 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co
|
|||
}
|
||||
}
|
||||
|
||||
// Draw circle within an image
|
||||
void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color)
|
||||
// Draw a lines sequence within an image
|
||||
void ImageDrawLineStrip(Image *dst, const Vector2 *points, int pointCount, Color color)
|
||||
{
|
||||
int x = 0;
|
||||
int y = radius;
|
||||
int decesionParameter = 3 - 2*radius;
|
||||
|
||||
while (y >= x)
|
||||
for (int i = 0; i < pointCount - 1; i++)
|
||||
{
|
||||
ImageDrawRectangle(dst, centerX - x, centerY + y, x*2, 1, color);
|
||||
ImageDrawRectangle(dst, centerX - x, centerY - y, x*2, 1, color);
|
||||
ImageDrawRectangle(dst, centerX - y, centerY + x, y*2, 1, color);
|
||||
ImageDrawRectangle(dst, centerX - y, centerY - x, y*2, 1, color);
|
||||
x++;
|
||||
|
||||
if (decesionParameter > 0)
|
||||
{
|
||||
y--;
|
||||
decesionParameter = decesionParameter + 4*(x - y) + 10;
|
||||
}
|
||||
else decesionParameter = decesionParameter + 4*x + 6;
|
||||
ImageDrawLineV(dst, points[i], points[i + 1], color);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw circle within an image (Vector version)
|
||||
void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color)
|
||||
{
|
||||
ImageDrawCircle(dst, (int)center.x, (int)center.y, radius, color);
|
||||
}
|
||||
|
||||
// Draw circle outline within an image
|
||||
void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color)
|
||||
{
|
||||
int x = 0;
|
||||
int y = radius;
|
||||
int decesionParameter = 3 - 2*radius;
|
||||
|
||||
while (y >= x)
|
||||
{
|
||||
ImageDrawPixel(dst, centerX + x, centerY + y, color);
|
||||
ImageDrawPixel(dst, centerX - x, centerY + y, color);
|
||||
ImageDrawPixel(dst, centerX + x, centerY - y, color);
|
||||
ImageDrawPixel(dst, centerX - x, centerY - y, color);
|
||||
ImageDrawPixel(dst, centerX + y, centerY + x, color);
|
||||
ImageDrawPixel(dst, centerX - y, centerY + x, color);
|
||||
ImageDrawPixel(dst, centerX + y, centerY - x, color);
|
||||
ImageDrawPixel(dst, centerX - y, centerY - x, color);
|
||||
x++;
|
||||
|
||||
if (decesionParameter > 0)
|
||||
{
|
||||
y--;
|
||||
decesionParameter = decesionParameter + 4*(x - y) + 10;
|
||||
}
|
||||
else decesionParameter = decesionParameter + 4*x + 6;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw circle outline within an image (Vector version)
|
||||
void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color)
|
||||
{
|
||||
ImageDrawCircleLines(dst, (int)center.x, (int)center.y, radius, color);
|
||||
}
|
||||
|
||||
// Draw rectangle within an image
|
||||
void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color)
|
||||
{
|
||||
ImageDrawRectangleRec(dst, (Rectangle){ (float)posX, (float)posY, (float)width, (float)height }, color);
|
||||
}
|
||||
|
||||
// Draw rectangle within an image (Vector version)
|
||||
void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color)
|
||||
{
|
||||
ImageDrawRectangle(dst, (int)position.x, (int)position.y, (int)size.x, (int)size.y, color);
|
||||
}
|
||||
|
||||
// Draw rectangle within an image
|
||||
void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color)
|
||||
{
|
||||
// Security check to avoid program crash
|
||||
if ((dst->data == NULL) || (dst->width == 0) || (dst->height == 0)) return;
|
||||
|
||||
// Security check to avoid drawing out of bounds in case of bad user data
|
||||
if (rec.x < 0) { rec.width += rec.x; rec.x = 0; }
|
||||
if (rec.y < 0) { rec.height += rec.y; rec.y = 0; }
|
||||
if (rec.width < 0) rec.width = 0;
|
||||
if (rec.height < 0) rec.height = 0;
|
||||
|
||||
// Clamp the size the the image bounds
|
||||
if ((rec.x + rec.width) >= dst->width) rec.width = dst->width - rec.x;
|
||||
if ((rec.y + rec.height) >= dst->height) rec.height = dst->height - rec.y;
|
||||
|
||||
// Check if the rect is even inside the image
|
||||
if ((rec.x >= dst->width) || (rec.y >= dst->height)) return;
|
||||
if (((rec.x + rec.width) <= 0) || (rec.y + rec.height <= 0)) return;
|
||||
|
||||
int sy = (int)rec.y;
|
||||
int sx = (int)rec.x;
|
||||
|
||||
int bytesPerPixel = GetPixelDataSize(1, 1, dst->format);
|
||||
|
||||
// Fill in the first pixel of the first row based on image format
|
||||
ImageDrawPixel(dst, sx, sy, color);
|
||||
|
||||
int bytesOffset = ((sy*dst->width) + sx)*bytesPerPixel;
|
||||
unsigned char *pSrcPixel = (unsigned char *)dst->data + bytesOffset;
|
||||
|
||||
// Repeat the first pixel data throughout the row
|
||||
for (int x = 1; x < (int)rec.width; x *= 2)
|
||||
{
|
||||
int pixelsToCopy = MIN(x, (int)rec.width - x);
|
||||
memcpy(pSrcPixel + x*bytesPerPixel, pSrcPixel, pixelsToCopy*bytesPerPixel);
|
||||
}
|
||||
|
||||
// Repeat the first row data for all other rows
|
||||
int bytesPerRow = bytesPerPixel*(int)rec.width;
|
||||
for (int y = 1; y < (int)rec.height; y++)
|
||||
{
|
||||
memcpy(pSrcPixel + (y*dst->width)*bytesPerPixel, pSrcPixel, bytesPerRow);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw rectangle lines within an image
|
||||
void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color)
|
||||
{
|
||||
ImageDrawRectangle(dst, (int)rec.x, (int)rec.y, (int)rec.width, thick, color);
|
||||
ImageDrawRectangle(dst, (int)rec.x, (int)(rec.y + thick), thick, (int)(rec.height - thick*2), color);
|
||||
ImageDrawRectangle(dst, (int)(rec.x + rec.width - thick), (int)(rec.y + thick), thick, (int)(rec.height - thick*2), color);
|
||||
ImageDrawRectangle(dst, (int)rec.x, (int)(rec.y + rec.height - thick), (int)rec.width, thick, color);
|
||||
}
|
||||
|
||||
// Draw triangle within an image
|
||||
void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color)
|
||||
{
|
||||
|
|
@ -3806,7 +3690,7 @@ void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color col
|
|||
}
|
||||
|
||||
// Draw triangle with interpolated colors within an image
|
||||
void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3)
|
||||
void ImageDrawTriangleGradient(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3)
|
||||
{
|
||||
// Calculate the 2D bounding box of the triangle
|
||||
// Determine the minimum and maximum x and y coordinates of the triangle vertices
|
||||
|
|
@ -3923,9 +3807,169 @@ void ImageDrawTriangleStrip(Image *dst, const Vector2 *points, int pointCount, C
|
|||
}
|
||||
}
|
||||
|
||||
// Draw an image (source) within an image (destination)
|
||||
// Draw rectangle within an image
|
||||
void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color)
|
||||
{
|
||||
ImageDrawRectangleRec(dst, (Rectangle){ (float)posX, (float)posY, (float)width, (float)height }, color);
|
||||
}
|
||||
|
||||
// Draw rectangle within an image (Vector version)
|
||||
void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color)
|
||||
{
|
||||
ImageDrawRectangle(dst, (int)position.x, (int)position.y, (int)size.x, (int)size.y, color);
|
||||
}
|
||||
|
||||
// Draw rectangle within an image
|
||||
void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color)
|
||||
{
|
||||
// Security check to avoid program crash
|
||||
if ((dst->data == NULL) || (dst->width == 0) || (dst->height == 0)) return;
|
||||
|
||||
// Security check to avoid drawing out of bounds in case of bad user data
|
||||
if (rec.x < 0) { rec.width += rec.x; rec.x = 0; }
|
||||
if (rec.y < 0) { rec.height += rec.y; rec.y = 0; }
|
||||
if (rec.width < 0) rec.width = 0;
|
||||
if (rec.height < 0) rec.height = 0;
|
||||
|
||||
// Clamp the size the the image bounds
|
||||
if ((rec.x + rec.width) >= dst->width) rec.width = dst->width - rec.x;
|
||||
if ((rec.y + rec.height) >= dst->height) rec.height = dst->height - rec.y;
|
||||
|
||||
// Check if the rect is even inside the image
|
||||
if ((rec.x >= dst->width) || (rec.y >= dst->height)) return;
|
||||
if (((rec.x + rec.width) <= 0) || (rec.y + rec.height <= 0)) return;
|
||||
|
||||
int sy = (int)rec.y;
|
||||
int sx = (int)rec.x;
|
||||
|
||||
int bytesPerPixel = GetPixelDataSize(1, 1, dst->format);
|
||||
|
||||
// Fill in the first pixel of the first row based on image format
|
||||
ImageDrawPixel(dst, sx, sy, color);
|
||||
|
||||
int bytesOffset = ((sy*dst->width) + sx)*bytesPerPixel;
|
||||
unsigned char *pSrcPixel = (unsigned char *)dst->data + bytesOffset;
|
||||
|
||||
// Repeat the first pixel data throughout the row
|
||||
for (int x = 1; x < (int)rec.width; x *= 2)
|
||||
{
|
||||
int pixelsToCopy = MIN(x, (int)rec.width - x);
|
||||
memcpy(pSrcPixel + x*bytesPerPixel, pSrcPixel, pixelsToCopy*bytesPerPixel);
|
||||
}
|
||||
|
||||
// Repeat the first row data for all other rows
|
||||
int bytesPerRow = bytesPerPixel*(int)rec.width;
|
||||
for (int y = 1; y < (int)rec.height; y++)
|
||||
{
|
||||
memcpy(pSrcPixel + (y*dst->width)*bytesPerPixel, pSrcPixel, bytesPerRow);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw rectangle lines within an image
|
||||
void ImageDrawRectangleLines(Image *dst, int posX, int posY, int width, int height, Color color)
|
||||
{
|
||||
Rectangle rec = { posX, posY, width, height };
|
||||
ImageDrawRectangleLinesEx(dst, rec, 1, color);
|
||||
}
|
||||
|
||||
// Draw rectangle lines within an image with line thickness
|
||||
void ImageDrawRectangleLinesEx(Image *dst, Rectangle rec, int thick, Color color)
|
||||
{
|
||||
ImageDrawRectangle(dst, (int)rec.x, (int)rec.y, (int)rec.width, thick, color);
|
||||
ImageDrawRectangle(dst, (int)rec.x, (int)(rec.y + thick), thick, (int)(rec.height - thick*2), color);
|
||||
ImageDrawRectangle(dst, (int)(rec.x + rec.width - thick), (int)(rec.y + thick), thick, (int)(rec.height - thick*2), color);
|
||||
ImageDrawRectangle(dst, (int)rec.x, (int)(rec.y + rec.height - thick), (int)rec.width, thick, color);
|
||||
}
|
||||
|
||||
// Draw circle within an image
|
||||
void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color)
|
||||
{
|
||||
int x = 0;
|
||||
int y = radius;
|
||||
int decesionParameter = 3 - 2*radius;
|
||||
|
||||
while (y >= x)
|
||||
{
|
||||
ImageDrawRectangle(dst, centerX - x, centerY + y, x*2, 1, color);
|
||||
ImageDrawRectangle(dst, centerX - x, centerY - y, x*2, 1, color);
|
||||
ImageDrawRectangle(dst, centerX - y, centerY + x, y*2, 1, color);
|
||||
ImageDrawRectangle(dst, centerX - y, centerY - x, y*2, 1, color);
|
||||
x++;
|
||||
|
||||
if (decesionParameter > 0)
|
||||
{
|
||||
y--;
|
||||
decesionParameter = decesionParameter + 4*(x - y) + 10;
|
||||
}
|
||||
else decesionParameter = decesionParameter + 4*x + 6;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw circle within an image (Vector version)
|
||||
void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color)
|
||||
{
|
||||
ImageDrawCircle(dst, (int)center.x, (int)center.y, radius, color);
|
||||
}
|
||||
|
||||
// Draw circle outline within an image
|
||||
void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color)
|
||||
{
|
||||
int x = 0;
|
||||
int y = radius;
|
||||
int decesionParameter = 3 - 2*radius;
|
||||
|
||||
while (y >= x)
|
||||
{
|
||||
ImageDrawPixel(dst, centerX + x, centerY + y, color);
|
||||
ImageDrawPixel(dst, centerX - x, centerY + y, color);
|
||||
ImageDrawPixel(dst, centerX + x, centerY - y, color);
|
||||
ImageDrawPixel(dst, centerX - x, centerY - y, color);
|
||||
ImageDrawPixel(dst, centerX + y, centerY + x, color);
|
||||
ImageDrawPixel(dst, centerX - y, centerY + x, color);
|
||||
ImageDrawPixel(dst, centerX + y, centerY - x, color);
|
||||
ImageDrawPixel(dst, centerX - y, centerY - x, color);
|
||||
x++;
|
||||
|
||||
if (decesionParameter > 0)
|
||||
{
|
||||
y--;
|
||||
decesionParameter = decesionParameter + 4*(x - y) + 10;
|
||||
}
|
||||
else decesionParameter = decesionParameter + 4*x + 6;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw circle outline within an image (Vector version)
|
||||
void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color)
|
||||
{
|
||||
ImageDrawCircleLines(dst, (int)center.x, (int)center.y, radius, color);
|
||||
}
|
||||
|
||||
// Draw a gradient-filled circle within an image
|
||||
void ImageDrawCircleGradient(Image *dst, Vector2 center, float radius, Color inner, Color outer)
|
||||
{
|
||||
// TODO: Implement gradient circle drawing
|
||||
}
|
||||
|
||||
// Draw an image within an image
|
||||
void ImageDrawImage(Image *dst, Image src, int posX, int posY, Color tint)
|
||||
{
|
||||
Rectangle srcRec = { 0, 0, src.width, src.height };
|
||||
Rectangle dstRec = { posX, posY, srcRec.width, srcRec.height };
|
||||
ImageDrawImagePro(dst, src, srcRec, dstRec, (Vector2){ 0 }, 0.0f, tint);
|
||||
}
|
||||
|
||||
// Draw a part of an image defined by a rectangle within an image
|
||||
void ImageDrawImageRec(Image *dst, Image src, Rectangle srcRec, Vector2 position, Color tint)
|
||||
{
|
||||
Rectangle dstRec = { position.x, position.y, srcRec.width, srcRec.height };
|
||||
ImageDrawImagePro(dst, src, srcRec, dstRec, (Vector2){ 0 }, 0.0f, tint);
|
||||
}
|
||||
|
||||
// Draw a part of an image defined by a rectangle into destination rectangle, with scaling and rotation, within an image
|
||||
// NOTE: Color tint is applied to source image
|
||||
void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint)
|
||||
// TODO: WARNING: origin and rotation are not implemented
|
||||
void ImageDrawImagePro(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Vector2 origin, float rotation, Color tint)
|
||||
{
|
||||
// Security check to avoid program crash
|
||||
if ((dst->data == NULL) || (dst->width == 0) || (dst->height == 0) ||
|
||||
|
|
@ -3986,7 +4030,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
|
|||
// [x] Consider fast path: no alpha blending required cases (src has no alpha)
|
||||
// [x] Consider fast path: same src/dst format with no alpha -> direct line copy
|
||||
// [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend()
|
||||
// [ ] TODO: Support 16bit and 32bit (float) channels drawing
|
||||
// [-] Support 16bit and 32bit (float) channels drawing
|
||||
|
||||
Color colSrc = { 0 };
|
||||
Color colDst = { 0 };
|
||||
|
|
@ -4070,7 +4114,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
|
|||
mipmapDstRec.x /= 2;
|
||||
mipmapDstRec.y /= 2;
|
||||
|
||||
ImageDraw(&mipmapDst, mipmapSrc, mipmapSrcRec, mipmapDstRec, tint);
|
||||
ImageDrawImagePro(&mipmapDst, mipmapSrc, mipmapSrcRec, mipmapDstRec, (Vector2){ 0 }, 0.0f, tint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4097,7 +4141,7 @@ void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position,
|
|||
Rectangle srcRec = { 0.0f, 0.0f, (float)imText.width, (float)imText.height };
|
||||
Rectangle dstRec = { position.x, position.y, (float)imText.width, (float)imText.height };
|
||||
|
||||
ImageDraw(dst, imText, srcRec, dstRec, WHITE);
|
||||
ImageDrawImagePro(dst, imText, srcRec, dstRec, (Vector2){ 0 }, 0.0f, WHITE);
|
||||
|
||||
UnloadImage(imText);
|
||||
}
|
||||
|
|
@ -4223,7 +4267,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
|
|||
ImageMipmaps(&faces);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) ImageDraw(&faces, mipmapped, faceRecs[i], (Rectangle){ 0, (float)size*i, (float)size, (float)size }, WHITE);
|
||||
for (int i = 0; i < 6; i++) ImageDrawImagePro(&faces, mipmapped, faceRecs[i], (Rectangle){ 0, (float)size*i, (float)size, (float)size }, (Vector2){ 0 }, 0.0f, WHITE);
|
||||
|
||||
UnloadImage(mipmapped);
|
||||
}
|
||||
|
|
@ -4286,7 +4330,7 @@ RenderTexture2D LoadRenderTexture(int width, int height)
|
|||
return target;
|
||||
}
|
||||
|
||||
// Check if a texture is valid (loaded in GPU)
|
||||
// Check if texture is valid (loaded in GPU)
|
||||
bool IsTextureValid(Texture2D texture)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -4311,7 +4355,7 @@ void UnloadTexture(Texture2D texture)
|
|||
}
|
||||
}
|
||||
|
||||
// Check if a render texture is valid (loaded in GPU)
|
||||
// Check if render texture is valid (loaded in GPU)
|
||||
bool IsRenderTextureValid(RenderTexture2D target)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -4479,28 +4523,28 @@ void DrawTextureV(Texture2D texture, Vector2 position, Color tint)
|
|||
DrawTextureEx(texture, position, 0, 1.0f, tint);
|
||||
}
|
||||
|
||||
// Draw a texture with extended parameters
|
||||
// Draw a texture with rotation and scale
|
||||
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
|
||||
{
|
||||
Rectangle source = { 0.0f, 0.0f, (float)texture.width, (float)texture.height };
|
||||
Rectangle dest = { position.x, position.y, (float)texture.width*scale, (float)texture.height*scale };
|
||||
Rectangle srcrec = { 0.0f, 0.0f, (float)texture.width, (float)texture.height };
|
||||
Rectangle dstrec = { position.x, position.y, (float)texture.width*scale, (float)texture.height*scale };
|
||||
Vector2 origin = { 0.0f, 0.0f };
|
||||
|
||||
DrawTexturePro(texture, source, dest, origin, rotation, tint);
|
||||
DrawTexturePro(texture, srcrec, dstrec, origin, rotation, tint);
|
||||
}
|
||||
|
||||
// Draw a part of a texture (defined by a rectangle)
|
||||
void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint)
|
||||
void DrawTextureRec(Texture2D texture, Rectangle rec, Vector2 position, Color tint)
|
||||
{
|
||||
Rectangle dest = { position.x, position.y, fabsf(source.width), fabsf(source.height) };
|
||||
Rectangle dstrec = { position.x, position.y, fabsf(rec.width), fabsf(rec.height) };
|
||||
Vector2 origin = { 0.0f, 0.0f };
|
||||
|
||||
DrawTexturePro(texture, source, dest, origin, 0.0f, tint);
|
||||
DrawTexturePro(texture, rec, dstrec, origin, 0.0f, tint);
|
||||
}
|
||||
|
||||
// Draw a part of a texture (defined by a rectangle) with 'pro' parameters
|
||||
// NOTE: origin is relative to destination rectangle size
|
||||
void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint)
|
||||
void DrawTexturePro(Texture2D texture, Rectangle srcrec, Rectangle dstrec, Vector2 origin, float rotation, Color tint)
|
||||
{
|
||||
// Check if texture is valid
|
||||
if (texture.id > 0)
|
||||
|
|
@ -4510,11 +4554,11 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
|
|||
|
||||
bool flipX = false;
|
||||
|
||||
if (source.width < 0) { flipX = true; source.width *= -1; }
|
||||
if (source.height < 0) source.y -= source.height;
|
||||
if (srcrec.width < 0) { flipX = true; srcrec.width *= -1; }
|
||||
if (srcrec.height < 0) srcrec.y -= srcrec.height;
|
||||
|
||||
if (dest.width < 0) dest.width *= -1;
|
||||
if (dest.height < 0) dest.height *= -1;
|
||||
if (dstrec.width < 0) dstrec.width *= -1;
|
||||
if (dstrec.height < 0) dstrec.height *= -1;
|
||||
|
||||
Vector2 topLeft = { 0 };
|
||||
Vector2 topRight = { 0 };
|
||||
|
|
@ -4524,33 +4568,33 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
|
|||
// Only calculate rotation if needed
|
||||
if (rotation == 0.0f)
|
||||
{
|
||||
float x = dest.x - origin.x;
|
||||
float y = dest.y - origin.y;
|
||||
float x = dstrec.x - origin.x;
|
||||
float y = dstrec.y - origin.y;
|
||||
topLeft = (Vector2){ x, y };
|
||||
topRight = (Vector2){ x + dest.width, y };
|
||||
bottomLeft = (Vector2){ x, y + dest.height };
|
||||
bottomRight = (Vector2){ x + dest.width, y + dest.height };
|
||||
topRight = (Vector2){ x + dstrec.width, y };
|
||||
bottomLeft = (Vector2){ x, y + dstrec.height };
|
||||
bottomRight = (Vector2){ x + dstrec.width, y + dstrec.height };
|
||||
}
|
||||
else
|
||||
{
|
||||
float sinRotation = sinf(rotation*DEG2RAD);
|
||||
float cosRotation = cosf(rotation*DEG2RAD);
|
||||
float x = dest.x;
|
||||
float y = dest.y;
|
||||
float x = dstrec.x;
|
||||
float y = dstrec.y;
|
||||
float dx = -origin.x;
|
||||
float dy = -origin.y;
|
||||
|
||||
topLeft.x = x + dx*cosRotation - dy*sinRotation;
|
||||
topLeft.y = y + dx*sinRotation + dy*cosRotation;
|
||||
|
||||
topRight.x = x + (dx + dest.width)*cosRotation - dy*sinRotation;
|
||||
topRight.y = y + (dx + dest.width)*sinRotation + dy*cosRotation;
|
||||
topRight.x = x + (dx + dstrec.width)*cosRotation - dy*sinRotation;
|
||||
topRight.y = y + (dx + dstrec.width)*sinRotation + dy*cosRotation;
|
||||
|
||||
bottomLeft.x = x + dx*cosRotation - (dy + dest.height)*sinRotation;
|
||||
bottomLeft.y = y + dx*sinRotation + (dy + dest.height)*cosRotation;
|
||||
bottomLeft.x = x + dx*cosRotation - (dy + dstrec.height)*sinRotation;
|
||||
bottomLeft.y = y + dx*sinRotation + (dy + dstrec.height)*cosRotation;
|
||||
|
||||
bottomRight.x = x + (dx + dest.width)*cosRotation - (dy + dest.height)*sinRotation;
|
||||
bottomRight.y = y + (dx + dest.width)*sinRotation + (dy + dest.height)*cosRotation;
|
||||
bottomRight.x = x + (dx + dstrec.width)*cosRotation - (dy + dstrec.height)*sinRotation;
|
||||
bottomRight.y = y + (dx + dstrec.width)*sinRotation + (dy + dstrec.height)*cosRotation;
|
||||
}
|
||||
|
||||
rlSetTexture(texture.id);
|
||||
|
|
@ -4560,23 +4604,23 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
|
|||
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
||||
|
||||
// Top-left corner for texture and quad
|
||||
if (flipX) rlTexCoord2f((source.x + source.width)/width, source.y/height);
|
||||
else rlTexCoord2f(source.x/width, source.y/height);
|
||||
if (flipX) rlTexCoord2f((srcrec.x + srcrec.width)/width, srcrec.y/height);
|
||||
else rlTexCoord2f(srcrec.x/width, srcrec.y/height);
|
||||
rlVertex2f(topLeft.x, topLeft.y);
|
||||
|
||||
// Bottom-left corner for texture and quad
|
||||
if (flipX) rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
|
||||
else rlTexCoord2f(source.x/width, (source.y + source.height)/height);
|
||||
if (flipX) rlTexCoord2f((srcrec.x + srcrec.width)/width, (srcrec.y + srcrec.height)/height);
|
||||
else rlTexCoord2f(srcrec.x/width, (srcrec.y + srcrec.height)/height);
|
||||
rlVertex2f(bottomLeft.x, bottomLeft.y);
|
||||
|
||||
// Bottom-right corner for texture and quad
|
||||
if (flipX) rlTexCoord2f(source.x/width, (source.y + source.height)/height);
|
||||
else rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
|
||||
if (flipX) rlTexCoord2f(srcrec.x/width, (srcrec.y + srcrec.height)/height);
|
||||
else rlTexCoord2f((srcrec.x + srcrec.width)/width, (srcrec.y + srcrec.height)/height);
|
||||
rlVertex2f(bottomRight.x, bottomRight.y);
|
||||
|
||||
// Top-right corner for texture and quad
|
||||
if (flipX) rlTexCoord2f(source.x/width, source.y/height);
|
||||
else rlTexCoord2f((source.x + source.width)/width, source.y/height);
|
||||
if (flipX) rlTexCoord2f(srcrec.x/width, srcrec.y/height);
|
||||
else rlTexCoord2f((srcrec.x + srcrec.width)/width, srcrec.y/height);
|
||||
rlVertex2f(topRight.x, topRight.y);
|
||||
|
||||
rlEnd();
|
||||
|
|
@ -4590,7 +4634,7 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
|
|||
/*
|
||||
rlSetTexture(texture.id);
|
||||
rlPushMatrix();
|
||||
rlTranslatef(dest.x, dest.y, 0.0f);
|
||||
rlTranslatef(dstrec.x, dstrec.y, 0.0f);
|
||||
if (rotation != 0.0f) rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
|
||||
rlTranslatef(-origin.x, -origin.y, 0.0f);
|
||||
|
||||
|
|
@ -4599,24 +4643,24 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
|
|||
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
||||
|
||||
// Bottom-left corner for texture and quad
|
||||
if (flipX) rlTexCoord2f((source.x + source.width)/width, source.y/height);
|
||||
else rlTexCoord2f(source.x/width, source.y/height);
|
||||
if (flipX) rlTexCoord2f((srcrec.x + srcrec.width)/width, srcrec.y/height);
|
||||
else rlTexCoord2f(srcrec.x/width, srcrec.y/height);
|
||||
rlVertex2f(0.0f, 0.0f);
|
||||
|
||||
// Bottom-right corner for texture and quad
|
||||
if (flipX) rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
|
||||
else rlTexCoord2f(source.x/width, (source.y + source.height)/height);
|
||||
rlVertex2f(0.0f, dest.height);
|
||||
if (flipX) rlTexCoord2f((srcrec.x + srcrec.width)/width, (srcrec.y + srcrec.height)/height);
|
||||
else rlTexCoord2f(srcrec.x/width, (srcrec.y + srcrec.height)/height);
|
||||
rlVertex2f(0.0f, dstrec.height);
|
||||
|
||||
// Top-right corner for texture and quad
|
||||
if (flipX) rlTexCoord2f(source.x/width, (source.y + source.height)/height);
|
||||
else rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
|
||||
rlVertex2f(dest.width, dest.height);
|
||||
if (flipX) rlTexCoord2f(srcrec.x/width, (srcrec.y + srcrec.height)/height);
|
||||
else rlTexCoord2f((srcrec.x + srcrec.width)/width, (srcrec.y + srcrec.height)/height);
|
||||
rlVertex2f(dstrec.width, dstrec.height);
|
||||
|
||||
// Top-left corner for texture and quad
|
||||
if (flipX) rlTexCoord2f(source.x/width, source.y/height);
|
||||
else rlTexCoord2f((source.x + source.width)/width, source.y/height);
|
||||
rlVertex2f(dest.width, 0.0f);
|
||||
if (flipX) rlTexCoord2f(srcrec.x/width, srcrec.y/height);
|
||||
else rlTexCoord2f((srcrec.x + srcrec.width)/width, srcrec.y/height);
|
||||
rlVertex2f(dstrec.width, 0.0f);
|
||||
rlEnd();
|
||||
rlPopMatrix();
|
||||
rlSetTexture(0);
|
||||
|
|
@ -4624,16 +4668,16 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
|
|||
}
|
||||
}
|
||||
|
||||
// Draws a texture (or part of it) that stretches or shrinks nicely using n-patch info
|
||||
void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint)
|
||||
// Draw a texture (or part of it) that stretches or shrinks nicely using n-patch info
|
||||
void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dstrec, Vector2 origin, float rotation, Color tint)
|
||||
{
|
||||
if (texture.id > 0)
|
||||
{
|
||||
float width = (float)texture.width;
|
||||
float height = (float)texture.height;
|
||||
|
||||
float patchWidth = ((int)dest.width <= 0)? 0.0f : dest.width;
|
||||
float patchHeight = ((int)dest.height <= 0)? 0.0f : dest.height;
|
||||
float patchWidth = ((int)dstrec.width <= 0)? 0.0f : dstrec.width;
|
||||
float patchHeight = ((int)dstrec.height <= 0)? 0.0f : dstrec.height;
|
||||
|
||||
if (nPatchInfo.source.width < 0) nPatchInfo.source.x -= nPatchInfo.source.width;
|
||||
if (nPatchInfo.source.height < 0) nPatchInfo.source.y -= nPatchInfo.source.height;
|
||||
|
|
@ -4692,7 +4736,7 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest,
|
|||
rlSetTexture(texture.id);
|
||||
|
||||
rlPushMatrix();
|
||||
rlTranslatef(dest.x, dest.y, 0.0f);
|
||||
rlTranslatef(dstrec.x, dstrec.y, 0.0f);
|
||||
rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
|
||||
rlTranslatef(-origin.x, -origin.y, 0.0f);
|
||||
|
||||
|
|
@ -5171,7 +5215,7 @@ Color GetColor(unsigned int hexValue)
|
|||
}
|
||||
|
||||
// Get color from a pixel from certain format
|
||||
Color GetPixelColor(void *srcPtr, int format)
|
||||
Color GetPixelColor(const void *srcPtr, int format)
|
||||
{
|
||||
Color color = { 0 };
|
||||
|
||||
|
|
|
|||
|
|
@ -675,13 +675,12 @@ int main(int argc, char *argv[])
|
|||
// WARNING 2: raylib.a and raylib.web.a must be available when compiling locally
|
||||
#if defined(_WIN32)
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", GetFileNameWithoutExt(inFileName));
|
||||
//putenv("RAYLIB_DIR=C:\\GitHub\\raylib");
|
||||
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
|
||||
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
|
||||
#else
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", GetFileNameWithoutExt(inFileName));
|
||||
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
|
||||
#endif
|
||||
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
|
||||
|
||||
// Update generated .html metadata
|
||||
LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName));
|
||||
UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName),
|
||||
|
|
@ -778,10 +777,9 @@ int main(int argc, char *argv[])
|
|||
// WARNING: EMSDK_PATH must be set to proper location when calling from GitHub Actions
|
||||
#if defined(_WIN32)
|
||||
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
|
||||
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename));
|
||||
#else
|
||||
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename));
|
||||
#endif
|
||||
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename));
|
||||
|
||||
// Update generated .html metadata
|
||||
UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exRename),
|
||||
TextFormat("%s/%s/%s.c", exBasePath, exCategory, exRename));
|
||||
|
|
@ -917,7 +915,7 @@ int main(int argc, char *argv[])
|
|||
// Set required environment variables
|
||||
//putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
|
||||
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
|
||||
//putenv("MAKE=mingw32-make");
|
||||
//putenv("MAKE=make");
|
||||
//ChangeDirectory(exBasePath);
|
||||
#endif
|
||||
for (int i = 0; i < exBuildListCount; i++)
|
||||
|
|
@ -933,7 +931,7 @@ int main(int argc, char *argv[])
|
|||
// Build example for PLATFORM_DESKTOP
|
||||
#if defined(_WIN32)
|
||||
LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName);
|
||||
system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName));
|
||||
system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName));
|
||||
#elif defined(PLATFORM_DRM)
|
||||
LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName);
|
||||
system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1",
|
||||
|
|
@ -949,13 +947,9 @@ int main(int argc, char *argv[])
|
|||
// Build: raylib.com/examples/<category>/<category>_example_name.data
|
||||
// Build: raylib.com/examples/<category>/<category>_example_name.wasm
|
||||
// Build: raylib.com/examples/<category>/<category>_example_name.js
|
||||
#if defined(_WIN32)
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName);
|
||||
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
|
||||
#else
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName);
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB\n", exName);
|
||||
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
|
||||
#endif
|
||||
|
||||
// Update generated .html metadata
|
||||
LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName));
|
||||
UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName),
|
||||
|
|
@ -1268,8 +1262,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
// NOTE: Some examples should be excluded from VS2022 solution because
|
||||
// they have specific platform/linkage requirements:
|
||||
if ((strcmp(exInfo->name, "web_basic_window") == 0) ||
|
||||
(strcmp(exInfo->name, "raylib_opengl_interop") == 0)) continue;
|
||||
if (strcmp(exInfo->name, "raylib_opengl_interop") == 0) continue;
|
||||
|
||||
// Review: Add: raylib/projects/VS2022/examples/<category>_example_name.vcxproj
|
||||
// Review: Add: raylib/projects/VS2022/raylib.sln
|
||||
|
|
@ -1313,11 +1306,10 @@ int main(int argc, char *argv[])
|
|||
#if defined(_WIN32)
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exInfo->name);
|
||||
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
|
||||
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name));
|
||||
#else
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exInfo->name);
|
||||
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name));
|
||||
#endif
|
||||
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name));
|
||||
|
||||
// Update generated .html metadata
|
||||
LOG("INFO: [%s.html] Updating HTML Metadata...\n", exInfo->name);
|
||||
|
|
@ -1496,7 +1488,7 @@ int main(int argc, char *argv[])
|
|||
// Set required environment variables
|
||||
//putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
|
||||
//_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
|
||||
//putenv("MAKE=mingw32-make");
|
||||
//putenv("MAKE=make");
|
||||
//ChangeDirectory(exBasePath);
|
||||
//_putenv("MAKE_PATH=C:\\raylib\\w64devkit\\bin");
|
||||
//_putenv("EMSDK_PATH = C:\\raylib\\emsdk");
|
||||
|
|
@ -1593,7 +1585,7 @@ int main(int argc, char *argv[])
|
|||
// Build: raylib.com/examples/<category>/<category>_example_name.js
|
||||
#if defined(_WIN32)
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName);
|
||||
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1",
|
||||
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1",
|
||||
exBasePath, exCategory, exName, exBasePath, exCategory, exName));
|
||||
#else
|
||||
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName);
|
||||
|
|
@ -1642,13 +1634,13 @@ int main(int argc, char *argv[])
|
|||
// Set required environment variables
|
||||
//putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
|
||||
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
|
||||
//putenv("MAKE=mingw32-make");
|
||||
//putenv("MAKE=make");
|
||||
//ChangeDirectory(exBasePath);
|
||||
#endif
|
||||
// Build example for PLATFORM_DESKTOP
|
||||
#if defined(_WIN32)
|
||||
LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName);
|
||||
system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1",
|
||||
system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1",
|
||||
exBasePath, exCategory, exName, exBasePath, exCategory, exName));
|
||||
#elif defined(PLATFORM_DRM)
|
||||
LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName);
|
||||
|
|
@ -1894,9 +1886,11 @@ int main(int argc, char *argv[])
|
|||
printf(" test <example_name> : Build and Test example for Desktop and Web platforms\n");
|
||||
printf(" validate : Validate examples collection, generates report\n");
|
||||
printf(" update : Validate and update examples collection, generates report\n\n");
|
||||
|
||||
printf("OPTIONS:\n\n");
|
||||
printf(" -h, --help : Show tool version and command line usage help\n");
|
||||
printf(" -v, --verbose : Verbose mode, show additional logs on processes\n");
|
||||
|
||||
printf("\nEXAMPLES:\n\n");
|
||||
printf(" > rexm add shapes_custom_stars\n");
|
||||
printf(" Add and updates new example provided <shapes_custom_stars>\n\n");
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ raylib_api: ../../src/raylib.h rlparser
|
|||
FORMAT=JSON EXTENSION=json $(MAKE) raylib_api.json
|
||||
FORMAT=XML EXTENSION=xml $(MAKE) raylib_api.xml
|
||||
FORMAT=LUA EXTENSION=lua $(MAKE) raylib_api.lua
|
||||
FORMAT=SEXPR EXTENSION=sexpr $(MAKE) raylib_api.sexpr
|
||||
|
||||
# rlparser execution: [raylib.h] parse, generating some output files
|
||||
raylib_api.$(EXTENSION): ../../src/raylib.h rlparser
|
||||
|
|
@ -112,7 +113,8 @@ all: rlparser
|
|||
FORMAT=JSON EXTENSION=json $(MAKE) parse
|
||||
FORMAT=XML EXTENSION=xml $(MAKE) parse
|
||||
FORMAT=LUA EXTENSION=lua $(MAKE) parse
|
||||
FORMAT=SEXPR EXTENSION=sexpr $(MAKE) parse
|
||||
|
||||
# Clean rlparser and generated output files
|
||||
clean:
|
||||
rm -f rlparser *.json *.txt *.xml *.lua
|
||||
rm -f rlparser *.json *.txt *.xml *.lua *.sexpr
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# rlparser - raylib parser
|
||||
|
||||
This parser scans [`raylib.h`](../src/raylib.h) to get information about `defines`, `structs`, `enums` and `functions`.
|
||||
This parser scans [`raylib.h`](../../src/raylib.h) to get information about `defines`, `structs`, `enums` and `functions`.
|
||||
All data is separated into parts, usually as strings. The following types are used for data:
|
||||
|
||||
- `struct DefineInfo`
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -146,7 +146,7 @@ typedef struct FunctionInfo {
|
|||
} FunctionInfo;
|
||||
|
||||
// Output format for parsed data
|
||||
typedef enum { DEFAULT = 0, JSON, XML, LUA, CODE } OutputFormat;
|
||||
typedef enum { DEFAULT = 0, JSON, XML, LUA, SEXPR, CODE } OutputFormat;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
|
|
@ -202,7 +202,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
if (argc > 1) ProcessCommandLine(argc, argv);
|
||||
|
||||
const char *raylibhPath = "../src/raylib.h\0";
|
||||
const char *raylibhPath = "../../src/raylib.h\0";
|
||||
const char *raylibapiPath = "raylib_api.txt\0";
|
||||
const char *rlapiPath = "RLAPI\0";
|
||||
if (inFileName[0] == '\0') MemoryCopy(inFileName, raylibhPath, TextLength(raylibhPath) + 1);
|
||||
|
|
@ -1062,6 +1062,7 @@ int main(int argc, char *argv[])
|
|||
else if (outputFormat == JSON) printf("\nOutput format: JSON\n\n");
|
||||
else if (outputFormat == XML) printf("\nOutput format: XML\n\n");
|
||||
else if (outputFormat == LUA) printf("\nOutput format: LUA\n\n");
|
||||
else if (outputFormat == SEXPR) printf("\nOutput format: SEXPR\n\n");
|
||||
else if (outputFormat == CODE) printf("\nOutput format: CODE\n\n");
|
||||
|
||||
ExportParsedData(outFileName, outputFormat);
|
||||
|
|
@ -1098,10 +1099,10 @@ static void ShowCommandLineInfo(void)
|
|||
printf(" -i, --input <filename.h> : Define input header file to parse.\n");
|
||||
printf(" NOTE: If not specified, defaults to: raylib.h\n\n");
|
||||
printf(" -o, --output <filename.ext> : Define output file and format.\n");
|
||||
printf(" Supported extensions: .txt, .json, .xml, .lua, .h\n");
|
||||
printf(" Supported extensions: .txt, .json, .xml, .lua, .sexpr, .h\n");
|
||||
printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n");
|
||||
printf(" -f, --format <type> : Define output format for parser data.\n");
|
||||
printf(" Supported types: DEFAULT, JSON, XML, LUA, CODE\n\n");
|
||||
printf(" Supported types: DEFAULT, JSON, XML, LUA, SEXPR, CODE\n\n");
|
||||
printf(" -d, --define <DEF> : Define functions specifiers (i.e. RLAPI for raylib.h, RMAPI for raymath.h, etc.)\n");
|
||||
printf(" NOTE: If no specifier defined, defaults to: RLAPI\n\n");
|
||||
printf(" -t, --truncate <after> : Define string to truncate input after (i.e. \"RLGL IMPLEMENTATION\" for rlgl.h)\n");
|
||||
|
|
@ -1154,7 +1155,8 @@ static void ProcessCommandLine(int argc, char *argv[])
|
|||
else if (IsTextEqual(argv[i + 1], "JSON\0", 5)) outputFormat = JSON;
|
||||
else if (IsTextEqual(argv[i + 1], "XML\0", 4)) outputFormat = XML;
|
||||
else if (IsTextEqual(argv[i + 1], "LUA\0", 4)) outputFormat = LUA;
|
||||
else if (IsTextEqual(argv[i + 1], "CODE\0", 4)) outputFormat = CODE;
|
||||
else if (IsTextEqual(argv[i + 1], "SEXPR\0", 4)) outputFormat = SEXPR;
|
||||
else if (IsTextEqual(argv[i + 1], "CODE\0", 5)) outputFormat = CODE;
|
||||
}
|
||||
else printf("WARNING: No format parameters provided\n");
|
||||
}
|
||||
|
|
@ -2007,6 +2009,131 @@ static void ExportParsedData(const char *fileName, int format)
|
|||
fprintf(outFile, " }\n");
|
||||
fprintf(outFile, "}\n");
|
||||
} break;
|
||||
case SEXPR:
|
||||
{
|
||||
fprintf(outFile, "(");
|
||||
|
||||
// Print defines info
|
||||
fprintf(outFile, "(defines\n");
|
||||
for (int i = 0; i < defineCount; i++)
|
||||
{
|
||||
if(i != 0) fprintf(outFile, "\n");
|
||||
fprintf(outFile, " ((name \"%s\")\n", defines[i].name);
|
||||
fprintf(outFile, " (type \"%s\")\n", StrDefineType(defines[i].type));
|
||||
if ((defines[i].type == INT) ||
|
||||
(defines[i].type == LONG) ||
|
||||
(defines[i].type == FLOAT) ||
|
||||
(defines[i].type == DOUBLE) ||
|
||||
(defines[i].type == STRING))
|
||||
{
|
||||
fprintf(outFile, " (value %s)\n", defines[i].value);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(outFile, " (value \"%s\")\n", defines[i].value);
|
||||
}
|
||||
fprintf(outFile, " (description \"%s\"))", defines[i].desc);
|
||||
}
|
||||
fprintf(outFile, ")\n\n");
|
||||
|
||||
// Print structs info
|
||||
fprintf(outFile, " (structs\n");
|
||||
for (int i = 0; i < structCount; i++)
|
||||
{
|
||||
if(i != 0) fprintf(outFile, "\n\n");
|
||||
fprintf(outFile, " ((name \"%s\")\n", structs[i].name);
|
||||
fprintf(outFile, " (description \"%s\")\n", EscapeBackslashes(structs[i].desc));
|
||||
fprintf(outFile, " (fields ");
|
||||
for (int f = 0; f < structs[i].fieldCount; f++)
|
||||
{
|
||||
fprintf(outFile, "\n ((type \"%s\")\n", structs[i].fieldType[f]);
|
||||
fprintf(outFile, " (name \"%s\")\n", structs[i].fieldName[f]);
|
||||
fprintf(outFile, " (description \"%s\"))", EscapeBackslashes(structs[i].fieldDesc[f]));
|
||||
}
|
||||
fprintf(outFile, "))");
|
||||
}
|
||||
fprintf(outFile, ")\n\n");
|
||||
|
||||
// Print aliases info
|
||||
fprintf(outFile, " (aliases\n");
|
||||
for (int i = 0; i < aliasCount; i++)
|
||||
{
|
||||
if(i != 0) fprintf(outFile, "\n\n");
|
||||
fprintf(outFile, " ((type \"%s\")\n", aliases[i].type);
|
||||
fprintf(outFile, " (name \"%s\")\n", aliases[i].name);
|
||||
fprintf(outFile, " (description \"%s\"))", aliases[i].desc);
|
||||
}
|
||||
fprintf(outFile, ")\n\n");
|
||||
|
||||
// Print enums info
|
||||
fprintf(outFile, " (enums\n");
|
||||
for (int i = 0; i < enumCount; i++)
|
||||
{
|
||||
if(i != 0) fprintf(outFile, "\n\n");
|
||||
fprintf(outFile, " ((name \"%s\")\n", enums[i].name);
|
||||
fprintf(outFile, " (description \"%s\")\n", EscapeBackslashes(enums[i].desc));
|
||||
fprintf(outFile, " (values\n");
|
||||
for (int e = 0; e < enums[i].valueCount; e++)
|
||||
{
|
||||
if(e != 0) fprintf(outFile, "\n\n");
|
||||
fprintf(outFile, " ((name \"%s\")\n", enums[i].valueName[e]);
|
||||
fprintf(outFile, " (value %i)\n", enums[i].valueInteger[e]);
|
||||
fprintf(outFile, " (description \"%s\"))", EscapeBackslashes(enums[i].valueDesc[e]));
|
||||
}
|
||||
fprintf(outFile, "))");
|
||||
}
|
||||
fprintf(outFile, ")\n\n");
|
||||
|
||||
// Print callbacks info
|
||||
fprintf(outFile, " (callbacks\n");
|
||||
for (int i = 0; i < callbackCount; i++)
|
||||
{
|
||||
if(i != 0) fprintf(outFile, "\n\n");
|
||||
fprintf(outFile, " ((name \"%s\")\n", callbacks[i].name);
|
||||
fprintf(outFile, " (description \"%s\")\n", EscapeBackslashes(callbacks[i].desc));
|
||||
fprintf(outFile, " (return-type \"%s\")", callbacks[i].retType);
|
||||
|
||||
if (callbacks[i].paramCount == 0) fprintf(outFile, "\n");
|
||||
else
|
||||
{
|
||||
fprintf(outFile, "\n (params\n");
|
||||
for (int p = 0; p < callbacks[i].paramCount; p++)
|
||||
{
|
||||
if(p != 0) fprintf(outFile, "\n");
|
||||
fprintf(outFile, " ((type \"%s\") (name \"%s\"))", callbacks[i].paramType[p], callbacks[i].paramName[p]);
|
||||
}
|
||||
fprintf(outFile, ")");
|
||||
}
|
||||
fprintf(outFile, ")");
|
||||
}
|
||||
fprintf(outFile, ")\n\n");
|
||||
|
||||
// Print functions info
|
||||
fprintf(outFile, " (functions\n");
|
||||
for (int i = 0; i < funcCount; i++)
|
||||
{
|
||||
if(i != 0) fprintf(outFile, "\n\n");
|
||||
fprintf(outFile, " ((name \"%s\")\n", funcs[i].name);
|
||||
fprintf(outFile, " (description \"%s\")\n", EscapeBackslashes(funcs[i].desc));
|
||||
fprintf(outFile, " (return-type \"%s\")", funcs[i].retType);
|
||||
|
||||
if (funcs[i].paramCount == 0) fprintf(outFile, "");
|
||||
else
|
||||
{
|
||||
fprintf(outFile, "\n (params\n");
|
||||
for (int p = 0; p < funcs[i].paramCount; p++)
|
||||
{
|
||||
if(p != 0) fprintf(outFile, "\n");
|
||||
fprintf(outFile, " ((type \"%s\") (name \"%s\"))", funcs[i].paramType[p], funcs[i].paramName[p]);
|
||||
}
|
||||
fprintf(outFile, ")");
|
||||
}
|
||||
fprintf(outFile, ")");
|
||||
}
|
||||
fprintf(outFile, ")");
|
||||
fprintf(outFile, ")\n");
|
||||
} break;
|
||||
|
||||
case CODE:
|
||||
default: break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user