diff --git a/BINDINGS.md b/BINDINGS.md index e5cae30d688b..22b740588dd5 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -1,6 +1,6 @@ # raylib bindings and wrappers -Some people ported raylib to other languages in form of bindings or wrappers to the library. Here is a list with all the ports available. Feel free to send a PR if you know of any binding/wrapper not in this list. +Some people ported raylib to other languages in the form of bindings or wrappers to the library. Here is a list with all the ports available. Feel free to send a PR if you know of any binding/wrapper not in this list. ### Language Bindings @@ -12,8 +12,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.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.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT | -| [Raylib.NET](https://github.com/Odex64/Raylib.NET) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT | +| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.1-dev** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT | | [cl-raylib](https://github.com/longlene/cl-raylib) | 4.0 | [Common Lisp](https://common-lisp.net) | MIT | | [claylib/wrap](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib | | [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 | @@ -37,7 +36,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT | | [jaylib](https://github.com/electronstudio/jaylib/) | 4.5 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | | [raylib-j](https://github.com/CreedVI/Raylib-J) | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | -| [raylib.jl](https://github.com/irishgreencitrus/raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib | +| [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) | 4.5 | [Lua](http://www.lua.org) | ISC | @@ -75,6 +74,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.0 | [Wren](http://wren.io) | ISC | | [raylib-zig](https://github.com/Not-Nik/raylib-zig) | **5.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 | | [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD | | [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **auto** | [BQN](https://mlochbaum.github.io/BQN) | MIT | diff --git a/CHANGELOG b/CHANGELOG index 77df794dbc8e..2141926ce8b2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -642,7 +642,7 @@ Release: raylib 4.0 - 8th Anniversary Edition (05 November 2021) KEY CHANGES: - Naming consistency and coherency: Complete review of the library: syntax, naming, comments, decriptions, logs... - Event Automation System: Support for input events recording and automatic re-playing, useful for automated testing and more! - - Custom game-loop control: Intended for advance users that want to control the events polling and the timming mechanisms + - Custom game-loop control: Intended for advanced users that want to control the events polling and the timming mechanisms - rlgl 4.0: Completely decoupling from platform layer and raylib, intended for standalone usage as single-file header-only - raymath 1.5: Complete review following new conventions, to make it more portable and self-contained - raygui 3.0: Complete review and official new release, more portable and self-contained, intended for tools development diff --git a/CMakeLists.txt b/CMakeLists.txt index 57719691aa5a..a5e3408c8f09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_policy(SET CMP0063 NEW) # Directory for easier includes # Anywhere you see include(...) you can check /cmake for that file -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # RAYLIB_IS_MAIN determines whether the project is being used from root # or if it is added as a dependency (through add_subdirectory for example). @@ -51,7 +51,7 @@ add_subdirectory(src raylib) # Uninstall target if(NOT TARGET uninstall) configure_file( - "${CMAKE_MODULE_PATH}/Uninstall.cmake" + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Uninstall.cmake" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) diff --git a/CMakeOptions.txt b/CMakeOptions.txt index 2c58cd5cc227..b063f02a1516 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -1,4 +1,4 @@ -### Config options ### +# ## Config options ### include(CMakeDependentOption) include(EnumOption) @@ -9,14 +9,14 @@ enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0" "Force a specific # Configuration options option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN}) option(CUSTOMIZE_BUILD "Show options for customizing your Raylib library build." OFF) -option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF) +option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF) option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF) option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF) # Shared library is always PIC. Static library should be PIC too if linked into a shared library option(WITH_PIC "Compile static library as position-independent code" OFF) option(BUILD_SHARED_LIBS "Build raylib as a shared library" OFF) -option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" OFF) +option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" OFF) cmake_dependent_option(USE_AUDIO "Build raylib with audio module" ON CUSTOMIZE_BUILD ON) enum_option(USE_EXTERNAL_GLFW "OFF;IF_POSSIBLE;ON" "Link raylib against system GLFW instead of embedded one") @@ -28,77 +28,9 @@ 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") -# raylib modules included -cmake_dependent_option(SUPPORT_MODULE_RSHAPES "Include module: rshapes" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_MODULE_RTEXTURES "Include module: rtextures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_MODULE_RTEXT "Include module: rtext" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_MODULE_RMODELS "Include module: rmodels" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_MODULE_RAUDIO "Include module: raudio" ON CUSTOMIZE_BUILD ON) +include(ParseConfigHeader) -# rcore.c -cmake_dependent_option(SUPPORT_CAMERA_SYSTEM "Provide camera module (rcamera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_RPRAND_GENERATOR "Include pseudo-random numbers generator (rprand.h), based on Xoshiro128** and SplitMix64" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_DEFAULT_FONT "Default font is loaded on window initialization to be available for the user to render simple text. If enabled, uses external module functions to load default raylib font (module: text)" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_WINMM_HIGHRES_TIMER "Setting a higher resolution can improve the accuracy of time-out intervals in wait functions" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_COMPRESSION_API "Support for compression API" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_EVENTS_AUTOMATION "Support automatic generated events, loading and recording of those events when required" OFF CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_CUSTOM_FRAME_CONTROL "Enabling this flag allows manual control of the frame processes, use at your own risk" OFF CUSTOMIZE_BUILD OFF) - -# rshapes.c -cmake_dependent_option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON CUSTOMIZE_BUILD ON) - -# rtextures.c -cmake_dependent_option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_PIC "Support loading PIC as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_PNM "Support loading PNM as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_QOI "Support loading QOI as textures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_SVG "Support loading SVG as textures" ${OFF} CUSTOMIZE_BUILD OFF) - -# rtext.c -cmake_dependent_option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FONT_ATLAS_WHITE_REC "Support white rec on font atlas bottom-right corner" ON CUSTOMIZE_BUILD ON) - -# rmodels.c -cmake_dependent_option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_VOX "Support loading VOX file format" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_M3D "Support loading M3D file format" ON CUSTOMIZE_BUILD ON) - -# raudio.c -cmake_dependent_option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_QOA "Support loading QOA for sound" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF} CUSTOMIZE_BUILD OFF) - -# utils.c -cmake_dependent_option(SUPPORT_STANDARD_FILEIO "Support standard file io library (stdio.h)" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON CUSTOMIZE_BUILD ON) +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}) +endforeach() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 644a89bf4ce0..78f953baf196 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ Do you enjoy raylib and want to contribute? Nice! You can help with the followin - `Testing` - Can you find some bugs in raylib? This document contains a set of guidelines to contribute to the project. These are mostly guidelines, not rules. -Use your best judgement, and feel free to propose changes to this document in a pull request. +Use your best judgment, and feel free to propose changes to this document in a pull request. ### raylib philosophy @@ -28,14 +28,14 @@ Use your best judgement, and feel free to propose changes to this document in a - [raylib license](LICENSE) - [raylib roadmap](ROADMAP.md) -[raylib Wiki](https://github.com/raysan5/raylib/wiki) contains some information about the library and is open to anyone for edit. +[raylib Wiki](https://github.com/raysan5/raylib/wiki) contains some information about the library and is open to anyone to edit. Feel free to review it if required, just take care not to break something. ### raylib C coding conventions Despite being written in C, raylib does not follow the standard Hungarian notation for C, it [follows Pascal-case/camel-case notation](https://github.com/raysan5/raylib/wiki/raylib-coding-conventions), -more common on C# language. All code formatting decisions have been carefully taken +more common in C# language. All code formatting decisions have been carefully taken to make it easier for students/users to read, write and understand code. Source code is extensively commented for that purpose, raylib primary learning method is: @@ -46,12 +46,12 @@ For detailed information on building raylib and examples, please check [raylib W ### Opening new Issues -To open new issue for raylib (bug, enhancement, discussion...), just try to follow these rules: +To open new issues for raylib (bug, enhancement, discussion...), just try to follow these rules: - Make sure the issue has not already been reported before by searching on GitHub under Issues. - If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a title and clear description, as much relevant information as possible, and a code sample demonstrating the unexpected behavior. - - If applies, attach some screenshot of the issue and a .zip file with the code sample and required resources. + - If applicable, attach some screenshot of the issue and a .zip file with the code sample and required resources. - On issue description, add a brackets tag about the raylib module that relates to this issue. If don't know which module, just report the issue, I will review it. - You can check other issues to see how is being done! @@ -60,7 +60,7 @@ To open new issue for raylib (bug, enhancement, discussion...), just try to foll - Make sure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. - Don't send big pull requests (lots of changelists), they are difficult to review. It's better to send small pull requests, one at a time. - - Verify that changes don't break the build (at least on Windows platform). As many platforms where you can test it, the better, but don't worry + - Verify that changes don't break the build (at least on Windows platform). The more platforms where you can test it, the better, but don't worry if you cannot test all the platforms. ### Contact information diff --git a/CONVENTIONS.md b/CONVENTIONS.md index 37db230e59db..b7ace0275b42 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -1,6 +1,6 @@ ## C Coding Style Conventions -Here it is a list with some of the code conventions used by raylib: +Here is a list with some of the code conventions used by raylib: Code element | Convention | Example --- | :---: | --- @@ -79,7 +79,7 @@ _NOTE: Avoid any space or special character in the files/dir naming!_ - Data files should be organized by context and usage in the game, think about the loading requirements for data and put all the resources that need to be loaded at the same time together. - Use descriptive names for the files, it would be perfect if just reading the name of the file, it was possible to know what is that file and where fits in the game. - - Here it is an example, note that some resources require to be loaded all at once while other require to be loaded only at initialization (gui, font). + - Here is an example, note that some resources require to be loaded all at once while other require to be loaded only at initialization (gui, font). ``` resources/audio/fx/long_jump.wav diff --git a/FAQ.md b/FAQ.md index be06657b92b1..d2f9308acf69 100644 --- a/FAQ.md +++ b/FAQ.md @@ -40,13 +40,13 @@ Yes, raylib can be used to create any kind of application, not just videogames. ### How can I learn to use raylib? Is there some official documentation or tutorials? -raylib does not provide a "standard" API reference documentation like other libraries, all of the raylib functionality is exposed in a simple [cheatsheet](https://www.raylib.com/cheatsheet/cheatsheet.html). Most of the functions are self-explanatory and the required parameters are very intuitive. It's also highly recommended to take a look to [`raylib.h`](https://github.com/raysan5/raylib/blob/master/src/raylib.h) header file or even the source code, that is very clean and organized, intended for teaching. +raylib does not provide a "standard" API reference documentation like other libraries, all of the raylib functionality is exposed in a simple [cheatsheet](https://www.raylib.com/cheatsheet/cheatsheet.html). Most of the functions are self-explanatory and the required parameters are very intuitive. It's also highly recommended to take a look at [`raylib.h`](https://github.com/raysan5/raylib/blob/master/src/raylib.h) header file or even the source code, that is very clean and organized, intended for teaching. raylib also provides a big [collection of examples](https://www.raylib.com/examples.html), to showcase the multiple functionality usage (+120 examples). Examples are categorized by the internal module functionality and also define an estimated level of difficulty to guide the users checking them. There is also a [FAQ on the raylib Wiki](https://github.com/raysan5/raylib/wiki/Frequently-Asked-Questions) with common technical questions. -There are also many tutorials on the internet and YouTube created by the growing raylib community along the years. +There are also many tutorials on the internet and YouTube created by the growing raylib community over the years. [raylib Discord Community](https://discord.gg/raylib) is also a great place to join and ask questions, the community is very friendly and always ready to help. @@ -56,7 +56,7 @@ raylib is [free and open source](https://github.com/raysan5/raylib). Anyone can ### What is the raylib license? -raylib source code is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software. Check [LICENSE](https://github.com/raysan5/raylib/blob/master/LICENSE) for further details. +raylib source code is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed-source software. Check [LICENSE](https://github.com/raysan5/raylib/blob/master/LICENSE) for further details. ### What platforms are supported by raylib? @@ -90,25 +90,25 @@ I personally consider raylib a graphics library with some high-level features ra ### What does raylib provide that other engines or libraries don't? -I would say "simplicity" and "enjoyment" at a really low-level of coding but actually is up to the user to discover it, to try it and to see if it fits their needs. raylib is not good for everyone but it's worth a try. +I would say "simplicity" and "enjoyment" at a really low level of coding but actually is up to the user to discover it, to try it and to see if it fits their needs. raylib is not good for everyone but it's worth a try. ### How does raylib compare to Unity/Unreal/Godot? Those engines are usually big and complex to use, providing lot of functionality. They require some time to learn and test, they usually abstract many parts of the game development process and they usually provide a set of tools to assist users on their creations (like a GUI editor). -raylib is a simple programming library, with no integrated tools or editors. It gives full control to users at a very low-level to create graphics applications in a more handmade way. +raylib is a simple programming library, with no integrated tools or editors. It gives full control to users at a very low level to create graphics applications in a more handmade way. ### What development tools are required for raylib? To develop raylib programs you only need a text editor (with recommended code syntax highlighting) and a compiler. -A [raylib Windows Installer](https://raysan5.itch.io/raylib) package is distributed including the Notepad++ editor and MinGW (GCC) compiler pre-configured for Windows for new users as an starter-pack but for more advance configurations with other editors/compilers, [raylib Wiki](https://github.com/raysan5/raylib/wiki) provides plenty of configuration tutorials. +A [raylib Windows Installer](https://raysan5.itch.io/raylib) package is distributed including the Notepad++ editor and MinGW (GCC) compiler pre-configured for Windows for new users as an starter-pack but for more advanced configurations with other editors/compilers, [raylib Wiki](https://github.com/raysan5/raylib/wiki) provides plenty of configuration tutorials. ### What are raylib's external dependencies? -raylib is self-contained, it has no external dependencies to build it. But internally raylib uses several libraries from other developers, mostly used to load specific file-formats. +raylib is self-contained, it has no external dependencies to build it. But internally raylib uses several libraries from other developers, mostly used to load specific file formats. -A detailed list of raylib dependencies could be found on the [raylib Wiki](https://github.com/raysan5/raylib/wiki/raylib-dependencies). +A detailed list of raylib dependencies can be found on the [raylib Wiki](https://github.com/raysan5/raylib/wiki/raylib-dependencies). ### Can I use raylib with other technologies or libraries? @@ -129,10 +129,10 @@ No, raylib is built on top of OpenGL API, and there are currently no plans to su ### What could I expect to see in raylib in the future? -The main focus of the library is simplicity. Most of the efforts are invested in maintainability and bug-fixing. Despite new small features are regularly added, it's not the objective for raylib to become a full-featured engine. Personally I prefer to keep it small and enjoyable. +The main focus of the library is simplicity. Most of the efforts are invested in maintainability and bug-fixing. Despite new small features being regularly added, it's not the objective for raylib to become a full-featured engine. Personally I prefer to keep it small and enjoyable. ### Who are the raylib developers? -The main raylib developer and maintainer is [Ramon Santamaria](https://www.linkedin.com/in/raysan/) but there's 360+ contributors that have helped by adding new features, testing the library and solving issues in the 9+ years life of raylib. +The main raylib developer and maintainer is [Ramon Santamaria](https://www.linkedin.com/in/raysan/) but there are 360+ contributors that have helped by adding new features, testing the library and solving issues in the 9+ years life of raylib. The full list of raylib contributors can be seen [on GitHub](https://github.com/raysan5/raylib/graphs/contributors). diff --git a/HISTORY.md b/HISTORY.md index de14b651c0a9..035054dbe971 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,13 +3,13 @@ introduction ------------ -I started developing videogames in 2006 and some years later I started teaching videogames development to young people with artistic profile, most of students had never written a single line of code. +I started developing videogames in 2006 and some years later I started teaching videogames development to young people with artistic profiles, most of students had never written a single line of code. I decided to start with C language basis and, after searching for the most simple and easy-to-use library to teach videogames programming, I found [WinBGI](https://winbgim.codecutter.org/); it was great and it worked very well with students, in just a couple of weeks, those students that had never written a single line of code were able to program (and understand) a simple PONG game, some of them even a BREAKOUT! -But WinBGI was not the clearer and most organized library for my taste. There were lots of things I found confusing and some function names were not clear enough for most of the students; not to mention the lack of transparencies support and no hardware acceleration. +But WinBGI was not the clearest and most organized library for my taste. There were lots of things I found confusing and some function names were not clear enough for most of the students; not to mention the lack of transparencies support and no hardware acceleration. -So, I decided to create my own library, hardware accelerated, clear function names, quite organized, well structured, plain C coding and, the most important, primarily intended to learn videogames programming. +So, I decided to create my own library, hardware accelerated, clear function names, quite organized, well structured, plain C coding and, most importantly, primarily intended to learn videogames programming. My previous videogames development experience was mostly in C# and [XNA](https://en.wikipedia.org/wiki/Microsoft_XNA) and I really loved it, so, I decided to use C# language style notation and XNA naming conventions. That way, students were able to move from raylib to XNA, MonoGame or similar libs extremely easily. @@ -20,28 +20,28 @@ Enjoy it. notes on raylib 1.1 ------------------- -On April 2014, after 6 month of first raylib release, raylib 1.1 has been released. This new version presents a complete internal redesign of the library to support OpenGL 1.1, OpenGL 3.3+ and OpenGL ES 2.0. +On April 2014, after 6 months of first raylib release, raylib 1.1 was released. This new version presents a complete internal redesign of the library to support OpenGL 1.1, OpenGL 3.3+ and OpenGL ES 2.0. - A new module named [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been added to the library. This new module translates raylib-OpenGL-style immediate mode functions (i.e. rlVertex3f(), rlBegin(), ...) to different versions of OpenGL (1.1, 3.3+, ES2), selectable by one define. - [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) also comes with a second new module named [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h), which includes a bunch of useful functions for 3d-math with vectors, matrices and quaternions. -Some other big changes of this new version have been the support for OGG files loading and stream playing, and the support of DDS texture files (compressed and uncompressed) along with mipmaps support. +Some other big changes of this new version have been the support for OGG file loading and stream playing, and the support of DDS texture files (compressed and uncompressed) along with mipmaps support. -Lots of code changes and lot of testing have concluded in this amazing new raylib 1.1. +Lots of code changes and a lot of testing have concluded in this amazing new raylib 1.1. notes on raylib 1.2 ------------------- -On September 2014, after 5 month of raylib 1.1 release, it comes raylib 1.2. Again, this version presents a complete internal redesign of [core](https://github.com/raysan5/raylib/blob/master/src/rcore.c) module to support two new platforms: [Android](http://www.android.com/) and [Raspberry Pi](http://www.raspberrypi.org/). +On September 2014, after 5 months of raylib 1.1 release, it comes raylib 1.2. Again, this version presents a complete internal redesign of [core](https://github.com/raysan5/raylib/blob/master/src/rcore.c) module to support two new platforms: [Android](http://www.android.com/) and [Raspberry Pi](http://www.raspberrypi.org/). -It's been some month of really hard work to accomodate raylib to those new platforms while keeping it easy for the users. On Android, raylib manages internally the activity cicle, as well as the inputs; on Raspberry Pi, a complete raw input system has been written from scratch. +It's been some months of really hard work to accommodate raylib to those new platforms while keeping it easy for the users. On Android, raylib manages internally the activity cycle, as well as the inputs; on Raspberry Pi, a complete raw input system has been written from scratch. - - A new display initialization system has been created to support multiple resolutions, adding black bars if required; user only defines desired screen size and it gets properly displayed. + - A new display initialization system has been created to support multiple resolutions, adding black bars if required; the user only defines the desired screen size and it gets properly displayed. - Now raylib can easily deploy games to Android devices and Raspberry Pi (console mode). -Lots of code changes and lot of testing have concluded in this amazing new raylib 1.2. +Lots of code changes and a lot of testing have concluded in this amazing new raylib 1.2. In December 2014, new raylib 1.2.2 was published with support to compile directly for web (html5) using [emscripten](http://kripken.github.io/emscripten-site/) and [asm.js](http://asmjs.org/). @@ -50,26 +50,26 @@ notes on raylib 1.3 On September 2015, after 1 year of raylib 1.2 release, arrives raylib 1.3. This version adds shaders functionality, improves tremendously textures module and also provides some new modules (camera system, gestures system, immediate-mode gui). - - Shaders support is the biggest addition to raylib 1.3, with support for easy shaders loading and use. Loaded shaders can be attached to 3d models or used as fullscreen postrocessing effects. A bunch of postprocessing shaders are also included in this release, check raylib/shaders folder. + - Shaders support is the biggest addition to raylib 1.3, with support for easy shaders loading and use. Loaded shaders can be attached to 3d models or used as fullscreen post-processing effects. A bunch of postprocessing shaders are also included in this release, check raylib/shaders folder. - Textures module has grown to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT); raylib 1.3 can load .dds, .pkm, .ktx, .astc and .pvr files. - - A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/rcamera.c) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_first_person.c). + - A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/rcamera.h) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_first_person.c). - New [gestures](https://github.com/raysan5/raylib/blob/master/src/rgestures.h) module simplifies gestures detection on Android and HTML5 programs. - - [raygui](https://github.com/raysan5/raylib/blob/master/src/raygui.h), the new immediate-mode GUI module offers a set of functions to create simple user interfaces, primary intended for tools development. It's still in experimental state but already fully functional. + - [raygui](https://github.com/raysan5/raylib/blob/master/examples/shapes/raygui.h), the new immediate-mode GUI module offers a set of functions to create simple user interfaces, primarily intended for tools development. It's still in an experimental state but already fully functional. Most of the examples have been completely rewritten and +10 new examples have been added to show the new raylib features. -Lots of code changes and lot of testing have concluded in this amazing new raylib 1.3. +Lots of code changes and a lot of testing have concluded in this amazing new raylib 1.3. notes on raylib 1.4 ------------------- On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version, lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added. - - First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now a basic image processing can be done before converting the image to texture for usage. + - First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1331) that have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now basic image processing can be done before converting the image to texture for usage. - SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file. @@ -77,12 +77,12 @@ On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For - [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline. - - [gestures](https://github.com/raysan5/raylib/blob/master/src/rgestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code. + - [gestures](https://github.com/raysan5/raylib/blob/master/src/rgestures.h) module has been redesigned and simplified, now it can process touch events from any source, including the mouse. This way, gestures system can be used on any platform providing a unified way to work with inputs and allowing the user to create multiplatform games with only one source code. - Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental). Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions, -and the addition of two simple functions for persistent data storage. Now raylib user can save and load game data in a file (only some platforms supported). A simple [easings](https://github.com/raysan5/raylib/blob/master/src/easings.h) module has also been added for values animation. +and the addition of two simple functions for persistent data storage. Now raylib users can save and load game data in a file (only some platforms are supported). A simple [easings](https://github.com/raysan5/raylib/blob/master/examples/shapes/reasings.h) module has also been added for values animation. Up to 8 new code examples have been added to show the new raylib features and +10 complete game samples have been provided to learn how to create some classic games like Arkanoid, Asteroids, Missile Commander, Snake or Tetris. @@ -94,36 +94,36 @@ notes on raylib 1.5 On July 2016, after 5 months of raylib 1.4 release, arrives raylib 1.5. This new version is the biggest boost of the library until now, lots of parts of the library have been redesigned, lots of bugs have been solved and some **AMAZING** new features have been added. - - VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameteres, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c). + - VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameters, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c). - New materials system: now raylib supports standard material properties for 3D models, including diffuse-ambient-specular colors and diffuse-normal-specular textures. Just assign values to standard material and everything is processed internally. - - New lighting system: added support for up to 8 configurable lights and 3 light types: **point**, **directional** and **spot** lights. Just create a light, configure its parameters and raylib manages render internally for every 3d object using standard material. + - New lighting system: added support for up to 8 configurable lights and 3 light types: **point**, **directional** and **spot** lights. Just create a light, configure its parameters and raylib manages to render internally for every 3d object using standard material. - Complete gamepad support on Raspberry Pi: Gamepad system has been completely redesigned. Now multiple gamepads can be easily configured and used; gamepad data is read and processed in raw mode in a second thread. - - Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been singnificantly improved, now physic objects are managed internally in a second thread. + - Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been significantly improved, now physic objects are managed internally in a second thread. - - Audio chiptunese support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All this features thanks to the amazing work of @kd7tck. + - Audio chiptunes support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All these features thanks to the amazing work of @kd7tck. -Other additions include a [2D camera system](https://github.com/raysan5/raylib/blob/master/examples/core_2d_rcamera.c), render textures for offline render (and most comprehensive [postprocessing](https://github.com/raysan5/raylib/blob/master/examples/shaders_postprocessing.c)) or support for legacy OpenGL 2.1 on desktop platforms. +Other additions include a [2D camera system](https://github.com/raysan5/raylib/blob/master/examples/core/core_2d_rcamera.c), render textures for offline render (and most comprehensive [postprocessing](https://github.com/raysan5/raylib/blob/master/examples/shaders/shaders_postprocessing.c)) or support for legacy OpenGL 2.1 on desktop platforms. -This new version is so massive that is difficult to list all the improvements, most of raylib modules have been reviewed and [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.c) module has been completely redesigned to accomodate to new material-lighting systems and stereo rendering. You can check [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) file for a more detailed list of changes. +This new version is so massive that is difficult to list all the improvements, most of the raylib modules have been reviewed and [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely redesigned to accommodate to new material-lighting systems and stereo rendering. You can check [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) file for a more detailed list of changes. -Up to 8 new code examples have been added to show the new raylib features and also some samples to show the usage of [rlgl](https://github.com/raysan5/raylib/blob/master/examples/rlgl_standalone.c) and [audio](https://github.com/raysan5/raylib/blob/master/examples/audio_standalone.c) raylib modules as standalone libraries. +Up to 8 new code examples have been added to show the new raylib features and also some samples to show the usage of [rlgl](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c) and [audio](https://github.com/raysan5/raylib/blob/master/examples/audio_standalone.c) raylib modules as standalone libraries. Lots of code changes (+400 commits) and lots of hours of hard work have concluded in this amazing new raylib 1.5. notes on raylib 1.6 ------------------- -On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version conmmemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features: +On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version commemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features: - Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality. - - Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more! + - Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completely self-contained, no external libraries are required anymore! - - [Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing! + - [Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, the library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing! - Camera and gestures modules have been reviewed, highly simplified and ported to single-file header-only libraries for easier portability and usage flexibility. Consequently, camera system usage has been simplified in all examples. @@ -131,41 +131,41 @@ On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new v - Improved textures and text functionality, adding new functions for texture filtering control and better TTF/AngelCode fonts loading and generation support. -Build system improvement. Added support for raylib dynamic library generation (raylib.dll) for users that prefer dynamic library linking. Also thinking on advance users, it has been added pre-configured [Visual Studio C++ 2015 solution](https://github.com/raysan5/raylib/tree/master/project/vs2015) with raylib project and C/C++ examples for users that prefer that professional IDE and compiler. +Build system improvement. Added support for raylib dynamic library generation (raylib.dll) for users that prefer dynamic library linking. Also thinking on advanced users, it has been added pre-configured [Visual Studio C++ 2015 solution](https://github.com/raysan5/raylib/tree/master/projects/vs2015) with raylib project and C/C++ examples for users that prefer that professional IDE and compiler. New examples, new functions, complete code-base review, multiple bugs corrected... this is raylib 1.6. Enjoy making games. notes on raylib 1.7 ------------------- -On May 2017, around 6 month after raylib 1.6, comes another raylib instalment, raylib 1.7. This time library has been improved a lot in terms of consistency and cleanness. As stated in [this patreon article](https://www.patreon.com/posts/raylib-future-7501034), this new raylib version has focused efforts in becoming more simple and easy-to-use to learn videogames programming. Some highlights of this new version are: +On May 2017, around 6 months after raylib 1.6, comes another raylib installment, raylib 1.7. This time library has been improved a lot in terms of consistency and cleanness. As stated in [this patreon article](https://www.patreon.com/posts/raylib-future-7501034), this new raylib version has focused efforts in becoming more simple and easy-to-use to learn videogames programming. Some highlights of this new version are: - More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, functions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions! - - Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advance users can customize raylib just choosing desired features, defining some configuration flags on modules compilation. That way users can control library size and available functionality. + - Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advanced users can customize raylib just by choosing desired features, and defining some configuration flags on modules compilation. That way users can control library size and available functionality. - - Improved [build system](https://github.com/raysan5/raylib/blob/master/src/Makefile) for all supported platforms (Windows, Linux, OSX, RPI, Android, HTML5) with a unique Makefile to compile sources. Added support for Android compilation with a custom standalone toolchain and also multiple build compliation flags. + - Improved [build system](https://github.com/raysan5/raylib/blob/master/src/Makefile) for all supported platforms (Windows, Linux, OSX, RPI, Android, HTML5) with a unique Makefile to compile sources. Added support for Android compilation with a custom standalone toolchain and also multiple build compilation flags. - - New [examples](http://www.raylib.com/examples.html) and [sample games](http://www.raylib.com/games.html) added. All samples material has been reviewed, removing useless examples and adding more comprehensive ones; all material has been ported to latest raylib version and tested in multiple platforms. Examples folder structure has been improved and also build systems. + - New [examples](http://www.raylib.com/examples.html) and [sample games](http://www.raylib.com/games.html) added. All sample material has been reviewed, removing useless examples and adding more comprehensive ones; all material has been ported to the latest raylib version and tested on multiple platforms. Examples folder structure has been improved and also build systems. - - Improved library consistency and organization in general. Functions and parameters have been renamed, some parts of the library have been cleaned and simplyfied, some functions has been moved to examples (lighting, Oculus Rift CV1 support) towards a more generic library implementation. Lots of hours have been invested in this process... + - Improved library consistency and organization in general. Functions and parameters have been renamed, some parts of the library have been cleaned and simplified, some functions have been moved to examples (lighting, Oculus Rift CV1 support) towards a more generic library implementation. Lots of hours have been invested in this process... Some other features: Gamepad support on HTML5, RPI touch screen support, 32bit audio support, frames timing improvements, public log system, rres file format support, automatic GIF recording... -And here it is another version of **raylib, a simple and easy-to-use library to enjoy videogames programming**. Enjoy it. +And here is another version of **raylib, a simple and easy-to-use library to enjoy videogames programming**. Enjoy it. notes on raylib 1.8 ------------------- October 2017, around 5 months after latest raylib version, another release is published: raylib 1.8. Again, several modules of the library have been reviewed and some new functionality added. Main changes of this new release are: - - [Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning pourpouses. + - [Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning purposes. - [Parametric mesh generation](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing. - - PBR Materials support, a completely redesigned shaders and material system allows advance materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference. + - PBR Materials support, a completely redesigned shaders and material system allows advanced materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference. - - Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts. + - Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into the final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts. - [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions. @@ -178,37 +178,37 @@ New installer provided, web updated, examples re-builded, documentation reviewed notes on raylib 2.0 ------------------- -It's been 9 month since last raylib version was published, a lots of things have changed since then... This new raylib version represents an inflexion point in the development of the library and so, we jump to a new major version... Here it is the result of almost **5 years and thousands of hours of hard work**... here it is... **raylib 2.0** +It's been 9 months since last raylib version was published, a lot of things have changed since then... This new raylib version represents an inflection point in the development of the library and so, we jump to a new major version... Here is the result of almost **5 years and thousands of hours of hard work**... here is... **raylib 2.0** In **raylib 2.0** the full API has been carefully reviewed for better consistency, some new functionality has been added and the overall raylib experience has been greatly improved... The key features of new version are: - - **Complete removal of external dependencies.** Finally, raylib does not require external libraries to be installed and linked along with raylib, all required libraries are contained and compiled within raylib. Obviously some external libraries are required but only the strictly platform-dependant ones, the ones that come installed with the OS. So, raylib becomes a self-contained platform-independent games development library. + - **Complete removal of external dependencies.** Finally, raylib does not require external libraries to be installed and linked along with raylib, all required libraries are contained and compiled within raylib. Obviously some external libraries are required but only the strictly platform-dependent ones, the ones that come installed with the OS. So, raylib becomes a self-contained platform-independent games development library. - **Full redesign of audio module to use the amazing miniaudio library**, along with external dependencies removal, OpenAL library has been replaced by [miniaudio](https://github.com/dr-soft/miniaudio), this brand new library offers automatic dynamic linking with default OS audio systems. Undoubtedly, the perfect low-level companion for raylib audio module! - - **Support for continuous integration building*** through AppVeyor and Travis CI. Consequently, raylib GitHub develop branch has been removed, simplyfing the code-base to a single master branch, always stable. Every time a new commit is deployed, library is compiled for **up-to 12 different configurations**, including multiple platforms, 32bit/64bit and multiple compiler options! All those binaries are automatically attached to any new release! + - **Support for continuous integration building*** through AppVeyor and Travis CI. Consequently, raylib GitHub develop branch has been removed, simplifying the code-base to a single master branch, always stable. Every time a new commit is deployed, library is compiled for **up-to 12 different configurations**, including multiple platforms, 32bit/64bit and multiple compiler options! All those binaries are automatically attached to any new release! - **More platforms supported and tested**, including BSD family (FreeBSD, openBSD, NetBSD, DragonFly) and Linux-based family platforms (openSUSE, Debian, Ubuntu, Arch, NixOS...). raylib has already been added to some package managers! Oh, and last but not less important, **Android 64bit** is already supported by raylib! - - **Support for TCC compiler!** Thanks to the lack of external dependencies, raylib can now be easily compiled with a **minimal toolchain**, like the one provide by Tiny C Compiler. It opens the door to an amazing future, allowing, for example, static linkage of libtcc for **runtime compilation of raylib-based code**... and the library itself if required! Moreover, TCC is blazing fast, it can compile all raylib in a couple of seconds! + - **Support for TCC compiler!** Thanks to the lack of external dependencies, raylib can now be easily compiled with a **minimal toolchain**, like the one provided by Tiny C Compiler. It opens the door to an amazing future, allowing, for example, static linkage of libtcc for **runtime compilation of raylib-based code**... and the library itself if required! Moreover, TCC is blazing fast, it can compile all raylib in a couple of seconds! - - Refactored all raylib configuration #defines into a **centralized `config.h` header**, with more than **40 possible configuration options** to compile a totally customizable raylib version including only desired options like supported file-formats or specific functionality support. It allows generating a trully ligth-weight version of the library if desired! + - Refactored all raylib configuration #defines into a **centralized `config.h` header**, with more than **40 possible configuration options** to compile a totally customizable raylib version including only desired options like supported file formats or specific functionality support. It allows generating a trully ligth-weight version of the library if desired! A part of that, lots of new features, like a brand **new font rendering and packaging system** for TTF fonts with **SDF support** (thanks to the amazing STB headers), new functions for **CPU image data manipulation**, new orthographic 3d camera mode, a complete review of `raymath.h` single-file header-only library for better consistency and performance, new examples and way, [way more](https://github.com/raysan5/raylib/blob/master/CHANGELOG). -Probably by now, **raylib 2.0 is the simplest and easiest-to-use library to enjoy (and learn) videogames programming**... but, undoubtedly its development has exceeded any initial objective; raylib has become a simple and easy-to-use trully multiplatform portable standalone media library with thousands of possibilities... and that's just the beginning! +Probably by now, **raylib 2.0 is the simplest and easiest-to-use library to enjoy (and learn) videogames programming**... but, undoubtedly its development has exceeded any initial objective; raylib has become a simple and easy-to-use truly multiplatform portable standalone media library with thousands of possibilities... and that's just the beginning! notes on raylib 2.5 ------------------- -After almost one years since latest raylib installment, here it is **raylib 2.5**. A lot of work has been put on this new version and consequently I decided to bump versioning several digits. The complete list of changes and additions is humungous, details can be found in the [CHANGELOG](CHANGELOG), and here it is a short recap with the highlight improvements. +After almost one years since latest raylib installment, here is **raylib 2.5**. A lot of work has been put on this new version and consequently I decided to bump versioning several digits. The complete list of changes and additions is humungous, details can be found in the [CHANGELOG](CHANGELOG), and here is a short recap with the highlight improvements. - New **window management and file system functions** to query monitor information, deal with clipboard, check directory files info and even launch a URL with default system web browser. Experimental **High-DPI monitor support** has also been added through a compile flag. - **Redesigned Gamepad mechanism**, now generic for all platforms and gamepads, no more specific gamepad configurations. **Redesigned UWP input system**, now raylib supports UWP seamlessly, previous implementation required a custom input system implemented in user code. - - `rlgl` module has been redesigned to **support a unique buffer for shapes drawing batching**, including LINES, TRIANGLES, QUADS in the same indexed buffer, also added support for multi-buffering if required. Additionally, `rlPushMatrix()`/`rlPopMatrix()` functionality has been reviewed to behave exactly like OpenGL 1.1, `models_rlgl_solar_system` example has been added to illustrate this behaviour. + - `rlgl` module has been redesigned to **support a unique buffer for shapes drawing batching**, including LINES, TRIANGLES, QUADS in the same indexed buffer, also added support for multi-buffering if required. Additionally, `rlPushMatrix()`/`rlPopMatrix()` functionality has been reviewed to behave exactly like OpenGL 1.1, `models_rlgl_solar_system` example has been added to illustrate this behavior. - **VR simulator** has been reviewed to **allow custom configuration of Head-Mounted-Device parameters and distortion shader**, `core_vr_simulator` has been properly adapted to showcase this new functionality, now the VR simulator is a generic configurable stereo rendering system that allows any VR device simulation with just a few lines of code or even dynamic tweaking of HMD parameters. @@ -220,30 +220,30 @@ After almost one years since latest raylib installment, here it is **raylib 2.5* - Experimental **cubemap support**, to automatically load multiple cubemap layouts (`LoadTextureCubemap()`). It required some internal `rlgl` redesign to allow cubemap textures. - - **Skeletal animation support for 3d models**, this addition implied a redesign of `Model` data structure to accomodate multiple mesh/multiple materials support and bones information. Multiple models functions have been reviewed and added on this process, also **glTF models loading support** has been added. + - **Skeletal animation support for 3d models**, this addition implied a redesign of `Model` data structure to accommodate multiple mesh/multiple materials support and bones information. Multiple models functions have been reviewed and added on this process, also **glTF models loading support** has been added. -This is a just a brief list with some of the changes of the new **raylib 2.5** but there is way more, about **70 new functions** have been added and several subsystems have been redesigned. More than **30 new examples** have been created to show the new functionalities and better illustrate already available ones. +This is just a brief list with some of the changes of the new **raylib 2.5** but there is way more, about **70 new functions** have been added and several subsystems have been redesigned. More than **30 new examples** have been created to show the new functionalities and better illustrate already available ones. It has been a long year of hard work to make raylib a solid technology to develop new products over it. notes on raylib 3.0 ------------------- -After **10 months of intense development**, new raylib version is ready. Despite primary intended as a minor release, the [CHANGELIST](CHANGELOG) has grown so big and the library has changed so much internally that it finally became a major release. Library **internal ABI** has reveived a big redesign and review, targeting portability, integration with other platforms and making it a perfect option for other progamming [language bindings](BINDINGS.md). +After **10 months of intense development**, new raylib version is ready. Despite primary intended as a minor release, the [CHANGELIST](CHANGELOG) has grown so big and the library has changed so much internally that it finally became a major release. Library **internal ABI** has received a big redesign and review, targeting portability, integration with other platforms and making it a perfect option for other programming [language bindings](BINDINGS.md). - - All **global variables** from the multiple raylib modules have been moved to a **global context state**, it has several benefits, first, better code readability with more comprehensive variables naming and categorization (organized by types, i.e. `CORE.Window.display.width`, `CORE.Input.Keyboard.currentKeyState` or `RLGL.State.modelview`). Second, it allows better memory management to load global context state dynamically when required (not at the moment), making it easy to implement a **hot-reloading mechanism** if desired. + - All **global variables** from the multiple raylib modules have been moved to a **global context state**, it has several benefits, first, better code readability with more comprehensive variable naming and categorization (organized by types, i.e. `CORE.Window.display.width`, `CORE.Input.Keyboard.currentKeyState` or `RLGL.State.modelview`). Second, it allows better memory management to load global context state dynamically when required (not at the moment), making it easy to implement a **hot-reloading mechanism** if desired. - - All **memory allocations** on raylib and its dependencies now use `RL_MALLOC`, `RL_FREE` and similar macros. Now users can easely hook their own memory allocations mechanism if desired, having more control over memory allocated internally by the library. Additionally, it makes it easier to port the library to embedded devices where memory control is critical. For more info check raylib issue #1074. + - All **memory allocations** on raylib and its dependencies now use `RL_MALLOC`, `RL_FREE` and similar macros. Now users can easily hook their own memory allocation mechanism if desired, having more control over memory allocated internally by the library. Additionally, it makes it easier to port the library to embedded devices where memory control is critical. For more info check raylib issue #1074. - All **I/O file accesses** from raylib are being moved to **memory data access**, now all I/O file access is centralized into just four functions: `LoadFileData()`, `SaveFileData()`, `LoadFileText()`, `SaveFileText()`. Users can just update those functions to any I/O file system. This change makes it easier to integrate raylib with **Virtual File Systems** or custom I/O file implementations. - All **raylib data structures** have been reviewed and optimized for pass-by-value usage. One of raylib distinctive design decisions is that most of its functions receive and return data by value. This design makes raylib really simple for newcomers, avoiding pointers and allowing complete access to all structures data in a simple way. The downside is that data is copied on stack every function call and that copy could be costly so, all raylib data structures have been optimized to **stay under 64 bytes** for fast copy and retrieve. - - All **raylib tracelog messages** have been reviewd and categorized for a more comprehensive output information when developing raylib applications, now all display, input, timer, platform, auxiliar libraries, file-accesses, data loading/unloading issues are properly reported with more detailed and visual messages. + - All **raylib tracelog messages** have been reviewed and categorized for a more comprehensive output information when developing raylib applications, now all display, input, timer, platform, auxiliar libraries, file-accesses, data loading/unloading issues are properly reported with more detailed and visual messages. - - `raudio` module has been internally reviewed to accomodate the new `Music` structure (converted from previous pointer format) and the module has been adapted to the **highly improved** [`miniaudio v0.10`](https://github.com/dr-soft/miniaudio). + - `raudio` module has been internally reviewed to accommodate the new `Music` structure (converted from previous pointer format) and the module has been adapted to the **highly improved** [`miniaudio v0.10`](https://github.com/dr-soft/miniaudio). - - `text` module reviewed to **improve fonts generation** and text management functions, `Font` structure has been redesigned to better accomodate characters data, decoupling individual characters as `Image` glyphs from the font atlas parameters. Several improvements have been made to better support Unicode strings with UTF-8 encoding. + - `text` module reviewed to **improve fonts generation** and text management functions, `Font` structure has been redesigned to better accommodate characters data, decoupling individual characters as `Image` glyphs from the font atlas parameters. Several improvements have been made to better support Unicode strings with UTF-8 encoding. - **Multiple new examples added** (most of them contributed by raylib users) and all examples reviewed for correct execution on most of the supported platforms, specially Web and Raspberry Pi. A detailed categorized table has been created on github for easy examples navigation and code access. @@ -274,19 +274,19 @@ Here the list with some highlights for `raylib 3.5`. - NEW **configuration options** exposed: For custom raylib builds, `config.h` now exposes **more than 150 flags and defines** to build raylib with only the desired features, for example, it allows to build a minimal raylib library in just some KB removing all external data filetypes supported, very useful to generate **small executables or embedded devices**. - - NEW **automatic GIF recording** feature: Actually, automatic GIF recording (**CTRL+F12**) for any raylib application has been available for some versions but this feature was really slow and low-performant using an old gif library with many file-accesses. It has been replaced by a **high-performant alternative** (`msf_gif.h`) that operates directly on memory... and actually works very well! Try it out! + - NEW **automatic GIF recording** feature: Actually, automatic GIF recording (**CTRL+F12**) for any raylib application has been available for some versions but this feature was really slow and low-performant using an old gif library with many file accesses. It has been replaced by a **high-performant alternative** (`msf_gif.h`) that operates directly on memory... and actually works very well! Try it out! - - NEW **RenderBatch** system: `rlgl` module has been redesigned to support custom **render batches** to allow grouping draw calls as desired, previous implementation just had one default render batch. This feature has not been exposed to raylib API yet but it can be used by advance users dealing with `rlgl` directly. For example, multiple `RenderBatch` can be created for 2D sprites and 3D geometry independently. + - NEW **RenderBatch** system: `rlgl` module has been redesigned to support custom **render batches** to allow grouping draw calls as desired, previous implementation just had one default render batch. This feature has not been exposed to raylib API yet but it can be used by advanced users dealing with `rlgl` directly. For example, multiple `RenderBatch` can be created for 2D sprites and 3D geometry independently. - - NEW **Framebuffer** system: `rlgl` module now exposes an API for custom **Framebuffer attachments** (including cubemaps!). raylib `RenderTexture` is a basic use-case, just allowing color and depth textures, but this new API allows the creation of more advance Framebuffers with multiple attachments, like the **G-Buffers**. `GenTexture*()` functions have been redesigned to use this new API. + - NEW **Framebuffer** system: `rlgl` module now exposes an API for custom **Framebuffer attachments** (including cubemaps!). raylib `RenderTexture` is a basic use-case, just allowing color and depth textures, but this new API allows the creation of more advanced Framebuffers with multiple attachments, like the **G-Buffers**. `GenTexture*()` functions have been redesigned to use this new API. - Improved **software rendering**: raylib `Image*()` API is intended for software rendering, for those cases when **no GPU or no Window is available**. Those functions operate directly with **multi-format** pixel data on RAM and they have been completely redesigned to be way faster, specially for small resolutions and retro-gaming. Low-end embedded devices like **microcontrollers with custom displays** could benefit of this raylib functionality! - File **loading from memory**: Multiple functions have been redesigned to load data from memory buffers **instead of directly accessing the files**, now all raylib file loading/saving goes through a couple of functions that load data into memory. This feature allows **custom virtual-file-systems** and it gives more control to the user to access data already loaded in memory (i.e. images, fonts, sounds...). - - NEW **Window states** management system: raylib `core` module has been redesigned to support Window **state check and setup more easily** and also **before/after Window initialization**, `SetConfigFlags()` has been reviewed and `SetWindowState()` has been added to control Window minification, maximization, hidding, focusing, topmost and more. + - NEW **Window states** management system: raylib `core` module has been redesigned to support Window **state check and setup more easily** and also **before/after Window initialization**, `SetConfigFlags()` has been reviewed and `SetWindowState()` has been added to control Window minification, maximization, hiding, focusing, topmost and more. - - NEW **GitHub Actions** CI/CD system: Previous CI implementation has been reviewed and improved a lot to support **multiple build configurations** (platforms, compilers, static/shared build) and also an **automatic deploy system** has been implemented to automatically attach the diferent generated artifacts to every new release. As the system seems to work very good, previous CI platforms (AppVeyor/TravisCI) have been removed. + - NEW **GitHub Actions** CI/CD system: Previous CI implementation has been reviewed and improved a lot to support **multiple build configurations** (platforms, compilers, static/shared build) and also an **automatic deploy system** has been implemented to automatically attach the different generated artifacts to every new release. As the system seems to work very good, previous CI platforms (AppVeyor/TravisCI) have been removed. A part of those changes, many new functions have been added, some redundant functions removed and many functions have been reviewed for consistency with the full API (function name, parameters name and order, code formatting...). Again, this release represents is a **great improvement for raylib and marks the way forward** for the library. Make sure to check [CHANGELOG](CHANGELOG) for details! Hope you enjoy it! @@ -295,7 +295,7 @@ Happy holidays! :) notes on raylib 3.7 ------------------- -April 2021, it's been about 4 months since last raylib release and here it is already a new one, this time with a bunch of internal redesigns and improvements. Surprisingly, on April the 8th I was awarded for a second time with the [Google Open Source Peer Bonus Award](https://opensource.googleblog.com/2021/04/announcing-first-group-of-google-open-source-peer-bonus-winners.html) for my contribution to open source world with raylib and it seems the library is getting some traction, what a better moment for a new release? Let's see what can be found in this new version: +April 2021, it's been about 4 months since the last raylib release and here is already a new one, this time with a bunch of internal redesigns and improvements. Surprisingly, on April 8th I was awarded for a second time with the [Google Open Source Peer Bonus Award](https://opensource.googleblog.com/2021/04/announcing-first-group-of-google-open-source-peer-bonus-winners.html) for my contribution to open source world with raylib and it seems the library is getting some traction, what a better moment for a new release? Let's see what can be found in this new version: Let's start with some numbers: @@ -315,18 +315,18 @@ Highlights for `raylib 3.7`: - **ADDED: glTF animations support**. glTF is the preferred models file format to be used with raylib and along the addition of a models animation API on latest raylib versions, now animations support for glTF format has come to raylib, thanks for this great contribution to [Hristo Stamenov](@object71) - - **ADDED: Music streaming support from memory**. raylib has been adding the `Load*FromMemory()` option to all its supported file formats but **music streaming** was not supported yet... until now. Thanks to this great contribution by [Agnis "NeZvÄ“rs" Aldiņš](@nezvers), now raylib supports music streamming from memory data for all supported file formats: WAV, OGG, MP3, FLAC, XM and MOD. + - **ADDED: Music streaming support from memory**. raylib has been adding the `Load*FromMemory()` option to all its supported file formats but **music streaming** was not supported yet... until now. Thanks to this great contribution by [Agnis "NeZvÄ“rs" Aldiņš](@nezvers), now raylib supports music streaming from memory data for all supported file formats: WAV, OGG, MP3, FLAC, XM and MOD. - **RENAMED: enums values for consistency**. Most raylib enums names and values names have been renamed for consistency, now all value names start with the type of data they represent. It increases clarity and readability when using those values and also **improves overall library consistency**. -Beside those key changes, many functions have been reviewed with improvements and bug fixes, many of them contributed by the community! Thanks! And again, this release sets a **new milestone for raylib library**. Make sure to check [CHANGELOG](CHANGELOG) for detailed list of changes! Hope you enjoy this new raylib installment! +Besides those key changes, many functions have been reviewed with improvements and bug fixes, many of them contributed by the community! Thanks! And again, this release sets a **new milestone for raylib library**. Make sure to check [CHANGELOG](CHANGELOG) for detailed list of changes! Hope you enjoy this new raylib installment! Happy **gamedev/tools/graphics** programming! :) notes on raylib 4.0 - 8th Anniversary Edition --------------------------------------------- -It's been about 6 months since last raylib release and it's been **8 years since I started with this project**, what an adventure! It's time for a new release: `raylib 4.0`, **the biggest release ever** and an inflexion point for the library. Many hours have been put in this release to make it special, **many library details have been polished**: syntax, naming conventions, code comments, functions descriptions, log outputs... Almost all the issues have been closed (only 3 remain open at the moment of this writing) and some amazing new features have been added. I expect this **`raylib 4.0`** to be a long term version (LTS), stable and complete enough for any new graphic/game/tool application development. +It's been about 6 months since last raylib release and it's been **8 years since I started with this project**, what an adventure! It's time for a new release: `raylib 4.0`, **the biggest release ever** and an inflection point for the library. Many hours have been put in this release to make it special, **many library details have been polished**: syntax, naming conventions, code comments, functions descriptions, log outputs... Almost all the issues have been closed (only 3 remain open at the moment of this writing) and some amazing new features have been added. I expect this **`raylib 4.0`** to be a long-term version (LTS), stable and complete enough for any new graphic/game/tool application development. Let's start with some numbers: @@ -339,11 +339,11 @@ Let's start with some numbers: Highlights for `raylib 4.0`: - - **Naming consistency and coherency**: `raylib` API has been completely reviewed to be consistent on naming conventions for data structures and functions, comments and descriptions have been reviewed, also the syntax of many symbols for consistency; some functions and structs have been renamed (i.e. `struct CharInfo` to `struct GlyphInfo`). Output log messages have been also improved to show more info to the users. Several articles have been writen in this process: [raylib_syntax analysis](https://github.com/raysan5/raylib/wiki/raylib-syntax-analysis) and [raylib API usage analysis](https://gist.github.com/raysan5/7c0c9fff1b6c19af24bb4a51b7383f1e). In general, a big polishment of the library to make it more consistent and coherent. + - **Naming consistency and coherency**: `raylib` API has been completely reviewed to be consistent on naming conventions for data structures and functions, comments and descriptions have been reviewed, also the syntax of many symbols for consistency; some functions and structs have been renamed (i.e. `struct CharInfo` to `struct GlyphInfo`). Output log messages have been also improved to show more info to the users. Several articles have been written in this process: [raylib_syntax analysis](https://github.com/raysan5/raylib/wiki/raylib-syntax-analysis) and [raylib API usage analysis](https://gist.github.com/raysan5/7c0c9fff1b6c19af24bb4a51b7383f1e). In general, a big polishment of the library to make it more consistent and coherent. - - **Event Automation System**: This new _experimental_ feature has been added for future usage, it allows to **record input events and re-play them automatically**. This feature could be very useful to automatize examples testing but also for tutorials with assited game playing, in-game cinematics, speedruns, AI playing and more! Note this feature is still experimental. + - **Event Automation System**: This new _experimental_ feature has been added for future usage, it allows to **record input events and re-play them automatically**. This feature could be very useful to automatize examples testing but also for tutorials with assisted game playing, in-game cinematics, speedruns, AI playing and more! Note this feature is still experimental. - - **Custom game-loop control**: As requested by some advance users, **the game-loop control can be exposed** compiling raylib with the config flag: `SUPPORT_CUSTOM_FRAME_CONTROL`. It's intended for advance users that want to control the events polling and also the timming mechanisms of their games. + - **Custom game-loop control**: As requested by some advanced users, **the game-loop control can be exposed** compiling raylib with the config flag: `SUPPORT_CUSTOM_FRAME_CONTROL`. It's intended for advanced users that want to control the events polling and also the timing mechanisms of their games. - [**`rlgl 4.0`**](https://github.com/raysan5/raylib/blob/master/src/rlgl.h): This module has been completely **decoupled from platform layer** and raylib, now `rlgl` single-file header-only library only depends on the multiple OpenGL backends supported, even the dependency on `raymath` has been removed. Additionally, **support for OpenGL 4.3** has been added, supporting compute shaders and Shader Storage Buffer Objects (SSBO). Now `rlgl` can be used as a complete standalone portable library to wrap several OpenGL version and providing **a simple and easy-to-use pseudo-OpenGL immediate-mode API**. @@ -361,12 +361,12 @@ Highlights for `raylib 4.0`: Those are some of the key features for this new release but actually there is way more! **Support for `VOX` ([MagikaVoxel](https://ephtracy.github.io/)) 3d model format** has been added, **new [raylib_game_template](https://github.com/raysan5/raylib-game-template)** repo shared, **new `EncodeDataBase64()` and `DecodeDataBase64()` functions** added, **improved HiDPI support**, new `DrawTextPro()` with support for text rotations, completely **reviewed `glTF` models loading**, added **`SeekMusicStream()` for music seeking**, many new examples and +20 examples reviewed... **hundreds of improvements and bug fixes**! Make sure to check [CHANGELOG](CHANGELOG) for a detailed list of changes! -Undoubtely, **this is the best raylib ever**. Enjoy gamedev/tools/graphics programming! :) +Undoubtedly, **this is the best raylib ever**. Enjoy gamedev/tools/graphics programming! :) notes on raylib 4.2 ------------------- -**New raylib release!** Nine months after latest raylib, here it is a new version. It was supposed to be just a small update but, actually, it's a huge update with lots of changes a improvements. It has been possible thanks to the many contributors that has helped with issues and improvements, it's the **update with more contributors to date** and that's amazing! +**New raylib release!** Nine months after latest raylib, here is a new version. It was supposed to be just a small update but, actually, it's a huge update with lots of changes a improvements. It has been possible thanks to the many contributors that has helped with issues and improvements, it's the **update with more contributors to date** and that's amazing! Some numbers to start with: @@ -390,7 +390,7 @@ Highlights for `raylib 4.2`: - **New file system API**: Current API has been redesigned to be more comprehensive and better aligned with raylib naming conventions, two new functions are provided `LoadDirectoryFiles()`/`LoadDirectoryFilesEx()` to load a `FilePathList` for provided path, supporting extension filtering and recursive directory scan. `LoadDroppedFiles()` has been renamed to better reflect its internal functionality. Now, all raylib functions that start with `Load*()` allocate memory internally and a equivalent `Unload*()` function is defined to take care of that memory internally when not required any more! - - **New audio stream processors API** (_experimental_): Now real-time audio stream data processors can be added using callbacks to played Music. It allows users to create custom effects for audio like delays of low-pass-filtering (example provided). The new API uses a callback system and it's still _ highly experimental_, it differs from the usual level of complexity that provides raylib and it is intended for advance users. It could change in the future but, actually, `raudio` module is in the spotlight for future updates; [miniaudio](https://github.com/mackron/miniaudio) implements a new higher-level API that can be useful in the future for raylib. + - **New audio stream processors API** (_experimental_): Now real-time audio stream data processors can be added using callbacks to played Music. It allows users to create custom effects for audio like delays of low-pass-filtering (example provided). The new API uses a callback system and it's still _ highly experimental_, it differs from the usual level of complexity that provides raylib and it is intended for advanced users. It could change in the future but, actually, `raudio` module is in the spotlight for future updates; [miniaudio](https://github.com/mackron/miniaudio) implements a new higher-level API that can be useful in the future for raylib. As always, there are more improvements than the key features listed, make sure to check raylib [CHANGELOG](CHANGELOG) for the detailed list of changes; for this release a `WARNING` flag has been added to all the changes that could affect bindings or productivity code. **raylib keeps improving one more version** and a special focus on maintainability has been put on the library for the future. Specific/advance functionality will be provided through **raylib-extras** repos and raylib main repo devlelopment will be focused on what made raylib popular: being a simple and easy-to-use library to **enjoy videogames programming**. @@ -399,7 +399,7 @@ As always, there are more improvements than the key features listed, make sure t notes on raylib 4.5 ------------------- -It's been **7 months** since latest raylib release. As usual, **many parts of the library have been reviewed and improved** along those months. Many issues have been closed, staying under 10 open issues at the moment of this writting and also many PRs from contributors have been received, reviewed and merged into raylib library. Some new functions have been added and some others have been removed to improve library coherence and avoid moving too high level, giving the users the tools to implement advance functionality themselfs over raylib. Again, this is a big release with a considerable amount of changes and improvements. Here it is a small summary highlighting this new **rayib 4.5**. +It's been **7 months** since latest raylib release. As usual, **many parts of the library have been reviewed and improved** along those months. Many issues have been closed, staying under 10 open issues at the moment of this writting and also many PRs from contributors have been received, reviewed and merged into raylib library. Some new functions have been added and some others have been removed to improve library coherence and avoid moving too high level, giving the users the tools to implement advance functionality themselfs over raylib. Again, this is a big release with a considerable amount of changes and improvements. Here is a small summary highlighting this new **rayib 4.5**. Some numbers for this release: @@ -413,7 +413,7 @@ Highlights for `raylib 4.5`: - **`NEW` Improved ANGLE support on Desktop platforms**: Support for OpenGL ES 2.0 on Desktop platforms (Windows, Linux, macOS) has been reviewed by @wtnbgo GitHub user. Now raylib can be compiled on desktop for OpenGL ES 2.0 and linked against [`ANGLE`](https://github.com/google/angle). This _small_ addition open the door to building raylib for all **ANGLE supported backends: Direct3D 11, Vulkan and Metal**. Please note that this new feature is still experimental and requires further testing! - - **`NEW` Camera module**: A brand new implementation from scratch for `rcamera` module, contributed by @Crydsch GitHub user! **New camera system is simpler, more flexible, more granular and more extendable**. Specific camera math transformations (movement/rotation) have been moved to individual functions, exposing them to users if required. Global state has been removed from the module and standalone usage has been greatly improved; now `rcamera.h` single-file header-only library can be used externally, independently of raylib. A new `UpdateCameraPro()` function has been added to address input-dependency of `UpdateCamera()`, now advance users have **full control over camera inputs and movement/rotation speeds**! + - **`NEW` Camera module**: A brand new implementation from scratch for `rcamera` module, contributed by @Crydsch GitHub user! **New camera system is simpler, more flexible, more granular and more extendable**. Specific camera math transformations (movement/rotation) have been moved to individual functions, exposing them to users if required. Global state has been removed from the module and standalone usage has been greatly improved; now `rcamera.h` single-file header-only library can be used externally, independently of raylib. A new `UpdateCameraPro()` function has been added to address input-dependency of `UpdateCamera()`, now advanced users have **full control over camera inputs and movement/rotation speeds**! - **`NEW` Support for M3D models and M3D/GLTF animations**: 3d models animations support has been a limited aspect of raylib for long time, some versions ago IQM animations were supported but raylib 4.5 also adds support for the brand new [M3D file format](https://bztsrc.gitlab.io/model3d/), including animations and the long expected support for **GLTF animations**! The new M3D file format is **simple, portable, feature complete, extensible and open source**. It also provides a complete set of tools to export/visualize M3D models from/to Blender! Now raylib supports up to **3 model file-formats with animations**: `IQM`, `GLTF` and `M3D`. @@ -425,7 +425,7 @@ Highlights for `raylib 4.5`: - **Reviewed `rshapes` module to minimize the rlgl dependency**: Now `rshapes` 2d shapes drawing functions **only depend on 6 low-level functions**: `rlBegin()`, `rlEnd()`, `rlVertex3f()`, `rlTexCoord2f()`, `rlNormal3f()`, `rlSetTexture()`. With only those pseudo-OpenGl 1.1 minimal functionality, everything can be drawn! This improvement converts `rshapes` module in a **self-contained, portable shapes-drawing library that can be used independently of raylib**, as far as entry points for those 6 functions are provided by the user. It even allows to be used for software rendering, with the proper backend! - - **Added data structures validation functions**: Multiple functions have been added by @RobLoach GitHub user to ease the validation of raylib data structures: `IsImageReady()`, `IsTextureReady()`, `IsSoundReady()`... Now users have a simple mechanism to **make sure data has been correctly loaded**, instead of checking internal structure values by themselfs. + - **Added data structures validation functions**: Multiple functions have been added by @RobLoach GitHub user to ease the validation of raylib data structures: `IsImageReady()`, `IsTextureReady()`, `IsSoundReady()`... Now users have a simple mechanism to **make sure data has been correctly loaded**, instead of checking internal structure values by themselves. As usual, those are only some highlights but there is much more! New image generators, new color transformation functionality, improved blending support for color/alpha, etc... Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes! Please, note that all breaking changes have been flagged with a `WARNING` in the CHANGELOG, specially useful for binding creators! @@ -436,7 +436,7 @@ Let's keep **enjoying games/tools/graphics programming!** :) notes on raylib 5.0 ------------------- -It's been **7 months** since latest raylib release and **10 years** since raylib 1.0 was officially released... what an adventure! In the last 10 years raylib has improved a lot, new functions have been added, many new features and improvements implemented, up to **500 contributors** have helped to shape the library as it is today. `raylib 5.0` is the final result of all this incredible amount of work and dedication. Here it is the summary with the key features and additions of this NEW major version of raylib. +It's been **7 months** since latest raylib release and **10 years** since raylib 1.0 was officially released... what an adventure! In the last 10 years raylib has improved a lot, new functions have been added, many new features and improvements implemented, up to **500 contributors** have helped to shape the library as it is today. `raylib 5.0` is the final result of all this incredible amount of work and dedication. Here is the summary with the key features and additions of this NEW major version of raylib. Some numbers for this release: @@ -448,9 +448,9 @@ Some numbers for this release: Highlights for `raylib 5.0`: - - **`rcore` module platform-split**: Probably the biggest raylib redesign in the last 10 years. raylib started as a library targeting 3 desktop platforms: `Windows`, `Linux` and `macOS` (thanks to `GLFW` underlying library) but with the years support for several new platforms has been added (`Android`, `Web`, `Rapsberry Pi`, `RPI native`...); lot of the platform code was shared so the logic was all together on `rcore.c` module, separated by compilation flags. This approach was very handy but also made it very difficult to support new platforms and specially painful for contributors not familiar with the module, navigating +8000 lines of code in a single file. A big redesign was really needed but the amount of work required was humungus and quite scary for a solo-developer like me, moreover considering that everything was working and the chances to break things were really high. Fortunately, some contributors were ready for the task (@ubkp, @michaelfiber, @Bigfoot71) and thanks to their initiative and super-hard work, the `rcore` [platform split](https://github.com/raysan5/raylib/blob/master/src/platforms) has been possible! This new raylib architecture greatly improves the platforms maintenance but also greatly simplifies the addition of new platforms. A [`platforms/rcore_template.c`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_template.c) file is provided with the required structure and functions to be filled for the addition of new platforms, actually it has been simplified to mostly filling some pre-defined functions: `InitPlatform()`, `ClosePlatform`, `PollInputEvents`... Undoubtely, **this redesign opens the doors to a new era for raylib**, letting the users to plug new platforms as desired. + - **`rcore` module platform-split**: Probably the biggest raylib redesign in the last 10 years. raylib started as a library targeting 3 desktop platforms: `Windows`, `Linux` and `macOS` (thanks to `GLFW` underlying library) but with the years support for several new platforms has been added (`Android`, `Web`, `Rapsberry Pi`, `RPI native`...); lot of the platform code was shared so the logic was all together on `rcore.c` module, separated by compilation flags. This approach was very handy but also made it very difficult to support new platforms and specially painful for contributors not familiar with the module, navigating +8000 lines of code in a single file. A big redesign was really needed but the amount of work required was humungous and quite scary for a solo-developer like me, moreover considering that everything was working and the chances to break things were really high. Fortunately, some contributors were ready for the task (@ubkp, @michaelfiber, @Bigfoot71) and thanks to their initiative and super-hard work, the `rcore` [platform split](https://github.com/raysan5/raylib/blob/master/src/platforms) has been possible! This new raylib architecture greatly improves the platforms maintenance but also greatly simplifies the addition of new platforms. A [`platforms/rcore_template.c`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_template.c) file is provided with the required structure and functions to be filled for the addition of new platforms, actually it has been simplified to mostly filling some pre-defined functions: `InitPlatform()`, `ClosePlatform`, `PollInputEvents`... Undoubtedly, **this redesign opens the doors to a new era for raylib**, letting the users to plug new platforms as desired. - - **`NEW` Platform backend supported: SDL**: Thanks to the new `rcore` platform-split, the addition of new platforms/backends to raylib has been greatly simplified. As a proof of concept, [`SDL2`](https://libsdl.org/) platform backend has been added to raylib as an aternative for `GLFW` library for desktop builds: [`platforms/rcore_desktop_sdl`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_sdl.c). Lot of work has been put to provide exactly the same features as the other platforms and carefully test the new implementation. Now `SDL2` fans can use this new backend, just providing the required include libraries on compilation and linkage (not included in raylib, like `GLFW`). `SDL` backend support also **eases the process of supporting a wider range of platforms** that already support `SDL`. + - **`NEW` Platform backend supported: SDL**: Thanks to the new `rcore` platform-split, the addition of new platforms/backends to raylib has been greatly simplified. As a proof of concept, [`SDL2`](https://libsdl.org/) platform backend has been added to raylib as an alternative for `GLFW` library for desktop builds: [`platforms/rcore_desktop_sdl`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_sdl.c). Lot of work has been put to provide exactly the same features as the other platforms and carefully test the new implementation. Now `SDL2` fans can use this new backend, just providing the required include libraries on compilation and linkage (not included in raylib, like `GLFW`). `SDL` backend support also **eases the process of supporting a wider range of platforms** that already support `SDL`. - **`NEW` Platform backend supported: Nintendo Switch (closed source)**: The addition of the `SDL` backend was quite a challenge but to really verify the robustness and ease of the new platform plugin system, adding support for a console was a more demanding adventure. Surprisingly, only two days of work were required to add support for `Nintendo Switch` to raylib! Implementation result showed an outstanding level of simplicity, with a **self-contained module** (`rcore_swith.cpp`) supporting graphics and inputs. Unfortunately this module can not be open-sourced due to licensing restrictions. @@ -468,6 +468,6 @@ As always, those are only some highlights of the new `raylib 5.0` but there is m Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes! -Undoubtely, this is the **biggest raylib update in 10 years**. Many new features and improvements with a special focus on maintainabiliy and long-term sustainability. **Undoubtely, this is the raylib of the future**. +Undoubtedly, this is the **biggest raylib update in 10 years**. Many new features and improvements with a special focus on maintainability and long-term sustainability. **Undoubtedly, this is the raylib of the future**. **Enjoy programming!** :) diff --git a/ROADMAP.md b/ROADMAP.md index 8755333c86c5..87ca2e1c8a28 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # raylib roadmap -Here it is a wishlist with features and ideas to improve the library. Note that features listed here are usually long term improvements or just describe a route to follow for the library. There are also some additional places to look for raylib improvements and ideas: +Here is a wishlist with features and ideas to improve the library. Note that features listed here are usually long term improvements or just describe a route to follow for the library. There are also some additional places to look for raylib improvements and ideas: - [GitHub Issues](https://github.com/raysan5/raylib/issues) has several open issues for possible improvements or bugs to fix. - [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve. @@ -73,7 +73,7 @@ _Current version of raylib is complete and functional but there is always room f **raylib 1.5** - [x] Support Oculus Rift CV1 and VR stereo rendering (simulator) - [x] Redesign Shaders/Textures system -> New Materials system - - [x] Support lighting: Omni, Directional and Spot lights + - [x] Support lighting: Omni, Directional and Spotlights - [x] Redesign physics module (physac) - [x] Chiptunes audio modules support diff --git a/cmake/CompileDefinitions.cmake b/cmake/CompileDefinitions.cmake index cc8324c4be68..0acbe2fa5b96 100644 --- a/cmake/CompileDefinitions.cmake +++ b/cmake/CompileDefinitions.cmake @@ -3,126 +3,22 @@ target_compile_definitions("raylib" PUBLIC "${PLATFORM_CPP}") target_compile_definitions("raylib" PUBLIC "${GRAPHICS}") function(define_if target variable) - if (${${variable}}) + if(${${variable}}) message(STATUS "${variable}=${${variable}}") - target_compile_definitions(${target} PUBLIC "${variable}") - endif () + target_compile_definitions(${target} PRIVATE "${variable}") + endif() endfunction() -if (${CUSTOMIZE_BUILD}) - target_compile_definitions("raylib" PUBLIC EXTERNAL_CONFIG_FLAGS) +if(${CUSTOMIZE_BUILD}) + target_compile_definitions("raylib" PRIVATE EXTERNAL_CONFIG_FLAGS) define_if("raylib" USE_AUDIO) - define_if("raylib" SUPPORT_MODULE_RSHAPES) - define_if("raylib" SUPPORT_MODULE_RTEXTURES) - define_if("raylib" SUPPORT_MODULE_RTEXT) - define_if("raylib" SUPPORT_MODULE_RMODELS) - define_if("raylib" SUPPORT_MODULE_RAUDIO) - define_if("raylib" SUPPORT_CAMERA_SYSTEM) - define_if("raylib" SUPPORT_GESTURES_SYSTEM) - define_if("raylib" SUPPORT_MOUSE_GESTURES) - define_if("raylib" SUPPORT_SSH_KEYBOARD_RPI) - define_if("raylib" SUPPORT_DEFAULT_FONT) - define_if("raylib" SUPPORT_SCREEN_CAPTURE) - define_if("raylib" SUPPORT_GIF_RECORDING) - define_if("raylib" SUPPORT_BUSY_WAIT_LOOP) - define_if("raylib" SUPPORT_EVENTS_WAITING) - define_if("raylib" SUPPORT_WINMM_HIGHRES_TIMER) - define_if("raylib" SUPPORT_COMPRESSION_API) - define_if("raylib" SUPPORT_EVENTS_AUTOMATION) - define_if("raylib" SUPPORT_CUSTOM_FRAME_CONTROL) - define_if("raylib" SUPPORT_QUADS_DRAW_MODE) - define_if("raylib" SUPPORT_IMAGE_EXPORT) - define_if("raylib" SUPPORT_IMAGE_GENERATION) - define_if("raylib" SUPPORT_IMAGE_MANIPULATION) - define_if("raylib" SUPPORT_FILEFORMAT_PNG) - define_if("raylib" SUPPORT_FILEFORMAT_DDS) - define_if("raylib" SUPPORT_FILEFORMAT_HDR) - define_if("raylib" SUPPORT_FILEFORMAT_PIC) - define_if("raylib" SUPPORT_FILEFORMAT_PNM) - define_if("raylib" SUPPORT_FILEFORMAT_KTX) - define_if("raylib" SUPPORT_FILEFORMAT_ASTC) - define_if("raylib" SUPPORT_FILEFORMAT_BMP) - define_if("raylib" SUPPORT_FILEFORMAT_TGA) - define_if("raylib" SUPPORT_FILEFORMAT_JPG) - define_if("raylib" SUPPORT_FILEFORMAT_GIF) - define_if("raylib" SUPPORT_FILEFORMAT_QOI) - define_if("raylib" SUPPORT_FILEFORMAT_PSD) - define_if("raylib" SUPPORT_FILEFORMAT_PKM) - define_if("raylib" SUPPORT_FILEFORMAT_PVR) - define_if("raylib" SUPPORT_FILEFORMAT_SVG) - define_if("raylib" SUPPORT_FILEFORMAT_FNT) - define_if("raylib" SUPPORT_FILEFORMAT_TTF) - define_if("raylib" SUPPORT_TEXT_MANIPULATION) - define_if("raylib" SUPPORT_MESH_GENERATION) - define_if("raylib" SUPPORT_FILEFORMAT_OBJ) - define_if("raylib" SUPPORT_FILEFORMAT_MTL) - define_if("raylib" SUPPORT_FILEFORMAT_IQM) - define_if("raylib" SUPPORT_FILEFORMAT_GLTF) - define_if("raylib" SUPPORT_FILEFORMAT_VOX) - define_if("raylib" SUPPORT_FILEFORMAT_M3D) - define_if("raylib" SUPPORT_FILEFORMAT_WAV) - define_if("raylib" SUPPORT_FILEFORMAT_OGG) - define_if("raylib" SUPPORT_FILEFORMAT_XM) - define_if("raylib" SUPPORT_FILEFORMAT_MOD) - define_if("raylib" SUPPORT_FILEFORMAT_MP3) - define_if("raylib" SUPPORT_FILEFORMAT_QOA) - define_if("raylib" SUPPORT_FILEFORMAT_FLAC) - define_if("raylib" SUPPORT_STANDARD_FILEIO) - define_if("raylib" SUPPORT_TRACELOG) - if (UNIX AND NOT APPLE) - target_compile_definitions("raylib" PUBLIC "MAX_FILEPATH_LENGTH=4096") - else () - target_compile_definitions("raylib" PUBLIC "MAX_FILEPATH_LENGTH=512") - endif () - - target_compile_definitions("raylib" PUBLIC "MAX_GAMEPADS=4") - target_compile_definitions("raylib" PUBLIC "MAX_GAMEPAD_AXIS=8") - target_compile_definitions("raylib" PUBLIC "MAX_GAMEPAD_BUTTONS=32") - target_compile_definitions("raylib" PUBLIC "MAX_TOUCH_POINTS=10") - target_compile_definitions("raylib" PUBLIC "MAX_KEY_PRESSED_QUEUE=16") - - target_compile_definitions("raylib" PUBLIC "STORAGE_DATA_FILE=\"storage.data\"") - target_compile_definitions("raylib" PUBLIC "MAX_CHAR_PRESSED_QUEUE=16") - target_compile_definitions("raylib" PUBLIC "MAX_DECOMPRESSION_SIZE=64") - - if (${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_33" OR ${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_11") - target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_BUFFER_ELEMENTS=8192") - elseif (${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES2") - target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_BUFFER_ELEMENTS=2048") - endif () - - target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_DRAWCALLS=256") - target_compile_definitions("raylib" PUBLIC "MAX_MATRIX_STACK_SIZE=32") - target_compile_definitions("raylib" PUBLIC "MAX_SHADER_LOCATIONS=32") - target_compile_definitions("raylib" PUBLIC "MAX_MATERIAL_MAPS=12") - target_compile_definitions("raylib" PUBLIC "RL_CULL_DISTANCE_NEAR=0.01") - target_compile_definitions("raylib" PUBLIC "RL_CULL_DISTANCE_FAR=1000.0") - - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION=0") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD=1") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL=2") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR=3") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT=4") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2=5") - - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION=\"vertexPosition\"") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD=\"vertexTexCoord\"") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL=\"vertexNormal\"") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR=\"vertexColor\"") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT=\"vertexTangent\"") - target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2=\"vertexTexCoord2\"") - - target_compile_definitions("raylib" PUBLIC "MAX_TEXT_BUFFER_LENGTH=1024") - target_compile_definitions("raylib" PUBLIC "MAX_TEXT_UNICODE_CHARS=512") - target_compile_definitions("raylib" PUBLIC "MAX_TEXTSPLIT_COUNT=128") - - target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_FORMAT=ma_format_f32") - target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_CHANNELS=2") - target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_SAMPLE_RATE=44100") - target_compile_definitions("raylib" PUBLIC "DEFAULT_AUDIO_BUFFER_SIZE=4096") - - target_compile_definitions("raylib" PUBLIC "MAX_TRACELOG_MSG_LENGTH=128") - target_compile_definitions("raylib" PUBLIC "MAX_UWP_MESSAGES=512") -endif () + foreach(FLAG IN LISTS CONFIG_HEADER_FLAGS) + string(REGEX MATCH "([^=]+)=(.+)" _ ${FLAG}) + define_if("raylib" ${CMAKE_MATCH_1}) + endforeach() + foreach(VALUE IN LISTS CONFIG_HEADER_VALUES) + target_compile_definitions("raylib" PRIVATE ${VALUE}) + endforeach() +endif() diff --git a/cmake/LibraryConfigurations.cmake b/cmake/LibraryConfigurations.cmake index 23a7ec2f0479..6d2250c715be 100644 --- a/cmake/LibraryConfigurations.cmake +++ b/cmake/LibraryConfigurations.cmake @@ -58,8 +58,9 @@ if (${PLATFORM} MATCHES "Desktop") elseif (${PLATFORM} MATCHES "Web") set(PLATFORM_CPP "PLATFORM_WEB") - set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 --profiling") + if(NOT GRAPHICS) + set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") + endif() set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") elseif (${PLATFORM} MATCHES "Android") diff --git a/cmake/ParseConfigHeader.cmake b/cmake/ParseConfigHeader.cmake new file mode 100644 index 000000000000..797eea3cd69d --- /dev/null +++ b/cmake/ParseConfigHeader.cmake @@ -0,0 +1,17 @@ +file(READ "${CMAKE_CURRENT_SOURCE_DIR}/src/config.h" CONFIG_HEADER_CONTENT) + +set(BLANK_OR_BACKSLASH_PATTERN "[ \t\r\n\\]") +set(VALID_IDENTIFIER_PATTERN "[A-Za-z_]+[A-Za-z_0-9]*") +set(VALID_VALUE_PATTERN [=["?[A-Za-z_0-9.-]+"?]=]) # not really correct but does the job since the config.h file hopefully will have been checked by a C preprocessor. +set(MACRO_REGEX "(//${BLANK_OR_BACKSLASH_PATTERN}*)?\#define${BLANK_OR_BACKSLASH_PATTERN}+(${VALID_IDENTIFIER_PATTERN})${BLANK_OR_BACKSLASH_PATTERN}+(${VALID_VALUE_PATTERN})") + +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]]) + +set(CONFIG_HEADER_VALUES ${MACRO_LIST}) +list(FILTER CONFIG_HEADER_VALUES EXCLUDE REGEX "(^.+SUPPORT_)|(^//)") +list(TRANSFORM CONFIG_HEADER_VALUES REPLACE ${MACRO_REGEX} [[\2=\3]]) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9223236741c8..64b6d76040e8 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -96,10 +96,9 @@ if (${PLATFORM} MATCHES "Android") list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c) elseif (${PLATFORM} MATCHES "Web") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os") # Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1 -s ASYNCIFY -s ALLOW_MEMORY_GROWTH=1 --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html") set(CMAKE_EXECUTABLE_SUFFIX ".html") list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c) @@ -113,6 +112,13 @@ elseif ("${PLATFORM}" STREQUAL "DRM") list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c) +elseif (NOT SUPPORT_GESTURES_SYSTEM) + # Items requiring gestures system + list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_mouse_painting.c) + list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_basic_screen_manager.c) + list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_input_gestures_web.c) + list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_input_gestures.c) + endif () # The rlgl_standalone example only targets desktop, without shared libraries. diff --git a/examples/README.md b/examples/README.md index 94f5369db7cc..d790f7d84b4a 100644 --- a/examples/README.md +++ b/examples/README.md @@ -202,5 +202,5 @@ Examples showing raylib misc functionality that does not fit in other categories | 125 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | raylib_opengl_interop | â­ï¸â­ï¸â­ï¸â­ï¸ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) | | 126 | [embedded_files_loading](others/embedded_files_loading.c) | embedded_files_loading | â­ï¸â­ï¸â˜†â˜† | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) | -As always contributions are welcome, feel free to send new examples! Here it is an [examples template](examples_template.c) to start with! +As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with! diff --git a/examples/audio/audio_mixed_processor.c b/examples/audio/audio_mixed_processor.c index 3a008f3e22cd..fd970dd19b0a 100644 --- a/examples/audio/audio_mixed_processor.c +++ b/examples/audio/audio_mixed_processor.c @@ -97,7 +97,7 @@ int main(void) DrawRectangle(199, 199, 402, 34, LIGHTGRAY); for (int i = 0; i < 400; i++) { - DrawLine(201 + i, 232 - averageVolume[i] * 32, 201 + i, 232, MAROON); + DrawLine(201 + i, 232 - (int)averageVolume[i] * 32, 201 + i, 232, MAROON); } DrawRectangleLines(199, 199, 402, 34, GRAY); diff --git a/examples/build.zig b/examples/build.zig index 5a17382caca1..df0cdf8c17f0 100644 --- a/examples/build.zig +++ b/examples/build.zig @@ -75,6 +75,7 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.Reso const install_cmd = b.addInstallArtifact(exe, .{}); const run_cmd = b.addRunArtifact(exe); + run_cmd.cwd = b.path(module); run_cmd.step.dependOn(&install_cmd.step); const run_step = b.step(name, name); diff --git a/examples/core/core_2d_camera_platformer.c b/examples/core/core_2d_camera_platformer.c index 75fd6cf6ad94..3743de80b0ef 100644 --- a/examples/core/core_2d_camera_platformer.c +++ b/examples/core/core_2d_camera_platformer.c @@ -133,10 +133,10 @@ int main(void) for (int i = 0; i < envItemsLength; i++) DrawRectangleRec(envItems[i].rect, envItems[i].color); - Rectangle playerRect = { player.position.x - 20, player.position.y - 40, 40, 40 }; + Rectangle playerRect = { player.position.x - 20, player.position.y - 40, 40.0f, 40.0f }; DrawRectangleRec(playerRect, RED); - DrawCircle(player.position.x, player.position.y, 5, GOLD); + DrawCircleV(player.position, 5.0f, GOLD); EndMode2D(); diff --git a/examples/core/core_custom_frame_control.c b/examples/core/core_custom_frame_control.c index 6e494d86ec03..9793fc359256 100644 --- a/examples/core/core_custom_frame_control.c +++ b/examples/core/core_custom_frame_control.c @@ -2,7 +2,7 @@ * * raylib [core] example - custom frame control * -* NOTE: WARNING: This is an example for advance users willing to have full control over +* NOTE: WARNING: This is an example for advanced users willing to have full control over * the frame processes. By default, EndDrawing() calls the following processes: * 1. Draw remaining batch data: rlDrawRenderBatchActive() * 2. SwapScreenBuffer() diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c index 843d5d90bc8b..656f7c244f83 100644 --- a/examples/core/core_input_gamepad.c +++ b/examples/core/core_input_gamepad.c @@ -22,7 +22,7 @@ // NOTE: Gamepad name ID depends on drivers and OS #define XBOX360_LEGACY_NAME_ID "Xbox Controller" #define XBOX360_NAME_ID "Xbox 360 Controller" -#define PS3_NAME_ID "PLAYSTATION(R)3 Controller" +#define PS3_NAME_ID "Sony PLAYSTATION(R)3 Controller" //------------------------------------------------------------------------------------ // Program main entry point @@ -67,7 +67,7 @@ int main(void) { DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK); - if (true) + if (TextIsEqual(GetGamepadName(gamepad), XBOX360_LEGACY_NAME_ID) || TextIsEqual(GetGamepadName(gamepad), XBOX360_NAME_ID)) { DrawTexture(texXboxPad, 0, 0, DARKGRAY); diff --git a/examples/core/core_input_mouse_wheel.c b/examples/core/core_input_mouse_wheel.c index 54f33545ef6a..d261e9348796 100644 --- a/examples/core/core_input_mouse_wheel.c +++ b/examples/core/core_input_mouse_wheel.c @@ -36,7 +36,7 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - boxPositionY -= (GetMouseWheelMove()*scrollSpeed); + boxPositionY -= (int)(GetMouseWheelMove()*scrollSpeed); //---------------------------------------------------------------------------------- // Draw diff --git a/examples/core/core_random_sequence.c b/examples/core/core_random_sequence.c index c946b64dad80..2f7c3be95832 100644 --- a/examples/core/core_random_sequence.c +++ b/examples/core/core_random_sequence.c @@ -41,7 +41,7 @@ int main(void) { int rectCount = 20; float rectSize = (float)screenWidth/rectCount; - ColorRect* rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight); + ColorRect* rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight); SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -62,7 +62,7 @@ int main(void) { rectCount++; rectSize = (float)screenWidth/rectCount; free(rectangles); - rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight); + rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight); } if(IsKeyPressed(KEY_DOWN)) @@ -71,7 +71,7 @@ int main(void) { rectCount--; rectSize = (float)screenWidth/rectCount; free(rectangles); - rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight); + rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight); } } @@ -121,17 +121,17 @@ static Color GenerateRandomColor() } static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight){ - int *seq = LoadRandomSequence(rectCount, 0, rectCount-1); - ColorRect* rectangles = (ColorRect *)malloc(rectCount*sizeof(ColorRect)); + int *seq = LoadRandomSequence((unsigned int)rectCount, 0, (unsigned int)rectCount-1); + ColorRect* rectangles = (ColorRect *)malloc((int)rectCount*sizeof(ColorRect)); float rectSeqWidth = rectCount * rectWidth; - int startX = (screenWidth - rectSeqWidth) * 0.5f; + float startX = (screenWidth - rectSeqWidth) * 0.5f; for(int x=0;x - + @@ -1075,6 +1075,9 @@ + + + @@ -1314,7 +1317,7 @@ - + @@ -1490,12 +1493,12 @@ - + - + @@ -1522,31 +1525,31 @@ - + - + - + - + - + @@ -1652,7 +1655,7 @@ - + @@ -1668,6 +1671,12 @@ + + + + + + @@ -1833,9 +1842,9 @@ - + - + @@ -1957,6 +1966,13 @@ + + + + + + + @@ -2008,6 +2024,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2396,6 +2447,12 @@ + + + + + + @@ -2425,7 +2482,7 @@ - + diff --git a/parser/raylib_parser.c b/parser/raylib_parser.c index 3e36f41f184c..cfb0133c3d2e 100644 --- a/parser/raylib_parser.c +++ b/parser/raylib_parser.c @@ -202,9 +202,12 @@ int main(int argc, char* argv[]) { if (argc > 1) ProcessCommandLine(argc, argv); - if (inFileName[0] == '\0') MemoryCopy(inFileName, "../src/raylib.h\0", 16); - if (outFileName[0] == '\0') MemoryCopy(outFileName, "raylib_api.txt\0", 15); - if (apiDefine[0] == '\0') MemoryCopy(apiDefine, "RLAPI\0", 6); + 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); + if (outFileName[0] == '\0') MemoryCopy(outFileName, raylibapiPath, TextLength(raylibapiPath) + 1); + if (apiDefine[0] == '\0') MemoryCopy(apiDefine, rlapiPath, TextLength(rlapiPath) + 1); int length = 0; char *buffer = LoadFileText(inFileName, &length); @@ -1097,7 +1100,7 @@ static void ShowCommandLineInfo(void) printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n"); printf(" -f, --format : Define output format for parser data.\n"); printf(" Supported types: DEFAULT, JSON, XML, LUA, CODE\n\n"); - printf(" -d, --define : Define functions specifiers (i.e. RLAPI for raylib.h, RMDEF for raymath.h, etc.)\n"); + printf(" -d, --define : 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 : Define string to truncate input after (i.e. \"RLGL IMPLEMENTATION\" for rlgl.h)\n"); printf(" NOTE: If not specified, the full input file is parsed.\n\n"); @@ -1107,7 +1110,7 @@ static void ShowCommandLineInfo(void) printf(" Process to generate \n\n"); printf(" > raylib_parser --output raylib_data.info --format XML\n"); printf(" Process to generate as XML text data\n\n"); - printf(" > raylib_parser --input raymath.h --output raymath_data.info --format XML\n"); + printf(" > raylib_parser --input raymath.h --output raymath_data.info --format XML --define RMAPI\n"); printf(" Process to generate as XML text data\n\n"); } @@ -1277,8 +1280,10 @@ static void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type } else if ((typeName[k] == '.') && (typeNameLen == 3)) // Handle varargs ...); { - MemoryCopy(type, "...", 3); - MemoryCopy(name, "args", 4); + const char *varargsDots = "..."; + const char *varargsArg = "args"; + MemoryCopy(type, varargsDots, TextLength(varargsDots)); + MemoryCopy(name, varargsArg, TextLength(varargsArg)); break; } } diff --git a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml index 6c0552974e35..c869a1a189dd 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +++ b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml @@ -509,7 +509,7 @@ - + @@ -2822,7 +2822,7 @@ - + diff --git a/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h b/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h index 8776d434969f..0a3c2417dbd7 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +++ b/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h @@ -134,7 +134,7 @@ RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal me RLAPI void MemFree(void *ptr); // Internal memory free // Set custom callbacks -// WARNING: Callbacks setup is intended for advance users +// WARNING: Callbacks setup is intended for advanced users RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver diff --git a/projects/VS2022/examples/shapes_splines_drawing.vcxproj b/projects/VS2022/examples/shapes_splines_drawing.vcxproj index 77b17a803e8c..7be42c0b7073 100644 --- a/projects/VS2022/examples/shapes_splines_drawing.vcxproj +++ b/projects/VS2022/examples/shapes_splines_drawing.vcxproj @@ -202,7 +202,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -219,7 +219,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) @@ -237,7 +237,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -258,7 +258,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -281,7 +281,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -303,7 +303,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -325,7 +325,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -353,7 +353,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 387665705c3d..c1360ee299e3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -69,7 +69,10 @@ else() endif() if (${PLATFORM} MATCHES "Web") - target_link_options(raylib PRIVATE "-sUSE_GLFW=3") + target_link_options(raylib PUBLIC "-sUSE_GLFW=3") + if(${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES3") + target_link_options(raylib PUBLIC "-sFULL_ES3") + endif() endif() set_target_properties(raylib PROPERTIES diff --git a/src/Makefile b/src/Makefile index 23742565d2f9..19251b95692e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -316,7 +316,7 @@ endif # -D_GNU_SOURCE access to lots of nonstandard GNU/Linux extension functions # -Werror=pointer-arith catch unportable code that does direct arithmetic on void pointers # -fno-strict-aliasing jar_xm.h does shady stuff (breaks strict aliasing) -CFLAGS = -Wall -D_GNU_SOURCE -D$(PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing $(CUSTOM_CFLAGS) +CFLAGS = -Wall -D_GNU_SOURCE -D$(PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing ifneq ($(RAYLIB_CONFIG_FLAGS), NONE) CFLAGS += -DEXTERNAL_CONFIG_FLAGS $(RAYLIB_CONFIG_FLAGS) @@ -449,6 +449,8 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) endif endif +CFLAGS += $(CUSTOM_CFLAGS) + # Define include paths for required headers: INCLUDE_PATHS # NOTE: Several external required libraries (stb and others) #------------------------------------------------------------------------------------------------ diff --git a/src/build.zig b/src/build.zig index d172b3c2a789..81d4a766263d 100644 --- a/src/build.zig +++ b/src/build.zig @@ -22,6 +22,7 @@ pub fn addRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. .platform_drm = options.platform_drm, .shared = options.shared, .linux_display_backend = options.linux_display_backend, + .opengl_version = options.opengl_version, }); const raylib = raylib_dep.artifact("raylib"); @@ -201,16 +202,22 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. const cache_include = std.fs.path.join(b.allocator, &.{ b.sysroot.?, "cache", "sysroot", "include" }) catch @panic("Out of memory"); defer b.allocator.free(cache_include); - var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!"); - dir.close(); - - raylib.addIncludePath(b.path(cache_include)); + if (comptime builtin.zig_version.minor > 12) { + var dir = std.fs.cwd().openDir(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!"); + dir.close(); + raylib.addIncludePath(b.path(cache_include)); + } else { + var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!"); + dir.close(); + raylib.addIncludePath(.{ .path = cache_include }); + } }, else => { @panic("Unsupported OS"); }, } + raylib.addIncludePath(b.path("src")); raylib.root_module.addCSourceFiles(.{ .root = b.path("src"), .files = c_source_files.items, diff --git a/src/config.h b/src/config.h index 3c92de72d5a0..c54583e74fbb 100644 --- a/src/config.h +++ b/src/config.h @@ -66,7 +66,7 @@ #define SUPPORT_COMPRESSION_API 1 // Support automatic generated events, loading and recording of those events when required #define SUPPORT_AUTOMATION_EVENTS 1 -// Support custom frame control, only for advance users +// Support custom frame control, only for advanced users // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // Enabling this flag allows manual control of the frame processes, use at your own risk //#define SUPPORT_CUSTOM_FRAME_CONTROL 1 diff --git a/src/external/RGFW.h b/src/external/RGFW.h index 67c67e91c9f2..a0ca21cec639 100644 --- a/src/external/RGFW.h +++ b/src/external/RGFW.h @@ -34,7 +34,9 @@ #define RGFW_BUFFER - (optional) just draw directly to (RGFW) window pixel buffer that is drawn to screen (the buffer is in the RGBA format) #define RGFW_EGL - (optional) use EGL for loading an OpenGL context (instead of the system's opengl api) #define RGFW_OPENGL_ES1 - (optional) use EGL to load and use Opengl ES (version 1) for backend rendering (instead of the system's opengl api) + This version doesn't work for desktops (I'm pretty sure) #define RGFW_OPENGL_ES2 - (optional) use OpenGL ES (version 2) + #define RGFW_OPENGL_ES3 - (optional) use OpenGL ES (version 3) #define RGFW_VULKAN - (optional) use vulkan for the rendering backend (rather than opengl) #define RGFW_DIRECTX - (optional) use directX for the rendering backend (rather than opengl) (windows only, defaults to opengl for unix) #define RGFW_NO_API - (optional) don't use any rendering API (no opengl, no vulkan, no directX) @@ -90,12 +92,16 @@ #ifndef RGFWDEF #ifdef __APPLE__ -#define RGFWDEF extern inline +#define RGFWDEF static inline #else #define RGFWDEF inline #endif #endif +#ifndef RGFW_UNUSED +#define RGFW_UNUSED(x) if (x){} +#endif + #ifdef __cplusplus extern "C" { #endif @@ -106,7 +112,7 @@ extern "C" { #define RGFW_HEADER #if !defined(u8) -#include + #include typedef uint8_t u8; typedef int8_t i8; @@ -130,12 +136,16 @@ extern "C" { #define RGFW_WINDOWS -#if defined(_WIN32) +#if defined(_WIN32) && !defined(WIN32) #define WIN32 #endif #if defined(_WIN64) + +#ifndef WIN64 #define WIN64 +#endif + #define _AMD64_ #undef _X86_ #else @@ -163,7 +173,7 @@ extern "C" { #define RGFW_MACOS #endif -#if (defined(RGFW_OPENGL_ES1) || defined(RGFW_OPENGL_ES2)) && !defined(RGFW_EGL) +#if (defined(RGFW_OPENGL_ES1) || defined(RGFW_OPENGL_ES2) || defined(RGFW_OPENGL_ES3)) && !defined(RGFW_EGL) #define RGFW_EGL #endif #if defined(RGFW_EGL) && defined(__APPLE__) @@ -193,7 +203,7 @@ extern "C" { #include #endif -#if defined(RGFW_X11) && defined(RGFW_OPENGL) +#if defined(RGFW_X11) && (defined(RGFW_OPENGL)) #ifndef GLX_MESA_swap_control #define GLX_MESA_swap_control #endif @@ -384,10 +394,10 @@ typedef struct { i32 x, y; } RGFW_vector; RGFW_vector point; /*!< mouse x, y of event (or drop point) */ u32 keyCode; /*!< keycode of event !!Keycodes defined at the bottom of the header file!! */ - u32 inFocus; /*if the window is in focus or not*/ - u32 fps; /*the current fps of the window [the fps is checked when events are checked]*/ - u32 current_ticks, frames; /* this is used for counting the fps */ + u64 frameTime, frameTime2; /* this is used for counting the fps */ + + u8 inFocus; /*if the window is in focus or not*/ u8 lockState; @@ -416,9 +426,10 @@ typedef struct { i32 x, y; } RGFW_vector; u32 display; void* displayLink; void* window; + u8 dndPassed; #endif -#if defined(RGFW_OPENGL) && !defined(RGFW_OSMESA) +#if (defined(RGFW_OPENGL)) && !defined(RGFW_OSMESA) #ifdef RGFW_MACOS void* rSurf; /*!< source graphics context */ #endif @@ -460,6 +471,7 @@ typedef struct { i32 x, y; } RGFW_vector; #ifdef RGFW_EGL EGLSurface EGL_surface; EGLDisplay EGL_display; + EGLContext EGL_context; #endif #if defined(RGFW_OSMESA) || defined(RGFW_BUFFER) @@ -508,7 +520,7 @@ typedef struct { i32 x, y; } RGFW_vector; RGFW_rect r; /* the x, y, w and h of the struct */ - u8 fpsCap; /*!< the fps cap of the window should run at (change this var to change the fps cap, 0 = no limit)*/ + u32 fpsCap; /*!< the fps cap of the window should run at (change this var to change the fps cap, 0 = no limit)*/ /*[the fps is capped when events are checked]*/ } RGFW_window; /*!< Window structure for managing the window */ @@ -627,7 +639,6 @@ typedef struct { i32 x, y; } RGFW_vector; this is run by default if the user uses the arg `RGFW_SCALE_TO_MONITOR` during window creation */ RGFWDEF void RGFW_window_scaleToMonitor(RGFW_window* win); - /* get the struct of the window's monitor */ RGFWDEF RGFW_monitor RGFW_window_getMonitor(RGFW_window* win); @@ -635,11 +646,16 @@ typedef struct { i32 x, y; } RGFW_vector; RGFWDEF void RGFW_window_makeCurrent(RGFW_window* win); /*error handling*/ - RGFWDEF u8 RGFW_Error(); /* returns true if an error has occurred (doesn't print errors itself) */ + RGFWDEF u8 RGFW_Error(void); /* returns true if an error has occurred (doesn't print errors itself) */ /*!< if window == NULL, it checks if the key is pressed globally. Otherwise, it checks only if the key is pressed while the window in focus.*/ RGFWDEF u8 RGFW_isPressedI(RGFW_window* win, u32 key); /*!< if key is pressed (key code)*/ + RGFWDEF u8 RGFW_wasPressedI(RGFW_window* win, u32 key); /*!< if key was pressed (checks prev keymap only) (key code)*/ + + RGFWDEF u8 RGFW_isHeldI(RGFW_window* win, u32 key); /*!< if key is held (key code)*/ + RGFWDEF u8 RGFW_isReleasedI(RGFW_window* win, u32 key); /*!< if key is released (key code)*/ + /* !!Keycodes defined at the bottom of the header file!! */ @@ -676,7 +692,14 @@ typedef struct { i32 x, y; } RGFW_vector; if you're going to use sili which is a good idea generally */ - RGFWDEF RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args); /*!< create a thread*/ + + #if defined(__unix__) || defined(__APPLE__) + typedef void* (* RGFW_threadFunc_ptr)(void*); + #else + typedef DWORD (* RGFW_threadFunc_ptr)(void*); + #endif + + RGFWDEF RGFW_thread RGFW_createThread(RGFW_threadFunc_ptr ptr, void* args); /*!< create a thread*/ RGFWDEF void RGFW_cancelThread(RGFW_thread thread); /*!< cancels a thread*/ RGFWDEF void RGFW_joinThread(RGFW_thread thread); /*!< join thread to current thread */ RGFWDEF void RGFW_setThreadPriority(RGFW_thread thread, u8 priority); /*!< sets the priority priority */ @@ -694,7 +717,7 @@ typedef struct { i32 x, y; } RGFW_vector; /*! native opengl functions */ #ifdef RGFW_OPENGL /*! Get max OpenGL version */ - RGFWDEF u8* RGFW_getMaxGLVersion(); + RGFWDEF u8* RGFW_getMaxGLVersion(void); /* OpenGL init hints */ RGFWDEF void RGFW_setGLStencil(i32 stencil); /* set stencil buffer bit size (8 by default) */ RGFWDEF void RGFW_setGLSamples(i32 samples); /* set number of sampiling buffers (4 by default) */ @@ -754,8 +777,8 @@ typedef struct { i32 x, y; } RGFW_vector; RGFWDEF void RGFW_createSurface(VkInstance instance, RGFW_window* win); int RGFW_deviceInitialization(RGFW_window* win); int RGFW_createSwapchain(RGFW_window* win); - RGFWDEF int RGFW_createRenderPass(); - int RGFW_createCommandPool(); + RGFWDEF int RGFW_createRenderPass(void); + int RGFW_createCommandPool(void); int RGFW_createCommandBuffers(RGFW_window* win); int RGFW_createSyncObjects(RGFW_window* win); RGFWDEF int RGFW_createFramebuffers(RGFW_window* win); @@ -780,8 +803,7 @@ typedef struct { i32 x, y; } RGFW_vector; RGFWDEF void RGFW_window_checkFPS(RGFW_window* win); /*!< updates fps / sets fps to cap (ran by RGFW_window_checkEvent)*/ RGFWDEF u64 RGFW_getTime(void); /* get time in seconds */ RGFWDEF u64 RGFW_getTimeNS(void); /* get time in nanoseconds */ - RGFWDEF u32 RGFW_getFPS(void); /* get current FPS (win->event.fps) */ - RGFWDEF void RGFW_sleep(u32 microsecond); /* sleep for a set time */ + RGFWDEF void RGFW_sleep(u64 microsecond); /* sleep for a set time */ #endif /* RGFW_HEADER */ /* @@ -859,20 +881,19 @@ typedef struct { i32 x, y; } RGFW_vector; #ifdef RGFW_WINDOWS -#define WIN32_LEAN_AND_MEAN - #include #endif #ifdef RGFW_MACOS -#include - /* based on silicon.h */ +#ifndef GL_SILENCE_DEPRECATION #define GL_SILENCE_DEPRECATION +#endif + #include #include #include @@ -914,7 +935,7 @@ typedef struct { i32 x, y; } RGFW_vector; #define abi_objc_msgSend_fpret objc_msgSend_fpret #endif -#define NSAlloc(nsclass) objc_msgSend_id(nsclass, sel_registerName("alloc")) +#define NSAlloc(nsclass) objc_msgSend_id((id)nsclass, sel_registerName("alloc")) #define objc_msgSend_bool ((BOOL (*)(id, SEL))objc_msgSend) #define objc_msgSend_void ((void (*)(id, SEL))objc_msgSend) #define objc_msgSend_void_id ((void (*)(id, SEL, id))objc_msgSend) @@ -948,7 +969,7 @@ typedef struct { i32 x, y; } RGFW_vector; loadFunc("stringWithUTF8String:"); return ((id(*)(id, SEL, const char*))objc_msgSend) - (objc_getClass("NSString"), func, str); + ((id)objc_getClass("NSString"), func, str); } const char* NSString_to_char(NSString* str) { @@ -1053,7 +1074,7 @@ typedef struct { i32 x, y; } RGFW_vector; void* func = sel_registerName("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:"); return (NSBitmapImageRep*) ((id(*)(id, SEL, unsigned char**, NSInteger, NSInteger, NSInteger, NSInteger, bool, bool, const char*, NSBitmapFormat, NSInteger, NSInteger))objc_msgSend) - (NSAlloc(objc_getClass("NSBitmapImageRep")), func, planes, width, height, bps, spp, alpha, isPlanar, NSString_stringWithUTF8String(colorSpaceName), bitmapFormat, rowBytes, pixelBits); + (NSAlloc((id)objc_getClass("NSBitmapImageRep")), func, planes, width, height, bps, spp, alpha, isPlanar, NSString_stringWithUTF8String(colorSpaceName), bitmapFormat, rowBytes, pixelBits); } NSColor* NSColor_colorWithSRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) { @@ -1079,7 +1100,7 @@ typedef struct { i32 x, y; } RGFW_vector; NSImage* NSImage_initWithSize(NSSize size) { void* func = sel_registerName("initWithSize:"); return ((id(*)(id, SEL, NSSize))objc_msgSend) - (NSAlloc(objc_getClass("NSImage")), func, size); + (NSAlloc((id)objc_getClass("NSImage")), func, size); } #define NS_OPENGL_ENUM_DEPRECATED(minVers, maxVers) API_AVAILABLE(macos(minVers)) typedef NS_ENUM(NSInteger, NSOpenGLContextParameter) { @@ -1111,13 +1132,13 @@ typedef struct { i32 x, y; } RGFW_vector; void* NSOpenGLPixelFormat_initWithAttributes(const uint32_t* attribs) { void* func = sel_registerName("initWithAttributes:"); return (void*) ((id(*)(id, SEL, const uint32_t*))objc_msgSend) - (NSAlloc(objc_getClass("NSOpenGLPixelFormat")), func, attribs); + (NSAlloc((id)objc_getClass("NSOpenGLPixelFormat")), func, attribs); } NSOpenGLView* NSOpenGLView_initWithFrame(NSRect frameRect, uint32_t* format) { void* func = sel_registerName("initWithFrame:pixelFormat:"); return (NSOpenGLView*) ((id(*)(id, SEL, NSRect, uint32_t*))objc_msgSend) - (NSAlloc(objc_getClass("NSOpenGLView")), func, frameRect, format); + (NSAlloc((id)objc_getClass("NSOpenGLView")), func, frameRect, format); } void NSCursor_performSelector(NSCursor* cursor, void* selector) { @@ -1126,7 +1147,7 @@ typedef struct { i32 x, y; } RGFW_vector; } NSPasteboard* NSPasteboard_generalPasteboard(void) { - return (NSPasteboard*) objc_msgSend_id(objc_getClass("NSPasteboard"), sel_registerName("generalPasteboard")); + return (NSPasteboard*) objc_msgSend_id((id)objc_getClass("NSPasteboard"), sel_registerName("generalPasteboard")); } NSString** cstrToNSStringArray(char** strs, size_t len) { @@ -1144,27 +1165,22 @@ typedef struct { i32 x, y; } RGFW_vector; } NSArray* c_array_to_NSArray(void* array, size_t len) { - void* func = sel_registerName("initWithObjects:count:"); + SEL func = sel_registerName("initWithObjects:count:"); void* nsclass = objc_getClass("NSArray"); - - return ((id(*)(id, SEL, void*, NSUInteger))objc_msgSend) - (NSAlloc(nsclass), func, array, len); + return ((id (*)(id, SEL, void*, NSUInteger))objc_msgSend) + (NSAlloc(nsclass), func, array, len); } - + void NSregisterForDraggedTypes(void* view, NSPasteboardType* newTypes, size_t len) { - NSString** ntypes = cstrToNSStringArray(newTypes, len); - - void* func = sel_registerName("registerForDraggedTypes:"); + NSString** ntypes = cstrToNSStringArray((char**)newTypes, len); NSArray* array = c_array_to_NSArray(ntypes, len); - objc_msgSend_void_id(view, sel_registerName("registerForDraggedTypes:"), array); - NSRelease(array); } NSInteger NSPasteBoard_declareTypes(NSPasteboard* pasteboard, NSPasteboardType* newTypes, size_t len, void* owner) { - NSString** ntypes = cstrToNSStringArray(newTypes, len); + NSString** ntypes = cstrToNSStringArray((char**)newTypes, len); void* func = sel_registerName("declareTypes:owner:"); @@ -1252,13 +1268,17 @@ typedef struct { i32 x, y; } RGFW_vector; (pasteboard, func, array, options); NSRelease(array); - NSUInteger count = NSArray_count(output); const char** res = si_array_init_reserve(sizeof(const char*), count); - for (NSUInteger i = 0; i < count; i++) - res[i] = NSString_to_char(NSArray_objectAtIndex(output, i)); + void* path_func = sel_registerName("path"); + + for (NSUInteger i = 0; i < count; i++) { + void* url = NSArray_objectAtIndex(output, i); + NSString* url_str = ((id(*)(id, SEL))objc_msgSend)(url, path_func); + res[i] = NSString_to_char(url_str); + } return res; } @@ -1301,12 +1321,20 @@ typedef struct { i32 x, y; } RGFW_vector; } #endif + #ifdef RGFW_WINDOWS + __declspec(dllimport) u32 __stdcall timeBeginPeriod(u32 uPeriod); + #endif + RGFWDEF RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args); RGFWDEF void RGFW_init_buffer(RGFW_window* win); RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) { RGFW_window* win = (RGFW_window*) RGFW_MALLOC(sizeof(RGFW_window)); /* make a new RGFW struct */ + #ifdef RGFW_WINDOWS + timeBeginPeriod(1); + #endif + #ifdef RGFW_ALLOC_DROPFILES win->event.droppedFiles = (char**) RGFW_MALLOC(sizeof(char*) * RGFW_MAX_DROPS); u32 i; @@ -1406,6 +1434,8 @@ typedef struct { i32 x, y; } RGFW_vector; win->src.hdcMem = CreateCompatibleDC(win->src.hdc); #endif +#else +RGFW_UNUSED(win); /* if buffer rendering is not being used */ #endif } @@ -1827,9 +1857,18 @@ typedef struct { i32 x, y; } RGFW_vector; #endif #if defined(RGFW_MACOS) - u8 RGFW_keyMap[128] = { 0 }; + u8 RGFW_keyBoard[128] = { 0 }; + u8 RGFW_keyBoard_prev[128]; #endif + u8 RGFW_isHeldI(RGFW_window* win, u32 key) { + return (RGFW_isPressedI(win, key) && RGFW_wasPressedI(win, key)); + } + + u8 RGFW_isReleasedI(RGFW_window* win, u32 key) { + return (!RGFW_isPressedI(win, key) && RGFW_wasPressedI(win, key)); + } + char* RGFW_keyCodeTokeyStr(u64 key) { #if defined(RGFW_MACOS) static char* keyStrs[128] = { "a", "s", "d", "f", "h", "g", "z", "x", "c", "v", "0", "b", "q", "w", "e", "r", "y", "t", "1", "2", "3", "4", "6", "5", "Equals", "9", "7", "Minus", "8", "0", "CloseBracket", "o", "u", "Bracket", "i", "p", "Return", "l", "j", "Apostrophe", "k", "Semicolon", "BackSlash", "Comma", "Slash", "n", "m", "Period", "Tab", "Space", "Backtick", "BackSpace", "0", "Escape", "0", "Super", "Shift", "CapsLock", "Alt", "Control", "0", "0", "0", "0", "0", "KP_Period", "0", "KP_Minus", "0", "0", "0", "0", "Numlock", "0", "0", "0", "KP_Multiply", "KP_Return", "0", "0", "0", "0", "KP_Slash", "KP_0", "KP_1", "KP_2", "KP_3", "KP_4", "KP_5", "KP_6", "KP_7", "0", "KP_8", "KP_9", "0", "0", "0", "F5", "F6", "F7", "F3", "F8", "F9", "0", "F11", "0", "F13", "0", "F14", "0", "F10", "0", "F12", "0", "F15", "Insert", "Home", "PageUp", "Delete", "F4", "End", "F2", "PageDown", "Left", "Right", "Down", "Up", "F1" }; @@ -1998,12 +2037,14 @@ typedef struct { i32 x, y; } RGFW_vector; u32 RGFW_isPressedJS(RGFW_window* win, u16 c, u8 button) { return win->src.jsPressed[c][button]; } #else - typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*); + typedef u64 (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*); PFN_XInputGetState XInputGetStateSRC = NULL; #define XInputGetState XInputGetStateSRC static HMODULE RGFW_XInput_dll = NULL; u32 RGFW_isPressedJS(RGFW_window* win, u16 c, u8 button) { + RGFW_UNUSED(win) + XINPUT_STATE state; if (XInputGetState == NULL || XInputGetState(c, &state) == ERROR_DEVICE_NOT_CONNECTED) return 0; @@ -2027,9 +2068,15 @@ typedef struct { i32 x, y; } RGFW_vector; } #endif -#ifdef RGFW_OPENGL +#if defined(RGFW_OPENGL) || defined(RGFW_EGL) i32 RGFW_majorVersion = 0, RGFW_minorVersion = 0; + + #ifndef RGFW_EGL i32 RGFW_STENCIL = 8, RGFW_SAMPLES = 4, RGFW_STEREO = GL_FALSE, RGFW_AUX_BUFFERS = 0; + #else + i32 RGFW_STENCIL = 0, RGFW_SAMPLES = 0, RGFW_STEREO = GL_FALSE, RGFW_AUX_BUFFERS = 0; + #endif + void RGFW_setGLStencil(i32 stencil) { RGFW_STENCIL = stencil; } void RGFW_setGLSamples(i32 samples) { RGFW_SAMPLES = samples; } @@ -2041,7 +2088,7 @@ typedef struct { i32 x, y; } RGFW_vector; RGFW_minorVersion = minor; } - u8* RGFW_getMaxGLVersion() { + u8* RGFW_getMaxGLVersion(void) { RGFW_window* dummy = RGFW_createWindow("dummy", RGFW_RECT(0, 0, 1, 1), 0); const char* versionStr = (const char*) glGetString(GL_VERSION); @@ -2055,6 +2102,8 @@ typedef struct { i32 x, y; } RGFW_vector; return version; } +#ifndef RGFW_EGL + #define RGFW_GL_RENDER_TYPE RGFW_OS_BASED_VALUE(GLX_X_VISUAL_TYPE, 0x2003, 73) #define RGFW_GL_ALPHA_SIZE RGFW_OS_BASED_VALUE(GLX_ALPHA_SIZE, 0x201b, 11) #define RGFW_GL_DEPTH_SIZE RGFW_OS_BASED_VALUE(GLX_DEPTH_SIZE, 0x2022, 12) @@ -2087,6 +2136,7 @@ typedef struct { i32 x, y; } RGFW_vector; #endif static u32* RGFW_initAttribs(u32 useSoftware) { + RGFW_UNUSED(useSoftware); static u32 attribs[] = { #ifndef RGFW_MACOS RGFW_GL_RENDER_TYPE, @@ -2165,9 +2215,9 @@ typedef struct { i32 x, y; } RGFW_vector; return attribs; } -#endif +#else -#ifdef RGFW_EGL +#include #if defined(RGFW_LINK_EGL) typedef EGLBoolean(EGLAPIENTRY* PFN_eglInitialize)(EGLDisplay, EGLint*, EGLint*); @@ -2202,8 +2252,8 @@ typedef struct { i32 x, y; } RGFW_vector; #endif -#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 -#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb +#define EGL_SURFACE_MAJOR_VERSION_KHR 0x3098 +#define EGL_SURFACE_MINOR_VERSION_KHR 0x30fb #ifndef RGFW_GL_ADD_ATTRIB #define RGFW_GL_ADD_ATTRIB(attrib, attVal) \ @@ -2214,9 +2264,8 @@ typedef struct { i32 x, y; } RGFW_vector; } #endif - void RGFW_createOpenGLContext(RGFW_window* win) { - static EGLContext globalCtx = EGL_NO_CONTEXT; + void RGFW_createOpenGLContext(RGFW_window* win) { #if defined(RGFW_LINK_EGL) eglInitializeSource = (PFNEGLINITIALIZEPROC) eglGetProcAddress("eglInitialize"); eglGetConfigsSource = (PFNEGLGETCONFIGSPROC) eglGetProcAddress("eglGetConfigs"); @@ -2233,69 +2282,101 @@ typedef struct { i32 x, y; } RGFW_vector; eglDestroySurfaceSource = (PFNEGLDESTROYSURFACEPROC) eglGetProcAddress("eglDestroySurface"); #endif /* RGFW_LINK_EGL */ + #ifdef RGFW_WINDOWS + win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.hdc); + #else win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.display); + #endif EGLint major, minor; eglInitialize(win->src.EGL_display, &major, &minor); - EGLint config_attribs[] = { + #ifndef EGL_OPENGL_ES1_BIT + #define EGL_OPENGL_ES1_BIT 0x1 + #endif + + EGLint egl_config[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, #ifdef RGFW_OPENGL_ES1 EGL_OPENGL_ES1_BIT, - #endif - #ifdef RGFW_OPENGL_ES2 + #elif defined(RGFW_OPENGL_ES3) + EGL_OPENGL_ES3_BIT, + #elif defined(RGFW_OPENGL_ES2) EGL_OPENGL_ES2_BIT, #else EGL_OPENGL_BIT, #endif - EGL_NONE + EGL_NONE, EGL_NONE }; EGLConfig config; - EGLint num_configs; - eglChooseConfig(win->src.EGL_display, config_attribs, &config, 1, &num_configs); + EGLint numConfigs; + eglChooseConfig(win->src.EGL_display, egl_config, &config, 1, &numConfigs); -#if defined(RGFW_OPENGL_ES2) || defined(RGFW_OPENGL_ES1) - eglBindAPI(EGL_OPENGL_ES_API); -#else - eglBindAPI(EGL_OPENGL_API); -#endif - EGLint attribs[]{ - EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT, - 0, 0, 0, 0 + win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL); + + EGLint attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, + #ifdef RGFW_OPENGL_ES1 + 1, + #else + 2, + #endif + EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE }; - size_t index = 2; + size_t index = 4; RGFW_GL_ADD_ATTRIB(EGL_STENCIL_SIZE, RGFW_STENCIL); RGFW_GL_ADD_ATTRIB(EGL_SAMPLES, RGFW_SAMPLES); - RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MAJOR_VERSION, RGFW_majorVersion); - RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MINOR_VERSION, RGFW_minorVersion); - win->src.rSurf = eglCreateContext(win->src.EGL_display, config, globalCtx, attribs); - win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL); + if (RGFW_majorVersion) { + attribs[1] = RGFW_majorVersion; + RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT); + RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MAJOR_VERSION, RGFW_majorVersion); + RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MINOR_VERSION, RGFW_minorVersion); + } - if (globalCtx == EGL_NO_CONTEXT) - RGFW_EGLglobalContext = win->src.rSurf; + #if defined(RGFW_OPENGL_ES1) || defined(RGFW_OPENGL_ES2) || defined(RGFW_OPENGL_ES3) + eglBindAPI(EGL_OPENGL_ES_API); + #else + eglBindAPI(EGL_OPENGL_API); + #endif - eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.rSurf); - eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface); + win->src.EGL_context = eglCreateContext(win->src.EGL_display, config, EGL_NO_CONTEXT, attribs); - eglSwapInterval(win->src.EGL_display, 1); + eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.EGL_context); + eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface); } - void* RGFW_getProcAddress(const char* procname) { return (void*) eglGetProcAddress(procname); } + #ifdef RGFW_APPLE + void* RGFWnsglFramework = NULL; + #elif defined(RGFW_WINDOWS) + static HMODULE wglinstance = NULL; + #endif + + void* RGFW_getProcAddress(const char* procname) { + #if defined(RGFW_WINDOWS) + void* proc = (void*) GetProcAddress(wglinstance, procname); + + if (proc) + return proc; + #endif + + return (void*) eglGetProcAddress(procname); + } void RGFW_closeEGL(RGFW_window* win) { eglDestroySurface(win->src.EGL_display, win->src.EGL_surface); - eglDestroyContext(win->src.EGL_display, win->src.rSurf); + eglDestroyContext(win->src.EGL_display, win->src.EGL_context); eglTerminate(win->src.EGL_display); } #endif /* RGFW_EGL */ +#endif /* RGFW_GL stuff? */ /* This is where OS specific stuff starts @@ -2388,7 +2469,7 @@ typedef struct { i32 x, y; } RGFW_vector; } u32 i; - for (i = 0; i < fbcount; i++) { + for (i = 0; i < (u32)fbcount; i++) { XVisualInfo* vi = glXGetVisualFromFBConfig((Display*) win->src.display, fbc[i]); if (vi == NULL) continue; @@ -2398,8 +2479,9 @@ typedef struct { i32 x, y; } RGFW_vector; i32 samp_buf, samples; glXGetFBConfigAttrib((Display*) win->src.display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetFBConfigAttrib((Display*) win->src.display, fbc[i], GLX_SAMPLES, &samples); - if ((best_fbc < 0 || samp_buf) && (samples == RGFW_SAMPLES)) + if ((best_fbc < 0 || samp_buf) && (samples == RGFW_SAMPLES || best_fbc == -1)) { best_fbc = i; + } } if (best_fbc == -1) { @@ -2471,11 +2553,6 @@ typedef struct { i32 x, y; } RGFW_vector; win->src.rSurf = glXCreateContextAttribsARB((Display*) win->src.display, bestFbc, ctx, True, context_attribs); #endif - -#ifdef RGFW_EGL - RGFW_createOpenGLContext(win); -#endif - if (RGFW_root == NULL) RGFW_root = win; @@ -2558,6 +2635,10 @@ typedef struct { i32 x, y; } RGFW_vector; PropModeReplace, (u8*) &version, 1); /* turns on drag and drop */ } + #ifdef RGFW_EGL + RGFW_createOpenGLContext(win); + #endif + RGFW_window_setMouseDefault(win); RGFW_windowsOpen++; @@ -2593,9 +2674,11 @@ typedef struct { i32 x, y; } RGFW_vector; int xAxis = 0, yAxis = 0; + char RGFW_keyboard[32]; + char RGFW_keyboard_prev[32]; + RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { assert(win != NULL); - win->event.type = 0; #ifdef __linux__ @@ -2650,13 +2733,6 @@ typedef struct { i32 x, y; } RGFW_vector; } u32 i; - - if (win->event.droppedFilesCount) { - for (i = 0; i < win->event.droppedFilesCount; i++) - win->event.droppedFiles[i][0] = '\0'; - } - - win->event.droppedFilesCount = 0; win->event.type = 0; @@ -2676,6 +2752,11 @@ typedef struct { i32 x, y; } RGFW_vector; win->event.keyCode = XkbKeycodeToKeysym((Display*) win->src.display, E.xkey.keycode, 0, E.xkey.state & ShiftMask ? 1 : 0); win->event.keyName = XKeysymToString(win->event.keyCode); /* convert to string */ + if (RGFW_isPressedI(win, win->event.keyCode)) + RGFW_keyboard_prev[E.xkey.keycode >> 3] |= (1 << (E.xkey.keycode & 7)); + else + RGFW_keyboard_prev[E.xkey.keycode >> 3] |= 0; + /* get keystate data */ win->event.type = (E.type == KeyPress) ? RGFW_keyPressed : RGFW_keyReleased; @@ -2690,6 +2771,8 @@ typedef struct { i32 x, y; } RGFW_vector; else if (win->event.keyCode == XK_Num_Lock) win->event.lockState |= RGFW_NUMLOCK; } + + XQueryKeymap(win->src.display, RGFW_keyboard); /* query the keymap */ break; case ButtonPress: @@ -2718,6 +2801,14 @@ typedef struct { i32 x, y; } RGFW_vector; win->event.type = RGFW_quit; break; } + + /* reset DND values */ + if (win->event.droppedFilesCount) { + for (i = 0; i < win->event.droppedFilesCount; i++) + win->event.droppedFiles[i][0] = '\0'; + } + + win->event.droppedFilesCount = 0; /* much of this event (drag and drop code) is source from glfw @@ -3002,13 +3093,13 @@ typedef struct { i32 x, y; } RGFW_vector; win->src.winArgs &= ~RGFW_MOUSE_CHANGED; } - if (win->src.winArgs & RGFW_HOLD_MOUSE && win->event.inFocus && win->event.type == RGFW_mousePosChanged) { - RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); - - if (XEventsQueued((Display*) win->src.display, QueuedAfterReading) <= 1) - XSync(win->src.display, True); - } + if (win->src.winArgs & RGFW_HOLD_MOUSE && win->event.inFocus && win->event.type == RGFW_mousePosChanged) { + RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); + if (XEventsQueued((Display*) win->src.display, QueuedAfterReading) <= 1) + XSync(win->src.display, True); + } + XFlush((Display*) win->src.display); @@ -3022,7 +3113,7 @@ typedef struct { i32 x, y; } RGFW_vector; assert(win != NULL); #ifdef RGFW_VULKAN - for (int i = 0; i < win->src.image_count; i++) { + for (u32 i = 0; i < win->src.image_count; i++) { vkDestroyImageView(RGFW_vulkan_info.device, win->src.swapchain_image_views[i], NULL); } @@ -3212,7 +3303,7 @@ typedef struct { i32 x, y; } RGFW_vector; #ifndef RGFW_NO_X11_CURSOR /* free the previous cursor */ - if (win->src.cursor && win->src.cursor != -1) + if (win->src.cursor) XFreeCursor((Display*) win->src.display, (Cursor) win->src.cursor); XcursorImage* native = XcursorImageCreate(a.w, a.h); @@ -3235,6 +3326,8 @@ typedef struct { i32 x, y; } RGFW_vector; win->src.cursor = XcursorImageLoadCursor((Display*) win->src.display, native); XcursorImageDestroy(native); +#else + RGFW_UNUSED(image) RGFW_UNUSED(a.w) RGFW_UNUSED(channels) #endif } @@ -3256,7 +3349,7 @@ typedef struct { i32 x, y; } RGFW_vector; } RGFWDEF void RGFW_window_disableMouse(RGFW_window* win) { - + RGFW_UNUSED(win); } void RGFW_window_setMouseDefault(RGFW_window* win) { @@ -3267,7 +3360,7 @@ typedef struct { i32 x, y; } RGFW_vector; assert(win != NULL); /* free the previous cursor */ - if (win->src.cursor && win->src.cursor != -1) + if (win->src.cursor) XFreeCursor((Display*) win->src.display, (Cursor) win->src.cursor); win->src.winArgs |= RGFW_MOUSE_CHANGED; @@ -3615,7 +3708,7 @@ typedef struct { i32 x, y; } RGFW_vector; monitor.physW = (monitor.rect.w * 25.4f / 96.f); monitor.physH = (monitor.rect.h * 25.4f / 96.f); - strncpy(monitor.name, DisplayString(display), 128); + strcpy(monitor.name, DisplayString(display)); XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY); @@ -3648,7 +3741,7 @@ typedef struct { i32 x, y; } RGFW_vector; RGFW_monitor RGFW_monitors[6]; RGFW_monitor* RGFW_getMonitors(void) { size_t i; - for (i = 0; i < ScreenCount(RGFW_root->src.display) && i < 6; i++) + for (i = 0; i < (size_t)ScreenCount(RGFW_root->src.display) && i < 6; i++) RGFW_monitors[i] = RGFW_XCreateMonitor(i); return RGFW_monitors; @@ -3684,9 +3777,7 @@ typedef struct { i32 x, y; } RGFW_vector; RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) { return RGFW_XCreateMonitor(DefaultScreen(win->src.display)); } - - char keyboard[32]; - + u8 RGFW_isPressedI(RGFW_window* win, u32 key) { Display* d; if (win == (RGFW_window*) 0) @@ -3695,11 +3786,22 @@ typedef struct { i32 x, y; } RGFW_vector; return 0; else d = (Display*) win->src.display; + + KeyCode kc2 = XKeysymToKeycode(d, key); /* convert the key to a keycode */ + return (RGFW_keyboard[kc2 >> 3] & (1 << (kc2 & 7))); /* check if the key is pressed */ + } - XQueryKeymap(d, keyboard); /* query the keymap */ - + u8 RGFW_wasPressedI(RGFW_window* win, u32 key) { + Display* d; + if (win == (RGFW_window*) 0) + d = RGFW_root->src.display; + else if (!win->event.inFocus) + return 0; + else + d = (Display*) win->src.display; + KeyCode kc2 = XKeysymToKeycode(d, key); /* convert the key to a keycode */ - return !!(keyboard[kc2 >> 3] & (1 << (kc2 & 7))); /* check if the key is pressed */ + return !!(RGFW_keyboard_prev[kc2 >> 3] & (1 << (kc2 & 7))); /* check if the key is pressed */ } #endif @@ -3742,8 +3844,8 @@ typedef struct { i32 x, y; } RGFW_vector; void* RGFWjoystickApi = NULL; /* these two wgl functions need to be preloaded */ - typedef HGLRC(WINAPI* wglCreateContextAttribsARB_type)(HDC hdc, HGLRC hShareContext, - const i32* attribList); + typedef long long int (WINAPI* wglCreateContextAttribsARB_type)(HDC hdc, HGLRC hShareContext, + const int* attribList); wglCreateContextAttribsARB_type wglCreateContextAttribsARB = NULL; /* defines for creating ARB attributes */ @@ -3785,7 +3887,9 @@ typedef struct { i32 x, y; } RGFW_vector; #define WGL_SAMPLES_ARB 0x2042 #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9 +#ifndef RGFW_EGL static HMODULE wglinstance = NULL; +#endif #ifdef RGFW_WGL_LOAD typedef HGLRC(WINAPI* PFN_wglCreateContext)(HDC); @@ -3802,13 +3906,13 @@ static HMODULE wglinstance = NULL; PFN_wglGetCurrentDC wglGetCurrentDCSRC; PFN_wglGetCurrentContext wglGetCurrentContextSRC; -#define wglCreateContext wglCreateContextSRC -#define wglDeleteContext wglDeleteContextSRC -#define wglGetProcAddress wglGetProcAddressSRC -#define wglMakeCurrent wglMakeCurrentSRC + #define wglCreateContext wglCreateContextSRC + #define wglDeleteContext wglDeleteContextSRC + #define wglGetProcAddress wglGetProcAddressSRC + #define wglMakeCurrent wglMakeCurrentSRC -#define wglGetCurrentDC wglGetCurrentDCSRC -#define wglGetCurrentContext wglGetCurrentContextSRC + #define wglGetCurrentDC wglGetCurrentDCSRC + #define wglGetCurrentContext wglGetCurrentContextSRC #endif #ifdef RGFW_OPENGL @@ -3820,11 +3924,11 @@ static HMODULE wglinstance = NULL; return (void*) GetProcAddress(wglinstance, procname); } - typedef BOOL(APIENTRY* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats); + typedef u64 (APIENTRY* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats); static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL; #endif - RGFW_window RGFW_eventWindow = { {NULL} }; + RGFW_window RGFW_eventWindow; LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { @@ -3845,7 +3949,7 @@ static HMODULE wglinstance = NULL; #ifndef RGFW_NO_DPI static HMODULE RGFW_Shcore_dll = NULL; - typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*); + typedef u64 (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*); PFN_GetDpiForMonitor GetDpiForMonitorSRC = NULL; #define GetDpiForMonitor GetDpiForMonitorSRC #endif @@ -3898,6 +4002,7 @@ static HMODULE wglinstance = NULL; if (name[0] == 0) name = (char*) " "; RGFW_eventWindow.r = RGFW_RECT(-1, -1, -1, -1); + RGFW_eventWindow.src.window = NULL; RGFW_window* win = RGFW_window_basic_init(rect, args); @@ -4036,7 +4141,7 @@ static HMODULE wglinstance = NULL; ReleaseDC(dummyWin, dummy_dc); if (wglCreateContextAttribsARB != NULL) { - PIXELFORMATDESCRIPTOR pfd = { sizeof(pfd), 1, PFD_TYPE_RGBA, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 8, PFD_MAIN_PLANE, 24, 8 }; + PIXELFORMATDESCRIPTOR pfd = (PIXELFORMATDESCRIPTOR){ sizeof(pfd), 1, PFD_TYPE_RGBA, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 8, PFD_MAIN_PLANE, 24, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; if (args & RGFW_OPENGL_SOFTWARE) pfd.dwFlags |= PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED; @@ -4059,15 +4164,15 @@ static HMODULE wglinstance = NULL; u32 index = 0; i32 attribs[40]; -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 - SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB); + + SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); if (RGFW_majorVersion || RGFW_minorVersion) { SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion); SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_minorVersion); } - SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB); + SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); if (RGFW_majorVersion || RGFW_minorVersion) { SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion); @@ -4076,7 +4181,7 @@ static HMODULE wglinstance = NULL; SET_ATTRIB(0, 0); - win->src.rSurf = wglCreateContextAttribsARB(win->src.hdc, NULL, attribs); + win->src.rSurf = (HGLRC)wglCreateContextAttribsARB(win->src.hdc, NULL, attribs); } else { fprintf(stderr, "Failed to create an accelerated OpenGL Context\n"); @@ -4293,6 +4398,9 @@ static HMODULE wglinstance = NULL; return 0; } + BYTE RGFW_keyBoard[256]; + BYTE RGFW_keyBoard_prev[256]; + RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { assert(win != NULL); @@ -4317,14 +4425,6 @@ static HMODULE wglinstance = NULL; return &win->event; } - if (win->event.droppedFilesCount) { - u32 i; - for (i = 0; i < win->event.droppedFilesCount; i++) - win->event.droppedFiles[i][0] = '\0'; - } - - win->event.droppedFilesCount = 0; - win->event.inFocus = (GetForegroundWindow() == win->src.window); if (RGFW_checkXInput(&win->event)) @@ -4334,7 +4434,6 @@ static HMODULE wglinstance = NULL; return NULL; static BYTE keyboardState[256]; - GetKeyboardState(keyboardState); if (PeekMessageA(&msg, win->src.window, 0u, 0u, PM_REMOVE)) { switch (msg.message) { @@ -4345,24 +4444,37 @@ static HMODULE wglinstance = NULL; case WM_KEYUP: win->event.keyCode = (u32) msg.wParam; + if (RGFW_isPressedI(win, win->event.keyCode)) + RGFW_keyBoard_prev[win->event.keyCode] |= 0x80; + else + RGFW_keyBoard_prev[win->event.keyCode] = 0; + strncpy(win->event.keyName, RGFW_keyCodeTokeyStr(msg.lParam), 16); - if (GetKeyState(VK_SHIFT) & 0x8000) { + if (RGFW_isPressedI(win, VK_SHIFT)) { ToAscii((UINT) msg.wParam, MapVirtualKey((UINT) msg.wParam, MAPVK_VK_TO_CHAR), keyboardState, (LPWORD) win->event.keyName, 0); } win->event.type = RGFW_keyReleased; + GetKeyboardState(RGFW_keyBoard); break; case WM_KEYDOWN: win->event.keyCode = (u32) msg.wParam; + + if (RGFW_isPressedI(win, win->event.keyCode)) + RGFW_keyBoard_prev[win->event.keyCode] |= 0x80; + else + RGFW_keyBoard_prev[win->event.keyCode] = 0; + strncpy(win->event.keyName, RGFW_keyCodeTokeyStr(msg.lParam), 16); - if (GetKeyState(VK_SHIFT) & 0x8000) { + if (RGFW_isPressedI(win, VK_SHIFT) & 0x8000) { ToAscii((UINT) msg.wParam, MapVirtualKey((UINT) msg.wParam, MAPVK_VK_TO_CHAR), keyboardState, (LPWORD) win->event.keyName, 0); } win->event.type = RGFW_keyPressed; + GetKeyboardState(RGFW_keyBoard); break; case WM_MOUSEMOVE: @@ -4413,6 +4525,15 @@ static HMODULE wglinstance = NULL; much of this event is source from glfw */ case WM_DROPFILES: { + + if (win->event.droppedFilesCount) { + u32 i; + for (i = 0; i < win->event.droppedFilesCount; i++) + win->event.droppedFiles[i][0] = '\0'; + } + + win->event.droppedFilesCount = 0; + win->event.type = RGFW_dnd; HDROP drop = (HDROP) msg.wParam; @@ -4522,6 +4643,9 @@ static HMODULE wglinstance = NULL; typedef struct { int iIndex; HMONITOR hMonitor; } RGFW_mInfo; BOOL CALLBACK GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + RGFW_UNUSED(hdcMonitor) + RGFW_UNUSED(lprcMonitor) + RGFW_mInfo* info = (RGFW_mInfo*) dwData; if (info->hMonitor == hMonitor) return FALSE; @@ -4586,6 +4710,9 @@ static HMODULE wglinstance = NULL; RGFW_monitor RGFW_monitors[6]; BOOL CALLBACK GetMonitorHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + RGFW_UNUSED(hdcMonitor) + RGFW_UNUSED(lprcMonitor) + RGFW_mInfo* info = (RGFW_mInfo*) dwData; if (info->iIndex >= 6) @@ -4618,9 +4745,20 @@ static HMODULE wglinstance = NULL; if (win != NULL && !win->event.inFocus) return 0; - if (GetAsyncKeyState(key) & 0x8000) + if (RGFW_keyBoard[key] & 0x80) return 1; - else return 0; + + return 0; + } + + u8 RGFW_wasPressedI(RGFW_window* win, u32 key) { + if (win != NULL && !win->event.inFocus) + return 0; + + if (RGFW_keyBoard_prev[key] & 0x80) + return 1; + + return 0; } HICON RGFW_loadHandleImage(RGFW_window* win, u8* src, RGFW_area a, BOOL icon) { @@ -4684,6 +4822,7 @@ static HMODULE wglinstance = NULL; void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels) { assert(win != NULL); + RGFW_UNUSED(channels) HCURSOR cursor = (HCURSOR) RGFW_loadHandleImage(win, image, a, FALSE); SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) cursor); @@ -4824,6 +4963,7 @@ static HMODULE wglinstance = NULL; /* much of this function is sourced from GLFW */ void RGFW_window_setIcon(RGFW_window* win, u8* src, RGFW_area a, i32 channels) { assert(win != NULL); + RGFW_UNUSED(channels) HICON handle = RGFW_loadHandleImage(win, src, a, TRUE); @@ -4900,12 +5040,14 @@ static HMODULE wglinstance = NULL; u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) { assert(win != NULL); + RGFW_UNUSED(jsNumber) + return RGFW_registerJoystickF(win, (char*) ""); } u16 RGFW_registerJoystickF(RGFW_window* win, char* file) { assert(win != NULL); - + RGFW_UNUSED(file) return win->src.joystickCount - 1; } @@ -4936,7 +5078,7 @@ static HMODULE wglinstance = NULL; } #ifndef RGFW_NO_THREADS - RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args) { return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) *function_ptr, args, 0, NULL); } + RGFW_thread RGFW_createThread(RGFW_threadFunc_ptr ptr, void* args) { return CreateThread(NULL, 0, ptr, args, 0, NULL); } void RGFW_cancelThread(RGFW_thread thread) { CloseHandle((HANDLE) thread); } void RGFW_joinThread(RGFW_thread thread) { WaitForSingleObject((HANDLE) thread, INFINITE); } void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { SetThreadPriority((HANDLE) thread, priority); } @@ -4962,7 +5104,10 @@ static HMODULE wglinstance = NULL; } #endif - CVReturn displayCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow, const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) { return kCVReturnSuccess; } + CVReturn displayCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow, const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) { + RGFW_UNUSED(displayLink) RGFW_UNUSED(inNow) RGFW_UNUSED(inOutputTime) RGFW_UNUSED(flagsIn) RGFW_UNUSED(flagsOut) RGFW_UNUSED(displayLinkContext) + return kCVReturnSuccess; + } RGFW_window* RGFW_windows[10]; u32 RGFW_windows_size = 0; @@ -4983,17 +5128,25 @@ static HMODULE wglinstance = NULL; } /* NOTE(EimaMei): Fixes the constant clicking when the app is running under a terminal. */ - bool acceptsFirstResponder() { return true; } - bool performKeyEquivalent(NSEvent* event) { return true; } + bool acceptsFirstResponder(void) { return true; } + bool performKeyEquivalent(NSEvent* event) { RGFW_UNUSED(event); return true; } - NSDragOperation draggingEntered(id self, SEL sel, id sender) { return NSDragOperationCopy; } - NSDragOperation draggingUpdated(id self, SEL sel, id sender) { return NSDragOperationCopy; } + NSDragOperation draggingEntered(id self, SEL sel, id sender) { + RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel); + return NSDragOperationCopy; + } + NSDragOperation draggingUpdated(id self, SEL sel, id sender) { + RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel); + return NSDragOperationCopy; + } bool prepareForDragOperation(void) { return true; } - void RGFW__osxDraggingEnded(id self, SEL sel, id sender) { return; } + void RGFW__osxDraggingEnded(id self, SEL sel, id sender) { RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel); return; } /* NOTE(EimaMei): Usually, you never need 'id self, SEL cmd' for C -> Obj-C methods. This isn't the case. */ bool performDragOperation(id self, SEL sel, id sender) { + RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel); + NSWindow* window = objc_msgSend_id(sender, sel_registerName("draggingDestinationWindow")); u32 i; bool found = false; @@ -5007,10 +5160,10 @@ static HMODULE wglinstance = NULL; if (!found) i = 0; - Class* array[] = { objc_getClass("NSURL"), NULL }; - char** droppedFiles = (char**) NSPasteboard_readObjectsForClasses( - (NSPasteboard*) objc_msgSend_id(sender, sel_registerName("draggingPasteboard")), - array, 1, NULL); + Class array[] = { objc_getClass("NSURL"), NULL }; + NSPasteboard* pasteBoard = objc_msgSend_id(sender, sel_registerName("draggingPasteboard")); + + char** droppedFiles = (char**) NSPasteboard_readObjectsForClasses(pasteBoard, array, 1, NULL); RGFW_windows[i]->event.droppedFilesCount = si_array_len(droppedFiles); @@ -5020,11 +5173,12 @@ static HMODULE wglinstance = NULL; strcpy(RGFW_windows[i]->event.droppedFiles[y], droppedFiles[y]); RGFW_windows[i]->event.type = RGFW_dnd; + RGFW_windows[i]->src.dndPassed = false; - NSPoint p = *(NSPoint*) objc_msgSend_id(sender, sel_registerName("draggingLocation")); - RGFW_windows[i]->event.point.x = p.x; - RGFW_windows[i]->event.point.x = p.y; + NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(sender, sel_registerName("draggingLocation")); + RGFW_windows[i]->event.point.x = (i32)p.x; + RGFW_windows[i]->event.point.x = (i32)p.y; return true; } @@ -5059,6 +5213,8 @@ static HMODULE wglinstance = NULL; NSSize RGFW__osxWindowResize(void* self, SEL sel, NSSize frameSize) { + RGFW_UNUSED(sel); + u32 i; for (i = 0; i < RGFW_windows_size; i++) { if (RGFW_windows[i] && NSWindow_delegate(RGFW_windows[i]) == self) { @@ -5074,6 +5230,8 @@ static HMODULE wglinstance = NULL; } void RGFW__osxWindowMove(void* self, SEL sel) { + RGFW_UNUSED(sel); + u32 i; for (i = 0; i < RGFW_windows_size; i++) { if (RGFW_windows[i] && NSWindow_delegate(RGFW_windows[i]) == self) { @@ -5093,8 +5251,8 @@ static HMODULE wglinstance = NULL; #define APPKIT_EXTERN extern #endif - APPKIT_EXTERN NSPasteboardType const NSPasteboardTypeURL = "public.url"; API_AVAILABLE(macos(10.13)); // Equivalent to kUTTypeURL - APPKIT_EXTERN NSPasteboardType const NSPasteboardTypeFileURL = "public.file-url"; API_AVAILABLE(macos(10.13)); // Equivalent to kUTTypeFileURL + NSPasteboardType const NSPasteboardTypeURL = "public.url"; + NSPasteboardType const NSPasteboardTypeFileURL = "public.file-url"; RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) { static u8 RGFW_loaded = 0; @@ -5109,7 +5267,7 @@ static HMODULE wglinstance = NULL; si_func_to_SEL("NSWindow", performKeyEquivalent); if (NSApp == NULL) { - NSApp = objc_msgSend_id(objc_getClass("NSApplication"), sel_registerName("sharedApplication")); + NSApp = objc_msgSend_id((id)objc_getClass("NSApplication"), sel_registerName("sharedApplication")); ((void (*)(id, SEL, NSUInteger))objc_msgSend) (NSApp, sel_registerName("setActivationPolicy:"), NSApplicationActivationPolicyRegular); @@ -5164,7 +5322,7 @@ static HMODULE wglinstance = NULL; #else NSRect contentRect = NSMakeRect(0, 0, win->r.w, win->r.h); win->src.view = ((id(*)(id, SEL, NSRect))objc_msgSend) - (NSAlloc(objc_getClass("NSView")), sel_registerName("initWithFrame:"), + (NSAlloc((id)objc_getClass("NSView")), sel_registerName("initWithFrame:"), contentRect); #endif @@ -5193,7 +5351,7 @@ static HMODULE wglinstance = NULL; } win->src.display = CGMainDisplayID(); - CVDisplayLinkCreateWithCGDisplay(win->src.display, &win->src.displayLink); + CVDisplayLinkCreateWithCGDisplay(win->src.display, (CVDisplayLinkRef*)&win->src.displayLink); CVDisplayLinkSetOutputCallback(win->src.displayLink, displayCallback, win); CVDisplayLinkStart(win->src.displayLink); @@ -5213,35 +5371,17 @@ static HMODULE wglinstance = NULL; NSMoveToResourceDir(); Class delegateClass = objc_allocateClassPair(objc_getClass("NSObject"), "WindowDelegate", 0); + + class_addMethod(delegateClass, sel_registerName("windowWillResize:toSize:"), (IMP) RGFW__osxWindowResize, "{NSSize=ff}@:{NSSize=ff}"); class_addMethod(delegateClass, sel_registerName("windowWillMove:"), (IMP) RGFW__osxWindowMove, ""); class_addMethod(delegateClass, sel_registerName("windowDidMove:"), (IMP) RGFW__osxWindowMove, ""); - - - if (args & RGFW_ALLOW_DND) { - win->src.winArgs |= RGFW_ALLOW_DND; - -/* - NSPasteboardType types[] = {NSPasteboardTypeURL, NSPasteboardTypeFileURL, NSPasteboardTypeString}; - - siArray(NSPasteboardType) array = sic_arrayInit(types, sizeof(id), countof(types)); - NSWindow_registerForDraggedTypes(win->hwnd, array); - - win->dndHead = win->dndPrev = out; -*/ - - NSPasteboardType array[] = {NSPasteboardTypeURL, NSPasteboardTypeFileURL, NSPasteboardTypeString}; - NSregisterForDraggedTypes(win->src.window, array, 3); - - /* NOTE(EimaMei): Drag 'n Drop requires too many damn functions for just a Drag 'n Drop event. */ - class_addMethod(delegateClass, "draggingEntered:", draggingEntered, "l@:@"); - class_addMethod(delegateClass, "draggingUpdated:", draggingUpdated, "l@:@"); - class_addMethod(delegateClass, "draggingExited:", RGFW__osxDraggingEnded, "v@:@"); - class_addMethod(delegateClass, "draggingEnded:", RGFW__osxDraggingEnded, "v@:@"); - class_addMethod(delegateClass, "prepareForDragOperation:", prepareForDragOperation, "B@:@"); - class_addMethod(delegateClass, "performDragOperation:", performDragOperation, "B@:@"); - - } + class_addMethod(delegateClass, sel_registerName("draggingEntered:"), (IMP)draggingEntered, "l@:@"); + class_addMethod(delegateClass, sel_registerName("draggingUpdated:"), (IMP)draggingUpdated, "l@:@"); + class_addMethod(delegateClass, sel_registerName("draggingExited:"), (IMP)RGFW__osxDraggingEnded, "v@:@"); + class_addMethod(delegateClass, sel_registerName("draggingEnded:"), (IMP)RGFW__osxDraggingEnded, "v@:@"); + class_addMethod(delegateClass, sel_registerName("prepareForDragOperation:"), (IMP)prepareForDragOperation, "B@:@"); + class_addMethod(delegateClass, sel_registerName("performDragOperation:"), (IMP)performDragOperation, "B@:@"); id delegate = objc_msgSend_id(NSAlloc(delegateClass), sel_registerName("init")); @@ -5249,6 +5389,13 @@ static HMODULE wglinstance = NULL; objc_msgSend_void_id(win->src.window, sel_registerName("setDelegate:"), delegate); + if (args & RGFW_ALLOW_DND) { + win->src.winArgs |= RGFW_ALLOW_DND; + + NSPasteboardType types[] = {NSPasteboardTypeURL, NSPasteboardTypeFileURL, NSPasteboardTypeString}; + NSregisterForDraggedTypes(win->src.window, types, 3); + } + // Show the window ((id(*)(id, SEL, SEL))objc_msgSend)(win->src.window, sel_registerName("makeKeyAndOrderFront:"), NULL); objc_msgSend_void_bool(win->src.window, sel_registerName("setIsVisible:"), true); @@ -5259,6 +5406,8 @@ static HMODULE wglinstance = NULL; RGFW_loaded = 1; } + objc_msgSend_void(win->src.window, sel_registerName("makeKeyWindow")); + NSApplication_finishLaunching(NSApp); RGFW_windows_size++; @@ -5385,12 +5534,25 @@ static HMODULE wglinstance = NULL; }; + typedef enum NSEventModifierFlags { + NSEventModifierFlagCapsLock = 1 << 16, + NSEventModifierFlagShift = 1 << 17, + NSEventModifierFlagControl = 1 << 18, + NSEventModifierFlagOption = 1 << 19, + NSEventModifierFlagCommand = 1 << 20 + } NSEventModifierFlags; + RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { assert(win != NULL); if (win->event.type == RGFW_quit) return &win->event; + if (win->event.type == RGFW_dnd && win->src.dndPassed == 0) { + win->src.dndPassed = 1; + return &win->event; + } + static void* eventFunc = NULL; if (eventFunc == NULL) eventFunc = sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:"); @@ -5426,85 +5588,156 @@ static HMODULE wglinstance = NULL; win->event.inFocus = (bool) objc_msgSend_bool(win->src.window, sel_registerName("isKeyWindow")); switch (objc_msgSend_uint(e, sel_registerName("type"))) { - case NSEventTypeKeyDown: - win->event.type = RGFW_keyPressed; - win->event.keyCode = (u16) objc_msgSend_uint(e, sel_registerName("keyCode")); - win->event.keyName = (const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters"))); + case NSEventTypeKeyDown: + win->event.keyCode = (u16) objc_msgSend_uint(e, sel_registerName("keyCode")); + RGFW_keyBoard_prev[win->event.keyCode] = RGFW_keyBoard[win->event.keyCode]; - RGFW_keyMap[win->event.keyCode] = 1; - break; + win->event.type = RGFW_keyPressed; + win->event.keyName = (char*)(const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters"))); - case NSEventTypeKeyUp: - win->event.type = RGFW_keyReleased; - win->event.keyCode = (u16) objc_msgSend_uint(e, sel_registerName("keyCode")); - win->event.keyName = (const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters"))); + RGFW_keyBoard[win->event.keyCode] = 1; + break; - RGFW_keyMap[win->event.keyCode] = 0; - break; + case NSEventTypeKeyUp: + win->event.keyCode = (u16) objc_msgSend_uint(e, sel_registerName("keyCode")); - case NSEventTypeLeftMouseDragged: - case NSEventTypeOtherMouseDragged: - case NSEventTypeRightMouseDragged: - case NSEventTypeMouseMoved: - win->event.type = RGFW_mousePosChanged; - NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(e, sel_registerName("locationInWindow")); + RGFW_keyBoard_prev[win->event.keyCode] = RGFW_keyBoard[win->event.keyCode]; + + win->event.type = RGFW_keyReleased; + win->event.keyName = (char*)(const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters"))); + + RGFW_keyBoard[win->event.keyCode] = 0; + break; + + case NSEventTypeFlagsChanged: { + u32 flags = objc_msgSend_uint(e, sel_registerName("modifierFlags")); + memcpy(RGFW_keyBoard_prev + 55, RGFW_keyBoard + 55, 5); - win->event.point = RGFW_VECTOR((u32) p.x, (u32) (win->r.h - p.y)); + if ((flags & NSEventModifierFlagCapsLock) && !RGFW_wasPressedI(win, 57)) { + RGFW_keyBoard[57] = 1; + win->event.type = RGFW_keyPressed; + win->event.keyCode = 57; + break; + } if (!(flags & NSEventModifierFlagCapsLock) && RGFW_wasPressedI(win, 57)) { + RGFW_keyBoard[57] = 0; + win->event.type = RGFW_keyReleased; + win->event.keyCode = 57; + break; + } + + if ((flags & NSEventModifierFlagOption) && !RGFW_wasPressedI(win, 58)) { + RGFW_keyBoard[58] = 1; + win->event.type = RGFW_keyPressed; + win->event.keyCode = 58; + break; + } if (!(flags & NSEventModifierFlagOption) && RGFW_wasPressedI(win, 58)) { + RGFW_keyBoard[58] = 0; + win->event.type = RGFW_keyReleased; + win->event.keyCode = 58; + break; + } + + if ((flags & NSEventModifierFlagControl) && !RGFW_wasPressedI(win, 59)) { + RGFW_keyBoard[59] = 1; + win->event.type = RGFW_keyPressed; + win->event.keyCode = 59; + break; + } if (!(flags & NSEventModifierFlagControl) && RGFW_wasPressedI(win, 59)) { + RGFW_keyBoard[59] = 0; + win->event.type = RGFW_keyReleased; + win->event.keyCode = 59; + break; + } + + if ((flags & NSEventModifierFlagCommand) && !RGFW_wasPressedI(win, 55)) { + RGFW_keyBoard[55] = 1; + win->event.type = RGFW_keyPressed; + win->event.keyCode = 55; + break; + } if (!(flags & NSEventModifierFlagCommand) && RGFW_wasPressedI(win, 55)) { + RGFW_keyBoard[55] = 0; + win->event.type = RGFW_keyReleased; + win->event.keyCode = 55; + break; + } - if (win->src.winArgs & RGFW_HOLD_MOUSE) { - RGFW_vector mouse = RGFW_getGlobalMousePoint(); - if ((mouse.x != win->r.x + (win->r.w / 2) || mouse.y != win->r.y + (win->r.h / 2))) { - RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); + if ((flags & NSEventModifierFlagShift) && !RGFW_wasPressedI(win, 56)) { + RGFW_keyBoard[56] = 1; + win->event.type = RGFW_keyPressed; + win->event.keyCode = 56; + break; + } if (!(flags & NSEventModifierFlagShift) && RGFW_wasPressedI(win, 56)) { + RGFW_keyBoard[56] = 0; + win->event.type = RGFW_keyReleased; + win->event.keyCode = 56; + break; } + + break; } - break; + case NSEventTypeLeftMouseDragged: + case NSEventTypeOtherMouseDragged: + case NSEventTypeRightMouseDragged: + case NSEventTypeMouseMoved: + win->event.type = RGFW_mousePosChanged; + NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(e, sel_registerName("locationInWindow")); - case NSEventTypeLeftMouseDown: - win->event.button = RGFW_mouseLeft; - win->event.type = RGFW_mouseButtonPressed; - break; + win->event.point = RGFW_VECTOR((u32) p.x, (u32) (win->r.h - p.y)); - case NSEventTypeOtherMouseDown: - win->event.button = RGFW_mouseMiddle; - win->event.type = RGFW_mouseButtonPressed; - break; + if (win->src.winArgs & RGFW_HOLD_MOUSE) { + RGFW_vector mouse = RGFW_getGlobalMousePoint(); + if ((mouse.x != win->r.x + (win->r.w / 2) || mouse.y != win->r.y + (win->r.h / 2))) { + RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); + } + } + break; - case NSEventTypeRightMouseDown: - win->event.button = RGFW_mouseRight; - win->event.type = RGFW_mouseButtonPressed; - break; + case NSEventTypeLeftMouseDown: + win->event.button = RGFW_mouseLeft; + win->event.type = RGFW_mouseButtonPressed; + break; - case NSEventTypeLeftMouseUp: - win->event.button = RGFW_mouseLeft; - win->event.type = RGFW_mouseButtonReleased; - break; + case NSEventTypeOtherMouseDown: + win->event.button = RGFW_mouseMiddle; + win->event.type = RGFW_mouseButtonPressed; + break; - case NSEventTypeOtherMouseUp: - win->event.button = RGFW_mouseMiddle; - win->event.type = RGFW_mouseButtonReleased; - break; + case NSEventTypeRightMouseDown: + win->event.button = RGFW_mouseRight; + win->event.type = RGFW_mouseButtonPressed; + break; - case NSEventTypeScrollWheel: { - double deltaY = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName("deltaY")); + case NSEventTypeLeftMouseUp: + win->event.button = RGFW_mouseLeft; + win->event.type = RGFW_mouseButtonReleased; + break; + + case NSEventTypeOtherMouseUp: + win->event.button = RGFW_mouseMiddle; + win->event.type = RGFW_mouseButtonReleased; + break; - if (deltaY > 0) - win->event.button = RGFW_mouseScrollUp; + case NSEventTypeScrollWheel: { + double deltaY = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName("deltaY")); - else if (deltaY < 0) - win->event.button = RGFW_mouseScrollDown; + if (deltaY > 0) + win->event.button = RGFW_mouseScrollUp; - win->event.scroll = deltaY; + else if (deltaY < 0) + win->event.button = RGFW_mouseScrollDown; - win->event.type = RGFW_mouseButtonReleased; - break; - } - case NSEventTypeRightMouseUp: - win->event.button = RGFW_mouseRight; - win->event.type = RGFW_mouseButtonReleased; - break; + win->event.scroll = deltaY; - default: - break; + win->event.type = RGFW_mouseButtonReleased; + break; + } + case NSEventTypeRightMouseUp: + win->event.button = RGFW_mouseRight; + win->event.type = RGFW_mouseButtonReleased; + break; + + default: + break; } objc_msgSend_void_id(NSApp, sel_registerName("sendEvent:"), e); @@ -5617,6 +5850,8 @@ static HMODULE wglinstance = NULL; } void RGFW_window_showMouse(RGFW_window* win, i8 show) { + RGFW_UNUSED(win); + if (show) { CGDisplayShowCursor(kCGDirectMainDisplay); } @@ -5626,11 +5861,13 @@ static HMODULE wglinstance = NULL; } void RGFW_window_setMouseStandard(RGFW_window* win, void* mouse) { + RGFW_UNUSED(win); CGDisplayShowCursor(kCGDirectMainDisplay); objc_msgSend_void(mouse, sel_registerName("set")); } void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector v) { + RGFW_UNUSED(win); assert(win != NULL); CGWarpMouseCursorPosition(CGPointMake(v.x, v.y)); @@ -5716,6 +5953,7 @@ static HMODULE wglinstance = NULL; } u8 RGFW_isPressedI(RGFW_window* win, u32 key) { + RGFW_UNUSED(win); if (key >= 128) { #ifdef RGFW_PRINT_ERRORS fprintf(stderr, "RGFW_isPressedI : invalid keycode\n"); @@ -5723,7 +5961,19 @@ static HMODULE wglinstance = NULL; RGFW_error = 1; } - return RGFW_keyMap[key]; + return RGFW_keyBoard[key]; + } + + u8 RGFW_wasPressedI(RGFW_window* win, u32 key) { + RGFW_UNUSED(win); + if (key >= 128) { +#ifdef RGFW_PRINT_ERRORS + fprintf(stderr, "RGFW_wasPressedI : invalid keycode\n"); +#endif + RGFW_error = 1; + } + + return RGFW_keyBoard_prev[key]; } #ifdef __cplusplus @@ -5740,6 +5990,8 @@ static HMODULE wglinstance = NULL; } void RGFW_writeClipboard(const char* text, u32 textLen) { + RGFW_UNUSED(textLen); + NSPasteboardType array[] = { NSPasteboardTypeString, NULL }; NSPasteBoard_declareTypes(NSPasteboard_generalPasteboard(), array, 1, NULL); @@ -5747,12 +5999,16 @@ static HMODULE wglinstance = NULL; } u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) { + RGFW_UNUSED(jsNumber); + assert(win != NULL); return RGFW_registerJoystickF(win, (char*) ""); } u16 RGFW_registerJoystickF(RGFW_window* win, char* file) { + RGFW_UNUSED(file); + assert(win != NULL); return win->src.joystickCount - 1; @@ -5820,9 +6076,11 @@ static HMODULE wglinstance = NULL; #ifndef RGFW_NO_THREADS #include - RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args) { + RGFW_thread RGFW_createThread(RGFW_threadFunc_ptr ptr, void* args) { + RGFW_UNUSED(args); + RGFW_thread t; - pthread_create((pthread_t*) &t, NULL, *function_ptr, NULL); + pthread_create((pthread_t*) &t, NULL, *ptr, NULL); return t; } void RGFW_cancelThread(RGFW_thread thread) { pthread_cancel((pthread_t) thread); } @@ -5848,7 +6106,7 @@ static HMODULE wglinstance = NULL; #endif #else #ifdef RGFW_EGL - eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.rSurf); + eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.EGL_context); #endif #endif @@ -5927,9 +6185,6 @@ static HMODULE wglinstance = NULL; void RGFW_window_swapBuffers(RGFW_window* win) { assert(win != NULL); - win->event.frames++; - RGFW_window_checkFPS(win); - RGFW_window_makeCurrent(win); /* clear the window*/ @@ -5958,10 +6213,10 @@ static HMODULE wglinstance = NULL; RGFW_area area = RGFW_getScreenSize(); #ifndef RGFW_X11_DONT_CONVERT_BGR - win->src.bitmap->data = (const char*) win->buffer; + win->src.bitmap->data = (char*) win->buffer; u32 x, y; - for (y = 0; y < win->r.h; y++) { - for (x = 0; x < win->r.w; x++) { + for (y = 0; y < (u32)win->r.h; y++) { + for (x = 0; x < (u32)win->r.w; x++) { u32 index = (y * 4 * area.w) + x * 4; u8 red = win->src.bitmap->data[index]; @@ -5992,7 +6247,7 @@ static HMODULE wglinstance = NULL; "NSDeviceRGBColorSpace", 0, area.w * 4, 32 ); - id image = NSAlloc(objc_getClass("NSImage")); + id image = NSAlloc((id)objc_getClass("NSImage")); NSImage_addRepresentation(image, rep); objc_msgSend_void_id(layer, sel_registerName("setContents:"), (id) image); @@ -6009,28 +6264,25 @@ static HMODULE wglinstance = NULL; #endif } - if (win->src.winArgs & RGFW_NO_GPU_RENDER) - return; + if (!(win->src.winArgs & RGFW_NO_GPU_RENDER)) { + #ifdef RGFW_EGL + eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface); + #elif defined(RGFW_OPENGL) + #if defined(RGFW_X11) && defined(RGFW_OPENGL) + glXSwapBuffers((Display*) win->src.display, (Window) win->src.window); + #elif defined(RGFW_WINDOWS) + SwapBuffers(win->src.hdc); + #elif defined(RGFW_MACOS) + NSOpenGLContext_flushBuffer(win->src.rSurf); + #endif + #endif -#ifdef RGFW_OPENGL -#ifdef RGFW_EGL - eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface); -#else -#if defined(RGFW_X11) && defined(RGFW_OPENGL) - glXSwapBuffers((Display*) win->src.display, (Window) win->src.window); -#endif -#ifdef RGFW_WINDOWS - SwapBuffers(win->src.hdc); -#endif -#if defined(RGFW_MACOS) - NSOpenGLContext_flushBuffer(win->src.rSurf); -#endif -#endif -#endif + #if defined(RGFW_WINDOWS) && defined(RGFW_DIRECTX) + win->src.swapchain->lpVtbl->Present(win->src.swapchain, 0, 0); + #endif + } -#if defined(RGFW_WINDOWS) && defined(RGFW_DIRECTX) - win->src.swapchain->lpVtbl->Present(win->src.swapchain, 0, 0); -#endif + RGFW_window_checkFPS(win); } void RGFW_window_maximize(RGFW_window* win) { @@ -6072,11 +6324,11 @@ static HMODULE wglinstance = NULL; #endif } - void RGFW_sleep(u32 ms) { + void RGFW_sleep(u64 ms) { #ifndef RGFW_WINDOWS struct timespec time; time.tv_sec = 0; - time.tv_nsec = ms * 1000; + time.tv_nsec = ms * 1e+6; nanosleep(&time, NULL); #else @@ -6084,32 +6336,31 @@ static HMODULE wglinstance = NULL; #endif } - static float currentFrameTime = 0; - void RGFW_window_checkFPS(RGFW_window* win) { - assert(win != NULL); - - win->event.fps = RGFW_getFPS(); + u64 deltaTime = RGFW_getTimeNS() - win->event.frameTime; - if (win->fpsCap == 0) - return; + u64 fps = round(1e+9 / deltaTime); + win->event.fps = fps; - double targetFrameTime = 1.0 / win->fpsCap; - double elapsedTime = RGFW_getTime() - currentFrameTime; + if (win->fpsCap && fps > win->fpsCap) { + u64 frameTimeNS = 1e+9 / win->fpsCap; + u64 sleepTimeMS = (frameTimeNS - deltaTime) / 1e6; - if (elapsedTime < targetFrameTime) { - u32 sleepTime = (u32) ((targetFrameTime - elapsedTime) * 1e3); - RGFW_sleep(sleepTime); + if (sleepTimeMS > 0) { + RGFW_sleep(sleepTimeMS); + win->event.frameTime = 0; + } } - currentFrameTime = (float) RGFW_getTime(); + win->event.frameTime = RGFW_getTimeNS(); + + if (win->fpsCap) { + u64 deltaTime = RGFW_getTimeNS() - win->event.frameTime2; - if (elapsedTime < targetFrameTime) { - u32 sleepTime = (u32) ((targetFrameTime - elapsedTime) * 1e3); - RGFW_sleep(sleepTime); + win->event.fps = round(1e+9 / deltaTime); + + win->event.frameTime2 = RGFW_getTimeNS(); } - - currentFrameTime = (float) RGFW_getTime(); } #ifdef __APPLE__ @@ -6127,7 +6378,7 @@ static HMODULE wglinstance = NULL; return (u64) (counter.QuadPart * 1e9 / frequency.QuadPart); #elif defined(__unix__) struct timespec ts = { 0 }; - clock_gettime(CLOCK_MONOTONIC, &ts); + clock_gettime(1, &ts); unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; return nanoSeconds; @@ -6151,7 +6402,7 @@ static HMODULE wglinstance = NULL; return (u64) (counter.QuadPart / (double) frequency.QuadPart); #elif defined(__unix__) struct timespec ts = { 0 }; - clock_gettime(CLOCK_MONOTONIC, &ts); + clock_gettime(1, &ts); unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; return (double)(nanoSeconds) * 1e-9; @@ -6165,27 +6416,6 @@ static HMODULE wglinstance = NULL; return 0; } - u32 RGFW_getFPS(void) { - static double previousSeconds = 0.0; - if (previousSeconds == 0.0) - previousSeconds = (double) RGFW_getTime();//glfwGetTime(); - - static i16 frameCount; - double currentSeconds = (double) RGFW_getTime();//glfwGetTime(); - double elapsedSeconds = currentSeconds - previousSeconds; - static double fps = 0; - - if (elapsedSeconds > 0.25) { - previousSeconds = currentSeconds; - fps = (double) frameCount / elapsedSeconds; - frameCount = 0; - } - - frameCount++; - - return (u32) fps; - } - #endif /*RGFW_IMPLEMENTATION*/ #define RGFW_Escape RGFW_OS_BASED_VALUE(0xff1b, 0x1B, 53) diff --git a/src/external/rl_gputex.h b/src/external/rl_gputex.h index c577305522cd..6b26d1c8d9b0 100644 --- a/src/external/rl_gputex.h +++ b/src/external/rl_gputex.h @@ -171,6 +171,10 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_ *width = header->width; *height = header->height; + + if (*width % 4 != 0) LOG("WARNING: IMAGE: DDS file width must be multiple of 4. Image will not display correctly"); + if (*height % 4 != 0) LOG("WARNING: IMAGE: DDS file height must be multiple of 4. Image will not display correctly"); + image_pixel_size = header->width*header->height; if (header->mipmap_count == 0) *mips = 1; // Parameter not used diff --git a/src/minshell.html b/src/minshell.html index 38f3672b9161..4068ca36c750 100644 --- a/src/minshell.html +++ b/src/minshell.html @@ -34,8 +34,12 @@