180 Commits

Author SHA1 Message Date
Ray
242dfee5ef Merge branch 'master' of https://github.com/raysan5/raylib 2026-01-29 19:51:25 +01:00
Ray
e56cdc2684 Update raylib_144x144.png 2026-01-29 19:51:04 +01:00
Ray
d5ae12f3eb Update raylib_1024x1024.png 2026-01-29 19:50:59 +01:00
08e79a16b0 Refactoring {0} to { 0 } to follow conventions (#5519)
Co-authored-by: maiconpintoabreu <maicon@thinkpad02.exads.com>
2026-01-29 17:30:03 +01:00
Ray
de7fc12be0 REVIEWED: IsGamepadButton*() for consistency with key and mouse equivalents 2026-01-28 19:35:54 +01:00
Ray
8a2da96eed Reviewed formating and spacing 2026-01-28 19:34:55 +01:00
af37fa2a96 Refactoring based on Coding Style Conventions (#5517)
Co-authored-by: maiconpintoabreu <maicon@thinkpad02.exads.com>
2026-01-28 19:27:03 +01:00
d0a6892989 [rcore] IsMouseButton*(), random key codes return unexpected results (#5516)
* update

* update

* stuff

* update

* move headerfile to root

* delete .h

* update ignore

* fix IsMouseButtonDown\Pressed\Released\Up will get randomly returned to true when the button code is outside the range of mouse button

* remove unessary macro

* refactor IsMouseButton*() early returns
2026-01-28 19:26:07 +01:00
63e4fd838d fixed typos preventing launch of native win32 backend (#5515) 2026-01-27 17:38:51 +01:00
4c71625730 [CI] Removing double zip and misleading zip type (#5512)
* Removing double zip and misleading zip type

* Removing extra spaces

---------

Co-authored-by: maiconpintoabreu <maicon@thinkpad02.exads.com>
2026-01-26 12:04:45 +01:00
3568b6e293 [rtext] Fix and enhance TextReplace() function (#5511)
* add check for replacement,replace strcpy,strncpy with memcpy

* add 4 spaces in if statement

* add spaces
2026-01-26 12:04:22 +01:00
Ray
6986183858 Merge branch 'master' of https://github.com/raysan5/raylib 2026-01-25 19:06:11 +01:00
Ray
65cddc852e Reviewed comments 2026-01-25 19:06:08 +01:00
afe74c1c70 Refactor int to float missing parse (#5503)
* refactor int to float parse

* Reverting  as requested

---------

Co-authored-by: Maicon <maicon@thinkpad02.exads.com>
2026-01-24 21:53:22 +01:00
70a63f7c62 [web] Fix Emscripten's Closure compiler error: undeclared canvas variable (#5507)
* Fix Emscripten Closure compiler error: undeclared canvas variable

* Fix hardcoded canvas IDs in web targets
2026-01-24 21:21:43 +01:00
Ray
a33ae4a8ef Update raymath.h 2026-01-23 17:11:37 +01:00
b21d7f234b [raymath] QuaternionFromVector3ToVector3(), math is wrong (#5508)
* the math in QuaternionFromVector3ToVector3 is wrong

* fix styling
2026-01-23 17:08:10 +01:00
eda915232d Update miniaudio to v0.11.24 (#5506) 2026-01-23 14:13:17 +01:00
e16467e8b6 Clean up Matrix handling and rl* functions to follow convention (#5505)
- Use named fields in rlTranslatef and rlScalef instead of array literals
- Label implicit row-major to column-major transpose in MatrixToFloatV
- Update rlSetUniformMatrix to use rlMatrixToFloat convention
2026-01-23 13:53:57 +01:00
594f5429b2 [rcore] LoadDirectoryFilesEx(), count files if not recursive (#5496)
* LoadDirectoryFilesEx on not recursive loading count files

* Removed FilePathList.capacity

* Added security check in case of memory leak

* Fix stop loading paths early on recursive loading

* Fix count directories only if filter contains DIRECTORY_FILTER_TAG

* rlparser: update raylib_api.* by CI

* GetDirectoryFileCount() and GetDirectoryFileCountEx() made visible

* rlparser: update raylib_api.* by CI

* Added new file and directories filter tags

* Renamed `fileCount` in `ScanDirectoryFiles()` to `expectedFileCount`

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-23 13:48:26 +01:00
Ray
c610d228a2 Update text_inline_styling.c 2026-01-20 21:01:41 +01:00
Ray
29896a2403 REVIEWED: Some comments (Code Gardening) 2026-01-19 12:40:32 +01:00
Ray
a8c75f2bc5 Update models_first_person_maze.c 2026-01-17 20:15:48 +01:00
Ray
fbed591a6f Reviewed example 2026-01-17 20:15:45 +01:00
9621c3d395 Add QNX EGL2.0 Library configuration (#5499) 2026-01-16 09:42:15 +01:00
10b94b02ad Fix opengl interop single header library not having it's implementation loaded (#5498) 2026-01-15 23:30:13 +01:00
Ray
439448ad7c Update rcore.c 2026-01-15 10:43:08 +01:00
Ray
0df2fe981b REVIEWED: ExportFontAsCode() #5497 2026-01-15 10:42:58 +01:00
a938a7c97a chore: add GetAppDir for wasm returning root VFS (#5495) 2026-01-15 10:08:03 +01:00
026b7e808a fix drm resources leak (#5494) 2026-01-15 10:03:54 +01:00
Ray
4b74312860 Update ROADMAP.md 2026-01-13 20:03:30 +01:00
Ray
4be6815b3b Revert "fix zig build accessing env vars (#5490)"
This reverts commit cfb81e4a00.
2026-01-13 16:27:51 +01:00
Ray
533a17e283 Merge branch 'master' of https://github.com/raysan5/raylib 2026-01-13 16:27:30 +01:00
Ray
132151cf28 Revert "Update build.zig to work with 0.16 (#5487)"
This reverts commit 32e7732061.
2026-01-13 16:27:16 +01:00
cfb81e4a00 fix zig build accessing env vars (#5490) 2026-01-12 22:58:41 +01:00
Ray
644ff28f87 Update shaders_deferred_rendering.c 2026-01-12 13:36:40 +01:00
Ray
28b9411e9d REMOVED: RLGL_RENDER_TEXTURES_HINT, enabled by default and no complaints of anyone having issues #5479 2026-01-12 13:23:27 +01:00
Ray
0c33c603f4 REVIEWED: EXTERNAL_CONFIG_FLAGS usage, check moved to config.h
Due to `utils` module removal, `EXTERNAL_CONFIG_FLAGS` was not working, so the system was redesigned.
This change is independent of #4411
2026-01-12 13:04:38 +01:00
32e7732061 Update build.zig to work with 0.16 (#5487) 2026-01-11 23:43:38 +01:00
d7c38cfbe4 fix rglfw.c path in build.zig for bsd platforms (#5486) 2026-01-11 22:01:14 +01:00
Ray
4badbe2b17 REVIEWED: Variable scope #5485 2026-01-11 21:02:59 +01:00
Ray
51bdaa34fa Update raylib.vcxproj 2026-01-11 16:56:47 +01:00
Ray
483b26ef84 Update rexm.c 2026-01-11 01:04:32 +01:00
Ray
972d6f0775 REXM: Fix raylib building 2026-01-11 00:32:16 +01:00
Ray
d94ea00a97 Update raylib.sln 2026-01-11 00:27:24 +01:00
Ray
f2c8a9c085 Merge branch 'master' of https://github.com/raysan5/raylib 2026-01-10 12:20:37 +01:00
Ray
1606dca0cb Update CMakeLists.txt 2026-01-10 12:20:26 +01:00
21f026a484 rlparser: update raylib_api.* by CI 2026-01-10 11:13:29 +00:00
Ray
dd7a1948f1 WARNING: REDESIGN: REMOVED: utils module, functionality moved to rcore module: logging and file-system #4551
[utils] was created long time ago, when [rcore] contained all the platforms code, the purpose of the file was exposing basic filesystem functionality across modules and also logging mechanism but many things have changed since then and there is no need to keep using this module.

 - Logging system has been move to [rcore] module and macros are exposed through `config.h` to other modules
 - File system functionality has also been centralized in [rcore] module that along the years it was already adding more and more file-system functions, now they are all in the same module
 - Android specific code has been moved to `rcore_android.c`, it had no sense to have specific platform code in `utils`, [rcore] is responsible of all platform code.
2026-01-10 12:13:07 +01:00
Ray
2f6feb74d4 Update raylib.sln 2026-01-10 11:53:46 +01:00
Ray
c7de5c9d4b Updated examples VCXPROJ UUID, not correctly calculated by REXM 2026-01-10 11:53:29 +01:00
Ray
6833305826 REVIEWED: android_fopen() 2026-01-10 10:59:22 +01:00
8de88c71da fix: fall back on dirent filename when all route fails on Android (#5484) 2026-01-10 10:54:54 +01:00
5b0a799769 fix (#5482) 2026-01-09 23:09:06 +01:00
Ray
1284d68721 Update core_highdpi_testbed.png 2026-01-09 20:18:45 +01:00
Ray
a6dd2af9e9 Update rexm.c 2026-01-09 20:06:57 +01:00
Ray
11f7db2dd8 REXM: ADDED: core_keyboard_testbed 2026-01-09 20:06:53 +01:00
Ray
7218b674e5 REXM: Updated: textures_framebuffer_rendering 2026-01-09 20:05:46 +01:00
Ray
cfd5c3f2ab Update examples_list.txt 2026-01-09 20:02:29 +01:00
Ray
b365d23f49 Update examples_list.txt 2026-01-09 19:59:38 +01:00
Ray
4cf844b74e Update raylib.h 2026-01-09 19:55:31 +01:00
Ray
5cc42c1b80 Updated file name 2026-01-09 19:55:26 +01:00
16e6d325b9 [raudio] Fix freeing the wrong memory (#5481) 2026-01-08 22:04:09 +01:00
0bcf79ce28 [#5455] Fix for: Fix window width calculation by adding wOffset (#5480) 2026-01-08 17:26:56 +01:00
Ray
5398b8c9b0 Update rexm.c 2026-01-07 23:09:51 +01:00
Ray
c814625c00 Update models_first_person_maze.c 2026-01-07 22:40:28 +01:00
5e1f5d5b74 examples/models: optimize collision check in first_person_maze (#5478)
Limit collision detection to the player surrounding cells instead of
iterating the full cubicmap each frame.
2026-01-07 22:38:04 +01:00
Ray
229f82699b Reviewed change #5476 2026-01-07 22:36:40 +01:00
c256f146b4 added saving to memory buffer and SaveFileData for binary files (#5476) 2026-01-07 22:32:58 +01:00
Ray
23bc037c37 Revert change, trying to follow DRM implementation but not needed on Android #5477 2026-01-07 22:32:09 +01:00
c78ac65786 Don't require a M3d animation only file to have a mesh. There are valid use cases for animation only files that can be applied to N other meshes. (#5475) 2026-01-06 22:32:42 +01:00
Ray
3678c2d157 REMOVE: TRACELOGD(), hardly ever used 2026-01-05 20:47:25 +01:00
Ray
35fc8ece44 Update models_decals.c 2026-01-03 23:01:37 +01:00
af544c24b9 [rcore] Fix touch position automation event handling (#5470)
* fix touch position automation event handling

* Fix alignment of previousPosition comment in rcore.c
2026-01-03 22:57:22 +01:00
c4b11a30cd Fix DrawMeshInstanced breaking if instanceTransform is unused (#5469) 2026-01-03 22:52:04 +01:00
a44157c2a8 [example] Added textures_frame_buffer_rendering (#5468) 2026-01-03 22:41:52 +01:00
b00cbdaf49 Cleanup warnings in examples (#5467) 2026-01-03 22:38:51 +01:00
f67e70bb47 Fix typecast warnings in rcore (#5466) 2026-01-03 08:59:34 +01:00
Ray
9fe51a6144 Merge branch 'master' of https://github.com/raysan5/raylib 2026-01-02 18:43:37 +01:00
Ray
c92de5f108 REVIEWED: Comments about intrinsics support #5316 2026-01-02 18:43:28 +01:00
942f93db55 fix(build): do not use != assignment in Makefiles (#5464)
GNU Make 3.81 that ships with MacOSX does not understand '!= ...' assignment
so we use ':= $(shell ...)' instead which have the same behavior here.

Additionally, I have changed the use of 'type' to 'command -v'
because assigning the result of 'type' to variable named 'EMMAKE'
does not make much sense. I also reused this variable.

For more detailed information read the linked issue.

Fixes: https://github.com/raysan5/raylib/issues/5460
2026-01-02 18:36:22 +01:00
Ray
ca89934ed5 Update year to 2026 2026-01-02 13:53:20 +01:00
Ray
416af51a93 Update year to 2026 2026-01-02 13:40:15 +01:00
980e4d0ad3 Use the size of the texture as the V scale so repeatable textures work well (#5463) 2026-01-02 13:15:25 +01:00
c9a456e273 Add DenoRaylib550 binding to BINDINGS.md (#5462) 2026-01-02 13:14:25 +01:00
Ray
c07d075a63 REVIEWED: Security checks formatting and comments 2026-01-01 16:54:44 +01:00
5a3391fdce [rtext] Fix multiple security vulnerabilities in font loading (#5433, #5434, #5436) (#5450) 2026-01-01 16:35:12 +01:00
Ray
909f040dc5 Remove trailing spaces 2026-01-01 16:33:34 +01:00
eb4ad50d99 make sure that our up vector really is up in an axis before picking a world plane (#5459) 2025-12-31 23:52:08 +01:00
Ray
95f72b162b REVIEWED: TextReplace(), revert breaking change, needs to be reviewed again... -WIP- 2025-12-31 22:50:17 +01:00
Ray
cac02ab063 REXM: REVIEWED: Add new example to collection list at the end of its category, instead of adding it at the end of the file 2025-12-31 22:48:07 +01:00
Ray
ab1d9b3830 REXM: Check example exists (compilation worked) before trying to run it 2025-12-31 22:47:16 +01:00
Ray
f805e6cae8 REXM: Update Makefile.Web before trying to rebuild new example for web 2025-12-31 22:46:36 +01:00
Ray
83377a3488 Update examples_list.txt 2025-12-31 22:29:12 +01:00
Ray
2377506843 Update rcamera.h 2025-12-31 20:50:27 +01:00
0133a4e6c6 Make CameraMove up and right work with Z up cameras like the other functions do. (#5458) 2025-12-31 20:45:29 +01:00
Ray
c124f2552b REVIEWED: SIMD instrinsics must be explicitly enabled by developer, only SSE supported at the moment #5316 2025-12-31 11:22:26 +01:00
Ray
66755da4c8 REVIEWED: eglGetPlatformDisplay() usage 2025-12-31 11:08:17 +01:00
Ray
02cca28b5f REVIEWED: eglGetPlatformDisplay() usage 2025-12-31 11:08:10 +01:00
25ce6465d5 Added SSE to MatrixMultiply. (#5427) 2025-12-31 10:58:58 +01:00
4af95a3a84 Use eglGetPlatformDisplayEXT on DRM platform for Mali compatibility (#5446) 2025-12-31 10:33:17 +01:00
e534f14419 Fix window width calculation by adding wOffset (#5457) 2025-12-31 09:05:39 +01:00
Ray
9b183e0c5e REXM: Update examples and reports 2025-12-30 23:21:10 +01:00
Ray
8c83dc7d70 Merge branch 'master' of https://github.com/raysan5/raylib 2025-12-30 22:49:45 +01:00
Ray
0c3e10b262 REVIEWED: FileExists(), using macro 2025-12-30 22:49:43 +01:00
4054fc42f3 Remove stdio.h unused header (#5456) 2025-12-30 22:09:20 +01:00
Ray
695f353533 Update Makefile.Web 2025-12-30 22:07:23 +01:00
Ray
f260f5fdd0 Update Makefile 2025-12-30 22:06:18 +01:00
Ray
fa1d4eb7fa Update shapes_hilbert_curve.c 2025-12-30 22:06:05 +01:00
Ray
6e70dece56 Update minshell.html 2025-12-30 22:05:37 +01:00
Ray
ebf2f61425 Delete core_input_keyboard_gamepad_test.c 2025-12-30 22:03:36 +01:00
Ray
6dfaf9fe7e REVIEWED: example shapes_hilbert_curve #5454
Make it more didactic and dynamic, avoid global variables
2025-12-30 21:19:54 +01:00
7523738677 Add hilbert curve example (#5454) 2025-12-30 20:11:37 +01:00
Ray
2b48cf6793 Formating review 2025-12-29 13:06:05 +01:00
1c6f683161 [rcore][drm] Improved touch input handling and multitouch support, closes #4842 (#5447)
* Improved touch input handling and multitouch support in drm platform

* revert

* made some fixes for the touch issue in drm platform

* updated touch input handling by adding multitouch support

* improved how it handles the multitouch

* added cleanup

* Remove touch last update tracking to simplify touch input handling

* improved multitouch support by tracking touch positions and IDs for each slot

* Better touch input handling

* Increase maximum touch points from 8 to 10 and enhance touchscreen prioritization logic

* Refactor touch input handling to use slot index as ID for stability and simplify touch clearing logic

* Improve touch input handling by activating slot 0 based on mouse click or touch events

* touch event handling to use tracking ID for unique touch identification

* Add multitouch detection to PollMouseEvents for improved touch handling

* Fix conditional formatting in PollMouseEvents for clarity

* Refactor conditional statements in PollMouseEvents and InitPlatform for improved readability

* Fix formatting in PollMouseEvents for improved readability
2025-12-29 12:54:30 +01:00
00f42e4199 [rcore] [android] fixed gesture system not reporting GESTURE_NONE (#5452)
in android gesture system is not reporting GESTURE_NONE, specified in the issue https://github.com/raysan5/raylib/issues/5010 so, automatically GESTURE_SWIPE, TAP, DOUBLE_TAP, also will not be reported. in this commit it is fixed.
2025-12-29 12:50:12 +01:00
Ray
58d414bcf8 REVIEWED: InitPlatform(), code simplification 2025-12-29 12:39:40 +01:00
8f8346048c Add chicken scheme to BINDINGS.md (#5449)
* Add chicken scheme to BINDINGS.md

* Fix typo
2025-12-28 23:50:10 +01:00
Ray
eb3cc183cc REVIEWED: FIXED: Windows fullscreen, after breaking it due to X11/Wayland changes 2025-12-28 20:29:01 +01:00
Ray
a334a54eac Update rcore_desktop_glfw.c 2025-12-28 20:09:15 +01:00
Ray
890ca8d687 REVIEWED: GetWindowPosition(), return internal value 2025-12-28 20:04:44 +01:00
Ray
6450a48c75 Update core_highdpi_testbed.c 2025-12-28 20:03:51 +01:00
Ray
8a75439c25 REVIEWED: Fullscreen modes on Linux (X11 over XWayland)
It does not work as expected... :(
2025-12-28 19:51:04 +01:00
Ray
8871d7648d Update core_highdpi_testbed.c 2025-12-28 19:49:38 +01:00
Ray
4176c518c7 Update rcore_desktop_glfw.c 2025-12-28 18:40:44 +01:00
Ray
c0c8ee9dc8 Update rcore_desktop_glfw.c 2025-12-28 18:15:47 +01:00
Ray
11c248aa82 Update rcore_web.c 2025-12-28 16:20:43 +01:00
Ray
2cf8983e18 WARNING: REDESIGNED: Fullscreen modes, use current display resolution
Considering multi-monitor and multi-ppi configurations
Fullscreen-exclusive scales to available display resolution, ignoring content scaling
Windowed-borderless scales to available logical resolution considering HighDPI **if requested**
2025-12-28 16:11:42 +01:00
Ray
297dcc07b8 Update core_highdpi_testbed.c 2025-12-28 16:08:34 +01:00
Ray
8cfb99f275 Minor comment tweaks 2025-12-28 16:08:19 +01:00
Ray
1d8e011eee Update rcore_drm.c 2025-12-28 16:08:08 +01:00
Ray
37bc3f5012 REMOVED: SetupFramebuffer(), most platforms do not need it any more
Kept only for platforms that could potentially need it
2025-12-28 16:07:59 +01:00
Ray
da1a76604f REMOVED: CORE.Window.fullscreen, using available flag instead 2025-12-28 16:05:42 +01:00
Ray
05f5143603 Update README.md 2025-12-27 15:05:18 +01:00
Ray
e4491b40b5 Update README.md 2025-12-27 14:43:46 +01:00
Ray
538bf82037 Update README.md 2025-12-27 14:35:38 +01:00
84dfe6a4cf [rmodels] Fix glTF animation framerate calculation (#4472) (#5445)
- Changed GLTF_ANIMDELAY (17ms, ~58.82fps) to GLTF_FRAMERATE (60.0fps)
- Updated frameCount calculation: (animDuration * 60) instead of (animDuration * 1000 / 17)
- Updated time calculation: j / 60.0f instead of (j * 17) / 1000.0f

This fixes animation frame count misalignment when importing glTF models
exported at standard 60fps. Animations that were 27+ frames shorter than
expected on 1350-frame sequences will now import correctly.
2025-12-27 14:22:24 +01:00
Ray
25a54d87e6 Update rcore_desktop_win32.c 2025-12-26 21:09:53 +01:00
Ray
64bd27bd08 Update rcore_desktop_glfw.c 2025-12-26 20:49:03 +01:00
aee6734cff fix: set correct default axes for gamepads that are not connected (inside rcore_desktop_glfw.c) (#5444)
* fix: set correct default axes for gamepads that are not connected

`glfwGetGamepadState` will set all gamepad state variables to 0.0 if required gamepad is not connected, but `RecordAutomationEvent()` inside rcore.c expects trigger axes to be -1.0f when gamepad is not connected. Since SDL and RGFW return -1.0f in such case, this change is aligning it with them

* updated comment in rcore_desktop_glfw.c
2025-12-26 20:46:09 +01:00
5e14ac5a2e #5387 - Fix keyboard input detected as gamepad on some Android devices (#5439)
* [rcore][android] Fix keyboard input detected as gamepad on some devices (#5387)

* [core] Add keyboard vs gamepad input test example (#5387)
2025-12-26 20:42:32 +01:00
101502103a Fixed FLAG_IS_SET to check if all bits in the flag are set in the value (#5441) 2025-12-24 20:58:40 +01:00
Ray
20dd4641c8 REVIEWED: Potential security concerns while copying unbounded text data between strings
Note that issue has been reported by CodeQL static analysis system
2025-12-24 19:35:06 +01:00
Ray
fc843dc557 Create SECURITY.md 2025-12-24 19:21:43 +01:00
Ray
9103f6e055 ADDED: New platform backend for Web: Emscripten, not dependant on GLFW.js -WIP- 2025-12-24 18:58:20 +01:00
Ray
ced84333a9 Update rl_gputex.h 2025-12-24 18:02:24 +01:00
Ray
05f42aa119 Update core_highdpi_testbed.c 2025-12-24 18:02:04 +01:00
a1e84caa8c RGFW also requires RGBA8 images as window icons, as raylib already reports in raylib.h (#5431) 2025-12-24 09:04:41 +01:00
ddb827fb6f Fixed LoadCodepoints declaring a new local variable shadowing codpoints (#5430) 2025-12-24 08:59:51 +01:00
0a4583ca54 [rl_gputex.h] Possibly fixed the swizzling in rl_load_dds_from_memory() function (#5422)
* Possibly fixed the swizzling bug

* Removed examples, and generation.
2025-12-23 17:10:55 +01:00
6a701b2679 fix android SetWindowState (#5424) 2025-12-23 15:37:08 +01:00
Ray
aa2884bd78 Update rcore_desktop_glfw.c 2025-12-22 22:50:38 +01:00
Ray
f27f2d097f REVIEWED: HighDPI support on macOS (when requested by app)
Tested on two monitors with different DPI configuration, for HigDPI enabled and not, including window resizing (with framebuffer resizing if required). Verified mouse coordinates follow the requested screen size.
2025-12-22 22:48:08 +01:00
Ray
e4baf682ab Update rtext.c 2025-12-22 20:30:11 +01:00
Ray
8516750975 Remove internal function 2025-12-22 20:29:57 +01:00
3212becc91 Update BINDINGS.md (#5421) 2025-12-21 20:15:38 +01:00
Ray
b9446863d7 REXM: RENAMED: core_high_dpi --> core_highdpi_demo 2025-12-20 22:36:44 +01:00
Ray
13f9112d8c Update rcore_desktop_sdl.c 2025-12-19 01:16:34 +01:00
Ray
f16fb065ea Update rcore_template.c 2025-12-19 01:15:34 +01:00
Ray
66392fe0ae REVIEWED: rlGetPixelDataSize(), correct compressed data size calculation per blocks #5416 2025-12-19 00:06:44 +01:00
Ray
720dd22491 REVIEWED: rlLoadTexture(), un complete texture do to issue on mipmap loading #5416 2025-12-18 17:04:58 +01:00
Ray
ca578b8b08 Update raylib.sln 2025-12-18 17:03:53 +01:00
Ray
4b760091da REVIEWED: Window scaling with HighDPI on macOS #5059 2025-12-17 21:23:25 +01:00
Ray
6d562e5e87 REVIEWED: HiggDPI content scaling on changing monitors with different DPI #5335 #5356
Note that high-dpi awareness must be enabled by users and `CORE.Window.render` reports the scaled framebuffer size, while `CORE.Window.screen` reports the logical size.

`ToggleBorderlessWindow()` has also been reviewed to be consistent with scaling, if monitor physical display size is reported as 1920x1080 but there is a content scale of 1.5, then the borderless fullscreen window will be 1280x720, with the 1920x1080 framebuffer
2025-12-17 19:20:18 +01:00
Ray
7553e9d586 REVIEWED: Gamepads on latest SDL2 2.32.8 and SDL3 3.3.6 #5403 2025-12-16 19:36:01 +01:00
Ray
80ad96acc2 Fix #5413 2025-12-16 18:33:07 +01:00
Ray
7a5e8aa3a5 Update rcore_android.c 2025-12-16 18:30:33 +01:00
1c94e94873 [rcore] Implement FLAG_WINDOW_ALWAYS_RUN on Android (#5414) 2025-12-16 18:26:20 +01:00
33adda1983 fixed build errors with zig. now compatible with zig master 0.16.0-dev.1593+c13857e50. still backwards compatible with 0.15.1 (#5415) 2025-12-16 18:24:53 +01:00
Ray
f031b2f4f4 Alignment with other platform backends, avoid unneeded includes 2025-12-16 18:20:02 +01:00
Ray
1c7240a01d Revert "REVIEWED: Alignment with other platforms"
This reverts commit cf0d6fc664.
2025-12-16 18:18:42 +01:00
Ray
cf0d6fc664 REVIEWED: Alignment with other platforms 2025-12-15 20:44:28 +01:00
Ray
615fc36eeb Fix #5406 2025-12-15 18:56:14 +01:00
Ray
cbe31759ab Fix #5405 2025-12-15 18:52:27 +01:00
d74556d35c Modify text_words_alignment.c (#5411) 2025-12-15 18:49:40 +01:00
8d246fdaff Fix EXTERNAL_CONFIG_FLAGS being defined even when no custom config is used when building with zig (#5410) 2025-12-15 00:03:31 +01:00
Ray
a0fd5ab1d9 Update rmodels.c 2025-12-14 19:59:12 +01:00
Ray
9a337f3b3b ADDED: Support software renderer on Web, blitting framebuffer data directly to a 2d canvas
This improvement is just a prove of concept, at this moment `PLATFORM_WEB` is limited in terms of software rendering by `GLFW` that only allows creating a WebGL canvas context with `glfwCreateWindow()`.

We can skip that call but then some GLFW functionality is not available (windowing, inputs). The best solution is replacing GLFW completely by a pure Emscripten implementation for `PLATFORM_WEB`.
2025-12-14 19:52:18 +01:00
Ray
5025009860 REVIEWED: Make sure all variables are initialized on definition, prioritize one line per variable definitions 2025-12-14 19:45:28 +01:00
6f5cabf60c Fix misleading example text. (#5409) 2025-12-14 17:43:54 +01:00
127 changed files with 8760 additions and 3933 deletions

View File

@ -84,8 +84,10 @@ jobs:
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.RELEASE_NAME }}.tar.gz name: ${{ env.RELEASE_NAME }}
path: ./build/${{ env.RELEASE_NAME }}.tar.gz path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release - name: Upload Artifact to Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1

View File

@ -114,8 +114,10 @@ jobs:
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.RELEASE_NAME }}.tar.gz name: ${{ env.RELEASE_NAME }}
path: ./build/${{ env.RELEASE_NAME }}.tar.gz path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release - name: Upload Artifact to Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1

View File

@ -101,8 +101,10 @@ jobs:
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.RELEASE_NAME }}.tar.gz name: ${{ env.RELEASE_NAME }}
path: ./build/${{ env.RELEASE_NAME }}.tar.gz path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release - name: Upload Artifact to Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1

View File

@ -71,8 +71,10 @@ jobs:
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.RELEASE_NAME }}.zip name: ${{ env.RELEASE_NAME }}
path: ./build/${{ env.RELEASE_NAME }}.zip path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.zip
- name: Upload Artifact to Release - name: Upload Artifact to Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1

View File

@ -142,8 +142,10 @@ jobs:
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.RELEASE_NAME }}.zip name: ${{ env.RELEASE_NAME }}
path: ./build/${{ env.RELEASE_NAME }}.zip path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.zip
- name: Upload Artifact to Release - name: Upload Artifact to Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1

4
.gitignore vendored
View File

@ -58,6 +58,10 @@ packages/
*.h.pch *.h.pch
./*.obj ./*.obj
# Ignore SDL libs for testing
src/external/SDL2
src/external/SDL3
# Emscripten # Emscripten
emsdk emsdk

View File

@ -21,6 +21,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 | | [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
| [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 | | [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 |
| [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 | | [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 |
| [chicken-raylib](https://github.com/meowstr/chicken-raylib) | 5.5 | [CHICKEN Scheme](https://wiki.call-cc.org) | MIT |
| [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT | | [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT |
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 | | [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 |
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT | | [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
@ -28,6 +29,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 | | [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 | | [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib | | [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib |
| [DenoRaylib550](https://github.com/JJLDonley/DenoRaylib550) | **5.5** | [Deno](https://deno.land) | MIT |
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 | | [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 | | [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD | | [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |
@ -76,6 +78,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib | | [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib |
| [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib | | [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib |
| [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** | | [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** |
| [ringraylib5](https://github.com/ring-lang/ring/tree/master/extensions/ringraylib5) | **5.0** | [Ring](https://ring-lang.github.io/) | **???** |
| [racket-raylib](https://github.com/eutro/racket-raylib) | **5.5** | [Racket](https://racket-lang.org) | MIT/Apache-2.0 | | [racket-raylib](https://github.com/eutro/racket-raylib) | **5.5** | [Racket](https://racket-lang.org) | MIT/Apache-2.0 |
| [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT | | [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT |
| [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT | | [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT |

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
This software is provided "as-is", without any express or implied warranty. In no event This software is provided "as-is", without any express or implied warranty. In no event
will the authors be held liable for any damages arising from the use of this software. will the authors be held liable for any damages arising from the use of this software.

View File

@ -140,7 +140,7 @@ contributors
------------ ------------
<a href="https://github.com/raysan5/raylib/graphs/contributors"> <a href="https://github.com/raysan5/raylib/graphs/contributors">
<img src="https://contrib.rocks/image?repo=raysan5/raylib&max=500&columns=20&anon=1" /> <img src="https://contrib.rocks/image?repo=raysan5/raylib&max=800&columns=24&anon=0" />
</a> </a>
license license

View File

@ -15,13 +15,13 @@ _Current version of raylib is complete and functional but there is always room f
**raylib 5.x** **raylib 5.x**
- [ ] `rcore`: Support additional platforms: iOS, consoles? - [ ] `rcore`: Support additional platforms: iOS, consoles?
- [ ] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK - [x] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK
- [ ] `rlgl`: Review GLSL shaders naming conventions for consistency - [ ] `rlgl`: Review GLSL shaders naming conventions for consistency
- [ ] `textures`: Improve compressed textures support, loading and saving - [ ] `textures`: Improve compressed textures support, loading and saving
- [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf) - [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
- [ ] `raudio`: Implement miniaudio high-level provided features - [ ] `raudio`: Implement miniaudio high-level provided features
- [ ] `examples`: Review all examples, add more and better code explanations - [x] `examples`: Review all examples, add more and better code explanations
- [ ] Software renderer backend? Maybe using `Image` provided API - [x] Software renderer backend? Maybe using `Image` provided API
**raylib 4.x** **raylib 4.x**
- [x] Split core module into separate platforms? - [x] Split core module into separate platforms?

18
SECURITY.md Normal file
View File

@ -0,0 +1,18 @@
# Security Policy
## Supported Versions
Most considerations of errors and defects can be handled using the project Issues and/or Discussions.
| Version | Supported |
| ------- | ------------------ |
| 6.0.x | :white_check_mark: |
| < 5.5 | :x: |
## Reporting a Vulnerability
Discovered vulnerability can be directly reported using the project Issues and/or Discussions.
_TODO: Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc._

View File

@ -106,9 +106,9 @@ const config_h_flags = outer: {
if (std.mem.startsWith(u8, line, "//")) continue; if (std.mem.startsWith(u8, line, "//")) continue;
if (std.mem.startsWith(u8, line, "#if")) continue; if (std.mem.startsWith(u8, line, "#if")) continue;
var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace var flag = std.mem.trimStart(u8, line, " \t"); // Trim whitespace
flag = flag["#define ".len - 1 ..]; // Remove #define flag = flag["#define ".len - 1 ..]; // Remove #define
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace flag = std.mem.trimStart(u8, flag, " \t"); // Trim whitespace
flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
flag = "-D" ++ flag; // Prepend with -D flag = "-D" ++ flag; // Prepend with -D
@ -155,9 +155,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
); );
} }
// Sets a flag indicating the use of a custom `config.h`
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
if (options.config.len > 0) { if (options.config.len > 0) {
// Sets a flag indicating the use of a custom `config.h`
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
// Splits a space-separated list of config flags into multiple flags // Splits a space-separated list of config flags into multiple flags
// //
// Note: This means certain flags like `-x c++` won't be processed properly. // Note: This means certain flags like `-x c++` won't be processed properly.
@ -193,11 +193,11 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
// No GLFW required on PLATFORM_DRM // No GLFW required on PLATFORM_DRM
if (options.platform != .drm) { if (options.platform != .drm) {
raylib.addIncludePath(b.path("src/external/glfw/include")); raylib.root_module.addIncludePath(b.path("src/external/glfw/include"));
} }
var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2); var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2);
c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c", "src/utils.c" }); c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c" });
if (options.rshapes) { if (options.rshapes) {
try c_source_files.append(b.allocator, "src/rshapes.c"); try c_source_files.append(b.allocator, "src/rshapes.c");
@ -224,7 +224,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), ""); raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), "");
} }
raylib.addIncludePath(b.path("src/platforms")); raylib.root_module.addIncludePath(b.path("src/platforms"));
switch (target.result.os.tag) { switch (target.result.os.tag) {
.windows => { .windows => {
switch (options.platform) { switch (options.platform) {
@ -348,7 +348,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
} }
}, },
.freebsd, .openbsd, .netbsd, .dragonfly => { .freebsd, .openbsd, .netbsd, .dragonfly => {
try c_source_files.append(b.allocator, "rglfw.c"); try c_source_files.append(b.allocator, "src/rglfw.c");
raylib.root_module.linkSystemLibrary("GL", .{}); raylib.root_module.linkSystemLibrary("GL", .{});
raylib.root_module.linkSystemLibrary("rt", .{}); raylib.root_module.linkSystemLibrary("rt", .{});
raylib.root_module.linkSystemLibrary("dl", .{}); raylib.root_module.linkSystemLibrary("dl", .{});

View File

@ -27,6 +27,12 @@ if (${PLATFORM} MATCHES "Desktop")
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
find_package(OpenGL QUIET) find_package(OpenGL QUIET)
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm) set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm)
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "QNX")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
find_library(GLESV2 GLESv2)
find_library(EGL EGL)
set(LIBS_PUBLIC m)
set(LIBS_PRIVATE ${GLESV2} ${EGL} atomic pthread dl)
elseif (UNIX) elseif (UNIX)
find_library(pthread NAMES pthread) find_library(pthread NAMES pthread)
find_package(OpenGL QUIET) find_package(OpenGL QUIET)

View File

@ -30,7 +30,7 @@
# > PLATFORM_ANDROID: # > PLATFORM_ANDROID:
# - Android (ARM, ARM64) # - Android (ARM, ARM64)
# #
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.
@ -205,15 +205,17 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
endif endif
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
MAKE = mingw32-make ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make
endif
endif endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(OS),Windows_NT) ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make MAKE = mingw32-make
else else
EMMAKE != type emmake EMMAKE := $(shell command -v emmake)
ifneq (, $(EMMAKE)) ifneq (, $(EMMAKE))
MAKE = emmake make MAKE = $(EMMAKE) make
else else
MAKE = mingw32-make MAKE = mingw32-make
endif endif
@ -531,7 +533,7 @@ CORE = \
core/core_delta_time \ core/core_delta_time \
core/core_directory_files \ core/core_directory_files \
core/core_drop_files \ core/core_drop_files \
core/core_high_dpi \ core/core_highdpi_demo \
core/core_highdpi_testbed \ core/core_highdpi_testbed \
core/core_input_actions \ core/core_input_actions \
core/core_input_gamepad \ core/core_input_gamepad \
@ -542,6 +544,7 @@ CORE = \
core/core_input_mouse_wheel \ core/core_input_mouse_wheel \
core/core_input_multitouch \ core/core_input_multitouch \
core/core_input_virtual_controls \ core/core_input_virtual_controls \
core/core_keyboard_testbed \
core/core_monitor_detector \ core/core_monitor_detector \
core/core_random_sequence \ core/core_random_sequence \
core/core_random_values \ core/core_random_values \
@ -575,6 +578,7 @@ SHAPES = \
shapes/shapes_easings_box \ shapes/shapes_easings_box \
shapes/shapes_easings_rectangles \ shapes/shapes_easings_rectangles \
shapes/shapes_following_eyes \ shapes/shapes_following_eyes \
shapes/shapes_hilbert_curve \
shapes/shapes_kaleidoscope \ shapes/shapes_kaleidoscope \
shapes/shapes_lines_bezier \ shapes/shapes_lines_bezier \
shapes/shapes_lines_drawing \ shapes/shapes_lines_drawing \
@ -605,6 +609,7 @@ TEXTURES = \
textures/textures_bunnymark \ textures/textures_bunnymark \
textures/textures_cellular_automata \ textures/textures_cellular_automata \
textures/textures_fog_of_war \ textures/textures_fog_of_war \
textures/textures_framebuffer_rendering \
textures/textures_gif_player \ textures/textures_gif_player \
textures/textures_image_channel \ textures/textures_image_channel \
textures/textures_image_drawing \ textures/textures_image_drawing \

View File

@ -30,7 +30,7 @@
# > PLATFORM_ANDROID: # > PLATFORM_ANDROID:
# - Android (ARM, ARM64) # - Android (ARM, ARM64)
# #
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.
@ -208,12 +208,12 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
MAKE = mingw32-make MAKE = mingw32-make
endif endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(OS),Windows_NT) ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make MAKE = mingw32-make
else else
EMMAKE != type emmake EMMAKE := $(shell command -v emmake)
ifneq (, $(EMMAKE)) ifneq (, $(EMMAKE))
MAKE = emmake make MAKE = $(EMMAKE) make
else else
MAKE = mingw32-make MAKE = mingw32-make
endif endif
@ -519,7 +519,7 @@ CORE = \
core/core_delta_time \ core/core_delta_time \
core/core_directory_files \ core/core_directory_files \
core/core_drop_files \ core/core_drop_files \
core/core_high_dpi \ core/core_highdpi_demo \
core/core_highdpi_testbed \ core/core_highdpi_testbed \
core/core_input_actions \ core/core_input_actions \
core/core_input_gamepad \ core/core_input_gamepad \
@ -530,6 +530,7 @@ CORE = \
core/core_input_mouse_wheel \ core/core_input_mouse_wheel \
core/core_input_multitouch \ core/core_input_multitouch \
core/core_input_virtual_controls \ core/core_input_virtual_controls \
core/core_keyboard_testbed \
core/core_monitor_detector \ core/core_monitor_detector \
core/core_random_sequence \ core/core_random_sequence \
core/core_random_values \ core/core_random_values \
@ -563,6 +564,7 @@ SHAPES = \
shapes/shapes_easings_box \ shapes/shapes_easings_box \
shapes/shapes_easings_rectangles \ shapes/shapes_easings_rectangles \
shapes/shapes_following_eyes \ shapes/shapes_following_eyes \
shapes/shapes_hilbert_curve \
shapes/shapes_kaleidoscope \ shapes/shapes_kaleidoscope \
shapes/shapes_lines_bezier \ shapes/shapes_lines_bezier \
shapes/shapes_lines_drawing \ shapes/shapes_lines_drawing \
@ -593,6 +595,7 @@ TEXTURES = \
textures/textures_bunnymark \ textures/textures_bunnymark \
textures/textures_cellular_automata \ textures/textures_cellular_automata \
textures/textures_fog_of_war \ textures/textures_fog_of_war \
textures/textures_framebuffer_rendering \
textures/textures_gif_player \ textures/textures_gif_player \
textures/textures_image_channel \ textures/textures_image_channel \
textures/textures_image_drawing \ textures/textures_image_drawing \
@ -783,7 +786,7 @@ core/core_directory_files: core/core_directory_files.c
core/core_drop_files: core/core_drop_files.c core/core_drop_files: core/core_drop_files.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_high_dpi: core/core_high_dpi.c core/core_highdpi_demo: core/core_highdpi_demo.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_highdpi_testbed: core/core_highdpi_testbed.c core/core_highdpi_testbed: core/core_highdpi_testbed.c
@ -818,6 +821,9 @@ core/core_input_multitouch: core/core_input_multitouch.c
core/core_input_virtual_controls: core/core_input_virtual_controls.c core/core_input_virtual_controls: core/core_input_virtual_controls.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_keyboard_testbed: core/core_keyboard_testbed.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_monitor_detector: core/core_monitor_detector.c core/core_monitor_detector: core/core_monitor_detector.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -914,6 +920,9 @@ shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_hilbert_curve: shapes/shapes_hilbert_curve.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -1005,6 +1014,9 @@ textures/textures_cellular_automata: textures/textures_cellular_automata.c
textures/textures_fog_of_war: textures/textures_fog_of_war.c textures/textures_fog_of_war: textures/textures_fog_of_war.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_framebuffer_rendering: textures/textures_framebuffer_rendering.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_gif_player: textures/textures_gif_player.c textures/textures_gif_player: textures/textures_gif_player.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif --preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif
@ -1367,15 +1379,15 @@ shaders/shaders_fog_rendering: shaders/shaders_fog_rendering.c
shaders/shaders_game_of_life: shaders/shaders_game_of_life.c shaders/shaders_game_of_life: shaders/shaders_game_of_life.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/shaders/glsl100/game_of_life.fs@resources/shaders/glsl100/game_of_life.fs \ --preload-file shaders/resources/shaders/glsl100/game_of_life.fs@resources/shaders/glsl100/game_of_life.fs \
--preload-file shaders/resources/game_of_life/acorn.png@resources/game_of_life/acorn.png \ --preload-file shaders/resources/game_of_life/r_pentomino.png@resources/game_of_life/r_pentomino.png \
--preload-file shaders/resources/game_of_life/breeder.png@resources/game_of_life/breeder.png \
--preload-file shaders/resources/game_of_life/glider.png@resources/game_of_life/glider.png \ --preload-file shaders/resources/game_of_life/glider.png@resources/game_of_life/glider.png \
--preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \ --preload-file shaders/resources/game_of_life/acorn.png@resources/game_of_life/acorn.png \
--preload-file shaders/resources/game_of_life/spaceships.png@resources/game_of_life/spaceships.png \
--preload-file shaders/resources/game_of_life/still_lifes.png@resources/game_of_life/still_lifes.png \
--preload-file shaders/resources/game_of_life/oscillators.png@resources/game_of_life/oscillators.png \ --preload-file shaders/resources/game_of_life/oscillators.png@resources/game_of_life/oscillators.png \
--preload-file shaders/resources/game_of_life/puffer_train.png@resources/game_of_life/puffer_train.png \ --preload-file shaders/resources/game_of_life/puffer_train.png@resources/game_of_life/puffer_train.png \
--preload-file shaders/resources/game_of_life/r_pentomino.png@resources/game_of_life/r_pentomino.png \ --preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \
--preload-file shaders/resources/game_of_life/spaceships.png@resources/game_of_life/spaceships.png \ --preload-file shaders/resources/game_of_life/breeder.png@resources/game_of_life/breeder.png
--preload-file shaders/resources/game_of_life/still_lifes.png@resources/game_of_life/still_lifes.png
shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \

View File

@ -17,9 +17,9 @@ You may find it easier to use than other toolchains, especially when it comes to
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`) - `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`) - `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
## EXAMPLES COLLECTION [TOTAL: 205] ## EXAMPLES COLLECTION [TOTAL: 208]
### category: core [47] ### category: core [48]
Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality. Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality.
@ -61,7 +61,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
| [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) | | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) |
| [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐☆☆☆ | 5.0 | 5.0 | [Dalton Overmyer](https://github.com/REDl3east) | | [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐☆☆☆ | 5.0 | 5.0 | [Dalton Overmyer](https://github.com/REDl3east) |
| [core_automation_events](core/core_automation_events.c) | <img src="core/core_automation_events.png" alt="core_automation_events" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) | | [core_automation_events](core/core_automation_events.c) | <img src="core/core_automation_events.png" alt="core_automation_events" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_high_dpi](core/core_high_dpi.c) | <img src="core/core_high_dpi.png" alt="core_high_dpi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) | | [core_highdpi_demo](core/core_highdpi_demo.c) | <img src="core/core_highdpi_demo.png" alt="core_highdpi_demo" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) |
| [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_undo_redo](core/core_undo_redo.c) | <img src="core/core_undo_redo.png" alt="core_undo_redo" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) | | [core_undo_redo](core/core_undo_redo.c) | <img src="core/core_undo_redo.png" alt="core_undo_redo" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_viewport_scaling](core/core_viewport_scaling.c) | <img src="core/core_viewport_scaling.png" alt="core_viewport_scaling" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) | | [core_viewport_scaling](core/core_viewport_scaling.c) | <img src="core/core_viewport_scaling.png" alt="core_viewport_scaling" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
@ -69,11 +69,12 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
| [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) | | [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
| [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) | | [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) |
| [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) | | [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_keyboard_testbed](core/core_keyboard_testbed.c) | <img src="core/core_keyboard_testbed.png" alt="core_keyboard_testbed" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
### category: shapes [38] ### category: shapes [39]
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
@ -117,8 +118,9 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) | | [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) | | [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) | | [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | <img src="shapes/shapes_hilbert_curve.png" alt="shapes_hilbert_curve" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
### category: textures [29] ### category: textures [30]
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module. Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
@ -153,6 +155,7 @@ Examples using raylib textures functionality, including image/textures loading/g
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) | | [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) | | [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) |
| [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | | [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
| [textures_framebuffer_rendering](textures/textures_framebuffer_rendering.c) | <img src="textures/textures_framebuffer_rendering.png" alt="textures_framebuffer_rendering" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jack Boakes](https://github.com/jackboakes) |
### category: text [16] ### category: text [16]

View File

@ -113,7 +113,7 @@ int main(void)
DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE); DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE);
DrawRectangle(300, 100, 200, 12, LIGHTGRAY); DrawRectangle(300, 100, 200, 12, LIGHTGRAY);
DrawRectangleLines(300, 100, 200, 12, GRAY); DrawRectangleLines(300, 100, 200, 12, GRAY);
DrawRectangle(300 + (pan + 1.0)/2.0f*200 - 5, 92, 10, 28, DARKGRAY); DrawRectangle((int)(300 + (pan + 1.0f)/2.0f*200 - 5), 92, 10, 28, DARKGRAY);
DrawRectangle(200, 200, 400, 12, LIGHTGRAY); DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON); DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON);
@ -125,7 +125,7 @@ int main(void)
DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN); DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN);
DrawRectangle(300, 360, 200, 12, LIGHTGRAY); DrawRectangle(300, 360, 200, 12, LIGHTGRAY);
DrawRectangleLines(300, 360, 200, 12, GRAY); DrawRectangleLines(300, 360, 200, 12, GRAY);
DrawRectangle(300 + volume*200 - 5, 352, 10, 28, DARKGRAY); DrawRectangle((int)(300 + volume*200 - 5), 352, 10, 28, DARKGRAY);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -115,7 +115,7 @@ int main(void)
.tapbackPos = 0.01f .tapbackPos = 0.01f
}; };
size_t wavCursor = 0; int wavCursor = 0;
const short *wavPCM16 = wav.data; const short *wavPCM16 = wav.data;
short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 }; short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -125,8 +125,8 @@ int main(void)
DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f)); DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f));
DrawRectangleLines( 10, 10, 250, 113, BLUE); DrawRectangleLines( 10, 10, 250, 113, BLUE);
DrawText("Free 2d camera controls:", 20, 20, 10, BLACK); DrawText("Free 2D camera controls:", 20, 20, 10, BLACK);
DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY); DrawText("- Right/Left to move player", 40, 40, 10, DARKGRAY);
DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY); DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY);
DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY); DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY);
DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY); DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -226,10 +226,10 @@ void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envI
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera); Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera);
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera); Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera);
if (max.x < width) camera->offset.x = width - (max.x - width/2); if (max.x < width) camera->offset.x = width - (max.x - (float)width/2);
if (max.y < height) camera->offset.y = height - (max.y - height/2); if (max.y < height) camera->offset.y = height - (max.y - (float)height/2);
if (min.x > 0) camera->offset.x = width/2 - min.x; if (min.x > 0) camera->offset.x = (float)width/2 - min.x;
if (min.y > 0) camera->offset.y = height/2 - min.y; if (min.y > 0) camera->offset.y = (float)height/2 - min.y;
} }
void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height) void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)

View File

@ -225,10 +225,10 @@ int main(void)
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera); Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera);
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera); Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera);
if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - screenWidth/2); if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - (float)screenWidth/2);
if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - screenHeight/2); if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - (float)screenHeight/2);
if (min.x > 0) camera.offset.x = screenWidth/2 - min.x; if (min.x > 0) camera.offset.x = (float)screenWidth/2 - min.x;
if (min.y > 0) camera.offset.y = screenHeight/2 - min.y; if (min.y > 0) camera.offset.y = (float)screenHeight/2 - min.y;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Events management // Events management

View File

@ -1,6 +1,6 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - high dpi * raylib [core] example - highdpi demo
* *
* Example complexity rating: [] 2/4 * Example complexity rating: [] 2/4
* *
@ -33,7 +33,7 @@ int main(void)
const int screenHeight = 450; const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE); SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
InitWindow(screenWidth, screenHeight, "raylib [core] example - high dpi"); InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi demo");
SetWindowMinSize(450, 450); SetWindowMinSize(450, 450);
int logicalGridDescY = 120; int logicalGridDescY = 120;

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -27,9 +27,14 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE); SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed"); InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
Vector2 scaleDpi = GetWindowScaleDPI();
Vector2 mousePos = GetMousePosition();
int currentMonitor = GetCurrentMonitor();
Vector2 windowPos = GetWindowPosition();
int gridSpacing = 40; // Grid spacing in pixels int gridSpacing = 40; // Grid spacing in pixels
SetTargetFPS(60); SetTargetFPS(60);
@ -40,7 +45,13 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// TODO: Update variables / Implement example logic at this point mousePos = GetMousePosition();
currentMonitor = GetCurrentMonitor();
scaleDpi = GetWindowScaleDPI();
windowPos = GetWindowPosition();
if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed();
if (IsKeyPressed(KEY_F)) ToggleFullscreen();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -50,11 +61,35 @@ int main(void)
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
// Draw grid // Draw grid
for (int h = 0; h < 20; h++) DrawLine(0, h*gridSpacing, GetRenderWidth(), h*gridSpacing, LIGHTGRAY); for (int h = 0; h < GetScreenHeight()/gridSpacing + 1; h++)
for (int v = 0; v < 40; v++) DrawLine(v*gridSpacing, 0, v*gridSpacing, GetScreenHeight(), LIGHTGRAY); {
DrawText(TextFormat("%02i", h*gridSpacing), 4, h*gridSpacing - 4, 10, GRAY);
DrawLine(24, h*gridSpacing, GetScreenWidth(), h*gridSpacing, LIGHTGRAY);
}
for (int v = 0; v < GetScreenWidth()/gridSpacing + 1; v++)
{
DrawText(TextFormat("%02i", v*gridSpacing), v*gridSpacing - 10, 4, 10, GRAY);
DrawLine(v*gridSpacing, 20, v*gridSpacing, GetScreenHeight(), LIGHTGRAY);
}
// Draw UI info // Draw UI info
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 10, 10, 20, BLACK); DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY);
DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY);
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);
DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 170, 20, DARKGRAY);
DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY);
// Draw reference rectangles, top-left and bottom-right corners
DrawRectangle(0, 0, 30, 60, RED);
DrawRectangle(GetScreenWidth() - 30, GetScreenHeight() - 60, 30, 60, BLUE);
// Draw mouse position
DrawCircleV(GetMousePosition(), 20, MAROON);
DrawRectangle(mousePos.x - 25, mousePos.y, 50, 2, BLACK);
DrawRectangle(mousePos.x, mousePos.y - 25, 2, 50, BLACK);
DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), mousePos.x - 44,
(mousePos.y > GetScreenHeight() - 60)? mousePos.y - 46 : mousePos.y + 30, 20, BLACK);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -67,7 +67,7 @@ int main(void)
if (IsKeyPressed(KEY_RIGHT)) gamepad++; if (IsKeyPressed(KEY_RIGHT)) gamepad++;
Vector2 mousePosition = GetMousePosition(); Vector2 mousePosition = GetMousePosition();
vibrateButton = (Rectangle){ 10, 70 + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 }; vibrateButton = (Rectangle){ 10, 70.0f + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 };
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0); if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -262,7 +262,7 @@ int main(void)
// Draw vibrate button // Draw vibrate button
DrawRectangleRec(vibrateButton, SKYBLUE); DrawRectangleRec(vibrateButton, SKYBLUE);
DrawText("VIBRATE", vibrateButton.x + 14, vibrateButton.y + 1, 10, DARKGRAY); DrawText("VIBRATE", (int)(vibrateButton.x + 14), (int)(vibrateButton.y + 1), 10, DARKGRAY);
if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED); if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED);
else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY); else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY);

View File

@ -0,0 +1,333 @@
/*******************************************************************************************
*
* raylib [core] example - keyboard testbed
*
* Example complexity rating: [★★☆☆] 2/4
*
* NOTE: raylib defined keys refer to ENG-US Keyboard layout,
* mapping to other layouts is up to the user
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2026 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define KEY_REC_SPACING 4 // Space in pixels between key rectangles
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static const char *GetKeyText(int key);
static void GuiKeyboardKey(Rectangle bounds, int key);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard testbed");
SetExitKey(KEY_NULL); // Avoid exit on KEY_ESCAPE
// Keyboard line 01
int line01KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45;
line01KeyWidths[13] = 62; // PRINTSCREEN
int line01Keys[15] = {
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
};
// Keyboard line 02
int line02KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45;
line02KeyWidths[0] = 25; // GRAVE
line02KeyWidths[13] = 82; // BACKSPACE
int line02Keys[15] = {
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE };
// Keyboard line 03
int line03KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line03KeyWidths[i] = 45;
line03KeyWidths[0] = 50; // TAB
line03KeyWidths[13] = 57; // BACKSLASH
int line03Keys[15] = {
KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y,
KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFT_BRACKET,
KEY_RIGHT_BRACKET, KEY_BACKSLASH, KEY_INSERT
};
// Keyboard line 04
int line04KeyWidths[14] = { 0 };
for (int i = 0; i < 14; i++) line04KeyWidths[i] = 45;
line04KeyWidths[0] = 68; // CAPS
line04KeyWidths[12] = 88; // ENTER
int line04Keys[14] = {
KEY_CAPS_LOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G,
KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
KEY_APOSTROPHE, KEY_ENTER, KEY_PAGE_UP
};
// Keyboard line 05
int line05KeyWidths[14] = { 0 };
for (int i = 0; i < 14; i++) line05KeyWidths[i] = 45;
line05KeyWidths[0] = 80; // LSHIFT
line05KeyWidths[11] = 76; // RSHIFT
int line05Keys[14] = {
KEY_LEFT_SHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B,
KEY_N, KEY_M, KEY_COMMA, KEY_PERIOD, /*KEY_MINUS*/
KEY_SLASH, KEY_RIGHT_SHIFT, KEY_UP, KEY_PAGE_DOWN
};
// Keyboard line 06
int line06KeyWidths[11] = { 0 };
for (int i = 0; i < 11; i++) line06KeyWidths[i] = 45;
line06KeyWidths[0] = 80; // LCTRL
line06KeyWidths[3] = 208; // SPACE
line06KeyWidths[7] = 60; // RCTRL
int line06Keys[11] = {
KEY_LEFT_CONTROL, KEY_LEFT_SUPER, KEY_LEFT_ALT,
KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL,
KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT
};
Vector2 keyboardOffset = { 26, 80 };
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
int key = GetKeyPressed(); // Get pressed keycode
if (key > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: KEY PRESSED: %d", key);
int ch = GetCharPressed(); // Get pressed char for text input, using OS mapping
if (ch > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: CHAR PRESSED: %c (%d)", ch, ch);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY);
// Keyboard line 01 - 15 keys
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, line01KeyWidths[i], 30 }, line01Keys[i]);
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 02 - 15 keys
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, line02KeyWidths[i], 38 }, line02Keys[i]);
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 03 - 15 keys
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38 + KEY_REC_SPACING*2, line03KeyWidths[i], 38 }, line03Keys[i]);
recOffsetX += line03KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 04 - 14 keys
// MAYUS, A, S, D, F, G, H, J, K, L, ;, ', ENTER, REPAG
for (int i = 0, recOffsetX = 0; i < 14; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*2 + KEY_REC_SPACING*3, line04KeyWidths[i], 38 }, line04Keys[i]);
recOffsetX += line04KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 05 - 14 keys
// LSHIFT, Z, X, C, V, B, N, M, ,, ., /, RSHIFT, UP, AVPAG
for (int i = 0, recOffsetX = 0; i < 14; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*3 + KEY_REC_SPACING*4, line05KeyWidths[i], 38 }, line05Keys[i]);
recOffsetX += line05KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 06 - 11 keys
// LCTRL, WIN, LALT, SPACE, ALTGR, \, FN, RCTRL, LEFT, DOWN, RIGHT
for (int i = 0, recOffsetX = 0; i < 11; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*4 + KEY_REC_SPACING*5, line06KeyWidths[i], 38 }, line06Keys[i]);
recOffsetX += line06KeyWidths[i] + KEY_REC_SPACING;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
// Get keyboard keycode as text (US keyboard)
// NOTE: Mapping for other keyboard layouts can be done here
static const char *GetKeyText(int key)
{
switch (key)
{
case KEY_APOSTROPHE : return "'"; // Key: '
case KEY_COMMA : return ","; // Key: ,
case KEY_MINUS : return "-"; // Key: -
case KEY_PERIOD : return "."; // Key: .
case KEY_SLASH : return "/"; // Key: /
case KEY_ZERO : return "0"; // Key: 0
case KEY_ONE : return "1"; // Key: 1
case KEY_TWO : return "2"; // Key: 2
case KEY_THREE : return "3"; // Key: 3
case KEY_FOUR : return "4"; // Key: 4
case KEY_FIVE : return "5"; // Key: 5
case KEY_SIX : return "6"; // Key: 6
case KEY_SEVEN : return "7"; // Key: 7
case KEY_EIGHT : return "8"; // Key: 8
case KEY_NINE : return "9"; // Key: 9
case KEY_SEMICOLON : return ";"; // Key: ;
case KEY_EQUAL : return "="; // Key: =
case KEY_A : return "A"; // Key: A | a
case KEY_B : return "B"; // Key: B | b
case KEY_C : return "C"; // Key: C | c
case KEY_D : return "D"; // Key: D | d
case KEY_E : return "E"; // Key: E | e
case KEY_F : return "F"; // Key: F | f
case KEY_G : return "G"; // Key: G | g
case KEY_H : return "H"; // Key: H | h
case KEY_I : return "I"; // Key: I | i
case KEY_J : return "J"; // Key: J | j
case KEY_K : return "K"; // Key: K | k
case KEY_L : return "L"; // Key: L | l
case KEY_M : return "M"; // Key: M | m
case KEY_N : return "N"; // Key: N | n
case KEY_O : return "O"; // Key: O | o
case KEY_P : return "P"; // Key: P | p
case KEY_Q : return "Q"; // Key: Q | q
case KEY_R : return "R"; // Key: R | r
case KEY_S : return "S"; // Key: S | s
case KEY_T : return "T"; // Key: T | t
case KEY_U : return "U"; // Key: U | u
case KEY_V : return "V"; // Key: V | v
case KEY_W : return "W"; // Key: W | w
case KEY_X : return "X"; // Key: X | x
case KEY_Y : return "Y"; // Key: Y | y
case KEY_Z : return "Z"; // Key: Z | z
case KEY_LEFT_BRACKET : return "["; // Key: [
case KEY_BACKSLASH : return "\\"; // Key: '\'
case KEY_RIGHT_BRACKET : return "]"; // Key: ]
case KEY_GRAVE : return "`"; // Key: `
case KEY_SPACE : return "SPACE"; // Key: Space
case KEY_ESCAPE : return "ESC"; // Key: Esc
case KEY_ENTER : return "ENTER"; // Key: Enter
case KEY_TAB : return "TAB"; // Key: Tab
case KEY_BACKSPACE : return "BACK"; // Key: Backspace
case KEY_INSERT : return "INS"; // Key: Ins
case KEY_DELETE : return "DEL"; // Key: Del
case KEY_RIGHT : return "RIGHT"; // Key: Cursor right
case KEY_LEFT : return "LEFT"; // Key: Cursor left
case KEY_DOWN : return "DOWN"; // Key: Cursor down
case KEY_UP : return "UP"; // Key: Cursor up
case KEY_PAGE_UP : return "PGUP"; // Key: Page up
case KEY_PAGE_DOWN : return "PGDOWN"; // Key: Page down
case KEY_HOME : return "HOME"; // Key: Home
case KEY_END : return "END"; // Key: End
case KEY_CAPS_LOCK : return "CAPS"; // Key: Caps lock
case KEY_SCROLL_LOCK : return "LOCK"; // Key: Scroll down
case KEY_NUM_LOCK : return "NUMLOCK"; // Key: Num lock
case KEY_PRINT_SCREEN : return "PRINTSCR"; // Key: Print screen
case KEY_PAUSE : return "PAUSE"; // Key: Pause
case KEY_F1 : return "F1"; // Key: F1
case KEY_F2 : return "F2"; // Key: F2
case KEY_F3 : return "F3"; // Key: F3
case KEY_F4 : return "F4"; // Key: F4
case KEY_F5 : return "F5"; // Key: F5
case KEY_F6 : return "F6"; // Key: F6
case KEY_F7 : return "F7"; // Key: F7
case KEY_F8 : return "F8"; // Key: F8
case KEY_F9 : return "F9"; // Key: F9
case KEY_F10 : return "F10"; // Key: F10
case KEY_F11 : return "F11"; // Key: F11
case KEY_F12 : return "F12"; // Key: F12
case KEY_LEFT_SHIFT : return "LSHIFT"; // Key: Shift left
case KEY_LEFT_CONTROL : return "LCTRL"; // Key: Control left
case KEY_LEFT_ALT : return "LALT"; // Key: Alt left
case KEY_LEFT_SUPER : return "WIN"; // Key: Super left
case KEY_RIGHT_SHIFT : return "RSHIFT"; // Key: Shift right
case KEY_RIGHT_CONTROL : return "RCTRL"; // Key: Control right
case KEY_RIGHT_ALT : return "ALTGR"; // Key: Alt right
case KEY_RIGHT_SUPER : return "RSUPER"; // Key: Super right
case KEY_KB_MENU : return "KBMENU"; // Key: KB menu
case KEY_KP_0 : return "KP0"; // Key: Keypad 0
case KEY_KP_1 : return "KP1"; // Key: Keypad 1
case KEY_KP_2 : return "KP2"; // Key: Keypad 2
case KEY_KP_3 : return "KP3"; // Key: Keypad 3
case KEY_KP_4 : return "KP4"; // Key: Keypad 4
case KEY_KP_5 : return "KP5"; // Key: Keypad 5
case KEY_KP_6 : return "KP6"; // Key: Keypad 6
case KEY_KP_7 : return "KP7"; // Key: Keypad 7
case KEY_KP_8 : return "KP8"; // Key: Keypad 8
case KEY_KP_9 : return "KP9"; // Key: Keypad 9
case KEY_KP_DECIMAL : return "KPDEC"; // Key: Keypad .
case KEY_KP_DIVIDE : return "KPDIV"; // Key: Keypad /
case KEY_KP_MULTIPLY : return "KPMUL"; // Key: Keypad *
case KEY_KP_SUBTRACT : return "KPSUB"; // Key: Keypad -
case KEY_KP_ADD : return "KPADD"; // Key: Keypad +
case KEY_KP_ENTER : return "KPENTER"; // Key: Keypad Enter
case KEY_KP_EQUAL : return "KPEQU"; // Key: Keypad =
default: return "";
}
}
// Draw keyboard key
static void GuiKeyboardKey(Rectangle bounds, int key)
{
if (key == KEY_NULL) DrawRectangleLinesEx(bounds, 2.0f, LIGHTGRAY);
else
{
if (IsKeyDown(key))
{
DrawRectangleLinesEx(bounds, 2.0f, MAROON);
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, MAROON);
}
else
{
DrawRectangleLinesEx(bounds, 2.0f, DARKGRAY);
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, DARKGRAY);
}
}
if (CheckCollisionPointRec(GetMousePosition(), bounds))
{
DrawRectangleRec(bounds, Fade(RED, 0.2f));
DrawRectangleLinesEx(bounds, 3.0f, RED);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -112,16 +112,16 @@ int main(void)
if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed) if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed)
{ {
resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT; resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT;
gameWidth = resolutionList[resolutionIndex].x; gameWidth = (int)resolutionList[resolutionIndex].x;
gameHeight = resolutionList[resolutionIndex].y; gameHeight = (int)resolutionList[resolutionIndex].y;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
} }
if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed) if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed)
{ {
resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT; resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT;
gameWidth = resolutionList[resolutionIndex].x; gameWidth = (int)resolutionList[resolutionIndex].x;
gameHeight = resolutionList[resolutionIndex].y; gameHeight = (int)resolutionList[resolutionIndex].y;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
} }
@ -145,7 +145,7 @@ int main(void)
// Draw our scene to the render texture // Draw our scene to the render texture
BeginTextureMode(target); BeginTextureMode(target);
ClearBackground(WHITE); ClearBackground(WHITE);
DrawCircle(textureMousePosition.x, textureMousePosition.y, 20.0f, LIME); DrawCircleV(textureMousePosition, 20.0f, LIME);
EndTextureMode(); EndTextureMode();
// Draw render texture to main framebuffer // Draw render texture to main framebuffer
@ -159,7 +159,7 @@ int main(void)
// Draw info box // Draw info box
Rectangle infoRect = (Rectangle){5, 5, 330, 105}; Rectangle infoRect = (Rectangle){5, 5, 330, 105};
DrawRectangleRec(infoRect, Fade(LIGHTGRAY, 0.7f)); DrawRectangleRec(infoRect, Fade(LIGHTGRAY, 0.7f));
DrawRectangleLines(infoRect.x, infoRect.y, infoRect.width, infoRect.height, BLUE); DrawRectangleLinesEx(infoRect, 1, BLUE);
DrawText(TextFormat("Window Resolution: %d x %d", screenWidth, screenHeight), 15, 15, 10, BLACK); DrawText(TextFormat("Window Resolution: %d x %d", screenWidth, screenHeight), 15, 15, 10, BLACK);
DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK); DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK);
@ -216,7 +216,7 @@ static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gam
static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
{ {
const float resizeRatio = (float)(screenHeight/gameHeight); const float resizeRatio = (float)screenHeight/gameHeight;
sourceRect->x = 0.0f; sourceRect->x = 0.0f;
sourceRect->y = 0.0f; sourceRect->y = 0.0f;
sourceRect->width = (float)(int)(screenWidth/resizeRatio); sourceRect->width = (float)(int)(screenWidth/resizeRatio);
@ -230,7 +230,7 @@ static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gam
static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
{ {
const float resizeRatio = (float)(screenWidth/gameWidth); const float resizeRatio = (float)screenWidth/gameWidth;
sourceRect->x = 0.0f; sourceRect->x = 0.0f;
sourceRect->y = 0.0f; sourceRect->y = 0.0f;
sourceRect->width = (float)gameWidth; sourceRect->width = (float)gameWidth;

View File

@ -413,7 +413,7 @@ static MsfGifBuffer * msf_compress_frame(void * allocContext, int width, int hei
//generate palette //generate palette
typedef struct { uint8_t r, g, b; } Color3; typedef struct { uint8_t r, g, b; } Color3;
Color3 table[256] = { {0} }; Color3 table[256] = { { 0 } };
int tableIdx = 1; //we start counting at 1 because 0 is the transparent color int tableIdx = 1; //we start counting at 1 because 0 is the transparent color
//transparent is always last in the table //transparent is always last in the table
tlb[tlbSize-1] = 0; tlb[tlbSize-1] = 0;
@ -550,7 +550,7 @@ static void msf_free_gif_state(MsfGifState * handle) {
int msf_gif_begin(MsfGifState * handle, int width, int height) { MsfTimeFunc int msf_gif_begin(MsfGifState * handle, int width, int height) { MsfTimeFunc
//NOTE: we cannot stomp the entire struct to zero because we must preserve `customAllocatorContext`. //NOTE: we cannot stomp the entire struct to zero because we must preserve `customAllocatorContext`.
MsfCookedFrame empty = {0}; //god I hate MSVC... MsfCookedFrame empty = { 0 }; //god I hate MSVC...
handle->previousFrame = empty; handle->previousFrame = empty;
handle->currentFrame = empty; handle->currentFrame = empty;
handle->width = width; handle->width = width;
@ -614,7 +614,7 @@ int msf_gif_frame(MsfGifState * handle, uint8_t * pixelData, int centiSecondsPer
} }
MsfGifResult msf_gif_end(MsfGifState * handle) { MsfTimeFunc MsfGifResult msf_gif_end(MsfGifState * handle) { MsfTimeFunc
if (!handle->listHead) { MsfGifResult empty = {0}; return empty; } if (!handle->listHead) { MsfGifResult empty = { 0 }; return empty; }
//first pass: determine total size //first pass: determine total size
size_t total = 1; //1 byte for trailing marker size_t total = 1; //1 byte for trailing marker

View File

@ -1,11 +1,13 @@
# #
# raylib examples list used to generate/update collection # raylib examples list with available .c example files
# examples must be provided as: <example_category>;<example_name>;<example_stars>;<raylib_created_version>;<raylib_last_update_version>;<year_created>;<year_reviewed>;"<example_author_name>";<author_github_user> #
# WARNING: List is not ordered by example name but by the display order on web,
# so it can not be automatically generated scanning available .c code files, only updated
# new examples are added at the end of each category; it's up to the user to reorder them as desired
#
# examples data is listed as: <example_category>;<example_name>;<example_stars>;<raylib_created_version>;<raylib_last_update_version>;<year_created>;<year_reviewed>;"<example_author_name>";<author_github_user>
# #
# This list is used as the main reference by [rexm] tool for examples collection validation and management # This list is used as the main reference by [rexm] tool for examples collection validation and management
# New examples must be added to this list and any possible rename must be made on this list first
#
# WARNING: List is not ordered by example name but by the display order on web
# #
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5 core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary
@ -43,7 +45,7 @@ core;core_custom_frame_control;★★★★;4.0;4.0;2021;2025;"Ramon Santamaria"
core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessandroni";@NotManyIdeasDev core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessandroni";@NotManyIdeasDev
core;core_random_sequence;★☆☆☆;5.0;5.0;2023;2025;"Dalton Overmyer";@REDl3east core;core_random_sequence;★☆☆☆;5.0;5.0;2023;2025;"Dalton Overmyer";@REDl3east
core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5 core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
core;core_high_dpi;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997 core;core_highdpi_demo;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5 core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
@ -54,6 +56,7 @@ core;core_screen_recording;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santama
core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839 core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04 core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5 shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5 shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower
@ -92,6 +95,7 @@ shapes;shapes_rlgl_color_wheel;★★★☆;5.6-dev;5.6-dev;2025;2025;"Robin";@R
shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5 textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5 textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
@ -121,6 +125,7 @@ textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";
textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501 textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501
textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary
textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
textures;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes
text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5 text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5
text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5 text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5

View File

@ -45,7 +45,7 @@ static void FreeMeshBuilder(MeshBuilder *mb);
static Mesh BuildMesh(MeshBuilder *mb); static Mesh BuildMesh(MeshBuilder *mb);
static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset); static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset);
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s);
#define FreeDecalMeshData() GenMeshDecal((Model){ .meshCount = -1.0f }, (Matrix){ 0 }, 0.0f, 0.0f) static void FreeDecalMeshData(void) { GenMeshDecal((Model){ .meshCount = -1 }, (Matrix){ 0 }, 0.0f, 0.0f); }
static bool GuiButton(Rectangle rec, const char *label); static bool GuiButton(Rectangle rec, const char *label);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -183,7 +183,7 @@ int main(void)
if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE); if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
// Draw the decal models // Draw the decal models
for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){0}, 1.0f, WHITE); for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){ 0 }, 1.0f, WHITE);
// If we hit the mesh, draw the box for the decal // If we hit the mesh, draw the box for the decal
if (collision.hit) if (collision.hit)
@ -191,19 +191,19 @@ int main(void)
Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f)); Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f));
Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0}); Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0});
placementCube.transform = MatrixInvert(splat); placementCube.transform = MatrixInvert(splat);
DrawModel(placementCube, (Vector3){0}, 1.0f, Fade(WHITE, 0.5f)); DrawModel(placementCube, (Vector3){ 0 }, 1.0f, Fade(WHITE, 0.5f));
} }
DrawGrid(10, 10.0f); DrawGrid(10, 10.0f);
EndMode3D(); EndMode3D();
float yPos = 10; float yPos = 10;
float x0 = GetScreenWidth() - 300; float x0 = GetScreenWidth() - 300.0f;
float x1 = x0 + 100; float x1 = x0 + 100;
float x2 = x1 + 100; float x2 = x1 + 100;
DrawText("Vertices", x1, yPos, 10, LIME); DrawText("Vertices", (int)x1, (int)yPos, 10, LIME);
DrawText("Triangles", x2, yPos, 10, LIME); DrawText("Triangles", (int)x2, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
int vertexCount = 0; int vertexCount = 0;
@ -215,24 +215,24 @@ int main(void)
triangleCount += model.meshes[i].triangleCount; triangleCount += model.meshes[i].triangleCount;
} }
DrawText("Main model", x0, yPos, 10, LIME); DrawText("Main model", (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME); DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
for (int i = 0; i < decalCount; i++) for (int i = 0; i < decalCount; i++)
{ {
if (i == 20) if (i == 20)
{ {
DrawText("...", x0, yPos, 10, LIME); DrawText("...", (int)x0, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
} }
if (i < 20) if (i < 20)
{ {
DrawText(TextFormat("Decal #%d", i+1), x0, yPos, 10, LIME); DrawText(TextFormat("Decal #%d", i+1), (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), x1, yPos, 10, LIME); DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), x2, yPos, 10, LIME); DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
} }
@ -240,18 +240,18 @@ int main(void)
triangleCount += decalModels[i].meshes[0].triangleCount; triangleCount += decalModels[i].meshes[0].triangleCount;
} }
DrawText("TOTAL", x0, yPos, 10, LIME); DrawText("TOTAL", (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME); DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
DrawText("Hold RMB to move camera", 10, 430, 10, GRAY); DrawText("Hold RMB to move camera", 10, 430, 10, GRAY);
DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY); DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY);
// UI elements // UI elements
if (GuiButton((Rectangle){ 10, screenHeight - 100, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel; if (GuiButton((Rectangle){ 10, screenHeight - 1000.f, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel;
if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100, 100, 60 }, "Clear Decals")) if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100.0f, 100, 60 }, "Clear Decals"))
{ {
// Clear decals, unload all decal models // Clear decals, unload all decal models
for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]); for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
@ -596,8 +596,8 @@ static bool GuiButton(Rectangle rec, const char *label)
DrawRectangleRec(rec, bgColor); DrawRectangleRec(rec, bgColor);
DrawRectangleLinesEx(rec, 2.0f, DARKGRAY); DrawRectangleLinesEx(rec, 2.0f, DARKGRAY);
float fontSize = 10.0f; int fontSize = 10;
float textWidth = MeasureText(label, fontSize); int textWidth = MeasureText(label, fontSize);
DrawText(label, (int)(rec.x + rec.width*0.5f - textWidth*0.5f), (int)(rec.y + rec.height*0.5f - fontSize*0.5f), fontSize, DARKGRAY); DrawText(label, (int)(rec.x + rec.width*0.5f - textWidth*0.5f), (int)(rec.y + rec.height*0.5f - fontSize*0.5f), fontSize, DARKGRAY);

View File

@ -80,18 +80,23 @@ int main(void)
if (playerCellY < 0) playerCellY = 0; if (playerCellY < 0) playerCellY = 0;
else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1; else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1;
// Check map collisions using image data and player position // Check map collisions using image data and player position against surrounding cells only
// TODO: Improvement: Just check player surrounding cells for collision for (int y = playerCellY - 1; y <= playerCellY + 1; y++)
for (int y = 0; y < cubicmap.height; y++)
{ {
for (int x = 0; x < cubicmap.width; x++) // Avoid map accessing out of bounds
if ((y >= 0) && (y < cubicmap.height))
{ {
if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel for (int x = playerCellX - 1; x <= playerCellX + 1; x++)
(CheckCollisionCircleRec(playerPos, playerRadius,
(Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f })))
{ {
// Collision detected, reset camera position // NOTE: Collision: Only checking R channel for white pixel
camera.position = oldCamPos; if (((x >= 0) && (x < cubicmap.width)) &&
(mapPixels[y*cubicmap.width + x].r == 255) &&
(CheckCollisionCircleRec(playerPos, playerRadius,
(Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f })))
{
// Collision detected, reset camera position
camera.position = oldCamPos;
}
} }
} }
} }

View File

@ -148,25 +148,25 @@ void DrawSphereBasic(Color color)
{ {
for (int j = 0; j < slices; j++) for (int j = 0; j < slices; j++)
{ {
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)), rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*i)), sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)),
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices))); cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)), rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices))); cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)), rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360.0f/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices))); cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)), rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*i)), sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)),
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices))); cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)), rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*(i))), sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i))),
cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices))); cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)), rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices))); cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
} }
} }
rlEnd(); rlEnd();

View File

@ -85,9 +85,9 @@ int main(void)
// Calculate the cube position // Calculate the cube position
Vector3 cubePos = { Vector3 cubePos = {
(float)(x - numBlocks/2)*(scale*3.0f) + scatter, (float)(x - (float)numBlocks/2)*(scale*3.0f) + scatter,
(float)(y - numBlocks/2)*(scale*2.0f) + scatter, (float)(y - (float)numBlocks/2)*(scale*2.0f) + scatter,
(float)(z - numBlocks/2)*(scale*3.0f) + scatter (float)(z - (float)numBlocks/2)*(scale*3.0f) + scatter
}; };
// Pick a color with a hue depending on cube position for the rainbow color effect // Pick a color with a hue depending on cube position for the rainbow color effect

View File

@ -30,6 +30,7 @@
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
#define GLAD_GLES2_IMPLEMENTATION
#include "glad_gles2.h" // Required for: OpenGL functionality #include "glad_gles2.h" // Required for: OpenGL functionality
#define glGenVertexArrays glGenVertexArraysOES #define glGenVertexArrays glGenVertexArraysOES
#define glBindVertexArray glBindVertexArrayOES #define glBindVertexArray glBindVertexArrayOES

View File

@ -40,13 +40,13 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// GBuffer data // GBuffer data
typedef struct GBuffer { typedef struct GBuffer {
unsigned int framebuffer; unsigned int framebufferId;
unsigned int positionTexture; unsigned int positionTextureId;
unsigned int normalTexture; unsigned int normalTextureId;
unsigned int albedoSpecTexture; unsigned int albedoSpecTextureId;
unsigned int depthRenderbuffer; unsigned int depthRenderbufferId;
} GBuffer; } GBuffer;
// Deferred mode passes // Deferred mode passes
@ -90,15 +90,10 @@ int main(void)
// Initialize the G-buffer // Initialize the G-buffer
GBuffer gBuffer = { 0 }; GBuffer gBuffer = { 0 };
gBuffer.framebuffer = rlLoadFramebuffer(); gBuffer.framebufferId = rlLoadFramebuffer();
if (gBuffer.framebufferId == 0) TraceLog(LOG_WARNING, "Failed to create framebufferId");
if (!gBuffer.framebuffer) rlEnableFramebuffer(gBuffer.framebufferId);
{
TraceLog(LOG_WARNING, "Failed to create framebuffer");
exit(1);
}
rlEnableFramebuffer(gBuffer.framebuffer);
// NOTE: Vertex positions are stored in a texture for simplicity. A better approach would use a depth texture // NOTE: Vertex positions are stored in a texture for simplicity. A better approach would use a depth texture
// (instead of a detph renderbuffer) to reconstruct world positions in the final render shader via clip-space position, // (instead of a detph renderbuffer) to reconstruct world positions in the final render shader via clip-space position,
@ -107,46 +102,42 @@ int main(void)
// 16-bit precision ensures OpenGL ES 3 compatibility, though it may lack precision for real scenarios // 16-bit precision ensures OpenGL ES 3 compatibility, though it may lack precision for real scenarios
// But as mentioned above, the positions could be reconstructed instead of stored. If not targeting OpenGL ES // But as mentioned above, the positions could be reconstructed instead of stored. If not targeting OpenGL ES
// and you wish to maintain this approach, consider using `RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32` // and you wish to maintain this approach, consider using `RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32`
gBuffer.positionTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1); gBuffer.positionTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1);
// Similarly, 16-bit precision is used for normals ensures OpenGL ES 3 compatibility // Similarly, 16-bit precision is used for normals ensures OpenGL ES 3 compatibility
// This is generally sufficient, but a 16-bit fixed-point format offer a better uniform precision in all orientations // This is generally sufficient, but a 16-bit fixed-point format offer a better uniform precision in all orientations
gBuffer.normalTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1); gBuffer.normalTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1);
// Albedo (diffuse color) and specular strength can be combined into one texture // Albedo (diffuse color) and specular strength can be combined into one texture
// The color in RGB, and the specular strength in the alpha channel // The color in RGB, and the specular strength in the alpha channel
gBuffer.albedoSpecTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); gBuffer.albedoSpecTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
// Activate the draw buffers for our framebuffer // Activate the draw buffers for our framebufferId
rlActiveDrawBuffers(3); rlActiveDrawBuffers(3);
// Now we attach our textures to the framebuffer // Now we attach our textures to the framebufferId
rlFramebufferAttach(gBuffer.framebuffer, gBuffer.positionTexture, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0); rlFramebufferAttach(gBuffer.framebufferId, gBuffer.positionTextureId, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0);
rlFramebufferAttach(gBuffer.framebuffer, gBuffer.normalTexture, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0); rlFramebufferAttach(gBuffer.framebufferId, gBuffer.normalTextureId, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0);
rlFramebufferAttach(gBuffer.framebuffer, gBuffer.albedoSpecTexture, RL_ATTACHMENT_COLOR_CHANNEL2, RL_ATTACHMENT_TEXTURE2D, 0); rlFramebufferAttach(gBuffer.framebufferId, gBuffer.albedoSpecTextureId, RL_ATTACHMENT_COLOR_CHANNEL2, RL_ATTACHMENT_TEXTURE2D, 0);
// Finally we attach the depth buffer // Finally we attach the depth buffer
gBuffer.depthRenderbuffer = rlLoadTextureDepth(screenWidth, screenHeight, true); gBuffer.depthRenderbufferId = rlLoadTextureDepth(screenWidth, screenHeight, true);
rlFramebufferAttach(gBuffer.framebuffer, gBuffer.depthRenderbuffer, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0); rlFramebufferAttach(gBuffer.framebufferId, gBuffer.depthRenderbufferId, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
// Make sure our framebuffer is complete // Make sure our framebufferId is complete
// NOTE: rlFramebufferComplete() automatically unbinds the framebuffer, so we don't have // NOTE: rlFramebufferComplete() automatically unbinds the framebufferId, so we don't have to rlDisableFramebuffer() here
// to rlDisableFramebuffer() here if (!rlFramebufferComplete(gBuffer.framebufferId)) TraceLog(LOG_WARNING, "Framebuffer is not complete");
if (!rlFramebufferComplete(gBuffer.framebuffer))
{
TraceLog(LOG_WARNING, "Framebuffer is not complete");
}
// Now we initialize the sampler2D uniform's in the deferred shader // Now we initialize the sampler2D uniform's in the deferred shader
// We do this by setting the uniform's values to the texture units that // We do this by setting the uniform's values to the texture units that
// we later bind our g-buffer textures to // we later bind our g-buffer textures to
rlEnableShader(deferredShader.id); rlEnableShader(deferredShader.id);
int texUnitPosition = 0; int texUnitPosition = 0;
int texUnitNormal = 1; int texUnitNormal = 1;
int texUnitAlbedoSpec = 2; int texUnitAlbedoSpec = 2;
SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gPosition"), &texUnitPosition, RL_SHADER_UNIFORM_SAMPLER2D); SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gPosition"), &texUnitPosition, RL_SHADER_UNIFORM_SAMPLER2D);
SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gNormal"), &texUnitNormal, RL_SHADER_UNIFORM_SAMPLER2D); SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gNormal"), &texUnitNormal, RL_SHADER_UNIFORM_SAMPLER2D);
SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gAlbedoSpec"), &texUnitAlbedoSpec, RL_SHADER_UNIFORM_SAMPLER2D); SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gAlbedoSpec"), &texUnitAlbedoSpec, RL_SHADER_UNIFORM_SAMPLER2D);
rlDisableShader(); rlDisableShader();
// Assign out lighting shader to model // Assign out lighting shader to model
@ -176,7 +167,7 @@ int main(void)
cubeRotations[i] = (float)(rand()%360); cubeRotations[i] = (float)(rand()%360);
} }
DeferredMode mode = DEFERRED_SHADING; int mode = DEFERRED_SHADING;
rlEnableDepthTest(); rlEnableDepthTest();
@ -215,17 +206,16 @@ int main(void)
BeginDrawing(); BeginDrawing();
// Draw to the geometry buffer by first activating it // Draw to the geometry buffer by first activating it
rlEnableFramebuffer(gBuffer.framebuffer); rlEnableFramebuffer(gBuffer.framebufferId);
rlClearColor(0, 0, 0, 0); rlClearColor(0, 0, 0, 0);
rlClearScreenBuffers(); // Clear color and depth buffer rlClearScreenBuffers(); // Clear color and depth buffer
rlDisableColorBlend(); rlDisableColorBlend();
BeginMode3D(camera); BeginMode3D(camera);
// NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader` // NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader`
// will not work, as they won't immediately load the shader program // will not work, as they won't immediately load the shader program
rlEnableShader(gbufferShader.id); rlEnableShader(gbufferShader.id);
// When drawing a model here, make sure that the material's shaders // When drawing a model here, make sure that the material's shaders are set to the gbuffer shader!
// are set to the gbuffer shader!
DrawModel(model, Vector3Zero(), 1.0f, WHITE); DrawModel(model, Vector3Zero(), 1.0f, WHITE);
DrawModel(cube, (Vector3) { 0.0, 1.0f, 0.0 }, 1.0f, WHITE); DrawModel(cube, (Vector3) { 0.0, 1.0f, 0.0 }, 1.0f, WHITE);
@ -234,12 +224,12 @@ int main(void)
Vector3 position = cubePositions[i]; Vector3 position = cubePositions[i];
DrawModelEx(cube, position, (Vector3) { 1, 1, 1 }, cubeRotations[i], (Vector3) { CUBE_SCALE, CUBE_SCALE, CUBE_SCALE }, WHITE); DrawModelEx(cube, position, (Vector3) { 1, 1, 1 }, cubeRotations[i], (Vector3) { CUBE_SCALE, CUBE_SCALE, CUBE_SCALE }, WHITE);
} }
rlDisableShader(); rlDisableShader();
EndMode3D(); EndMode3D();
rlEnableColorBlend(); rlEnableColorBlend();
// Go back to the default framebuffer (0) and draw our deferred shading // Go back to the default framebufferId (0) and draw our deferred shading
rlDisableFramebuffer(); rlDisableFramebuffer();
rlClearScreenBuffers(); // Clear color & depth buffer rlClearScreenBuffers(); // Clear color & depth buffer
@ -254,21 +244,21 @@ int main(void)
// We are binding them to locations that we earlier set in sampler2D uniforms `gPosition`, `gNormal`, // We are binding them to locations that we earlier set in sampler2D uniforms `gPosition`, `gNormal`,
// and `gAlbedoSpec` // and `gAlbedoSpec`
rlActiveTextureSlot(texUnitPosition); rlActiveTextureSlot(texUnitPosition);
rlEnableTexture(gBuffer.positionTexture); rlEnableTexture(gBuffer.positionTextureId);
rlActiveTextureSlot(texUnitNormal); rlActiveTextureSlot(texUnitNormal);
rlEnableTexture(gBuffer.normalTexture); rlEnableTexture(gBuffer.normalTextureId);
rlActiveTextureSlot(texUnitAlbedoSpec); rlActiveTextureSlot(texUnitAlbedoSpec);
rlEnableTexture(gBuffer.albedoSpecTexture); rlEnableTexture(gBuffer.albedoSpecTextureId);
// Finally, we draw a fullscreen quad to our default framebuffer // Finally, we draw a fullscreen quad to our default framebufferId
// This will now be shaded using our deferred shader // This will now be shaded using our deferred shader
rlLoadDrawQuad(); rlLoadDrawQuad();
rlDisableShader(); rlDisableShader();
rlEnableColorBlend(); rlEnableColorBlend();
EndMode3D(); EndMode3D();
// As a last step, we now copy over the depth buffer from our g-buffer to the default framebuffer // As a last step, we now copy over the depth buffer from our g-buffer to the default framebufferId
rlBindFramebuffer(RL_READ_FRAMEBUFFER, gBuffer.framebuffer); rlBindFramebuffer(RL_READ_FRAMEBUFFER, gBuffer.framebufferId);
rlBindFramebuffer(RL_DRAW_FRAMEBUFFER, 0); rlBindFramebuffer(RL_DRAW_FRAMEBUFFER, 0);
rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT
rlDisableFramebuffer(); rlDisableFramebuffer();
@ -290,7 +280,7 @@ int main(void)
case DEFERRED_POSITION: case DEFERRED_POSITION:
{ {
DrawTextureRec((Texture2D){ DrawTextureRec((Texture2D){
.id = gBuffer.positionTexture, .id = gBuffer.positionTextureId,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
@ -300,7 +290,7 @@ int main(void)
case DEFERRED_NORMAL: case DEFERRED_NORMAL:
{ {
DrawTextureRec((Texture2D){ DrawTextureRec((Texture2D){
.id = gBuffer.normalTexture, .id = gBuffer.normalTextureId,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
@ -310,7 +300,7 @@ int main(void)
case DEFERRED_ALBEDO: case DEFERRED_ALBEDO:
{ {
DrawTextureRec((Texture2D){ DrawTextureRec((Texture2D){
.id = gBuffer.albedoSpecTexture, .id = gBuffer.albedoSpecTextureId,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
@ -331,18 +321,20 @@ int main(void)
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
UnloadModel(model); // Unload the models // Unload the models
UnloadModel(model);
UnloadModel(cube); UnloadModel(cube);
UnloadShader(deferredShader); // Unload shaders // Unload shaders
UnloadShader(deferredShader);
UnloadShader(gbufferShader); UnloadShader(gbufferShader);
// Unload geometry buffer and all attached textures // Unload geometry buffer and all attached textures
rlUnloadFramebuffer(gBuffer.framebuffer); rlUnloadFramebuffer(gBuffer.framebufferId);
rlUnloadTexture(gBuffer.positionTexture); rlUnloadTexture(gBuffer.positionTextureId);
rlUnloadTexture(gBuffer.normalTexture); rlUnloadTexture(gBuffer.normalTextureId);
rlUnloadTexture(gBuffer.albedoSpecTexture); rlUnloadTexture(gBuffer.albedoSpecTextureId);
rlUnloadTexture(gBuffer.depthRenderbuffer); rlUnloadTexture(gBuffer.depthRenderbufferId);
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

View File

@ -258,8 +258,8 @@ int main(void)
UnloadImage(pattern); UnloadImage(pattern);
mode = MODE_PAUSE; mode = MODE_PAUSE;
offsetX = worldWidth*presetPatterns[preset].position.x - windowWidth/zoom/2.0f; offsetX = worldWidth*presetPatterns[preset].position.x - (float)windowWidth/zoom/2.0f;
offsetY = worldHeight*presetPatterns[preset].position.y - windowHeight/zoom/2.0f; offsetY = worldHeight*presetPatterns[preset].position.y - (float)windowHeight/zoom/2.0f;
} }
// Check window draw inside world limits // Check window draw inside world limits

View File

@ -65,7 +65,7 @@ int main(void)
Shader shdrRaster = LoadShader(0, TextFormat("resources/shaders/glsl%i/hybrid_raster.fs", GLSL_VERSION)); Shader shdrRaster = LoadShader(0, TextFormat("resources/shaders/glsl%i/hybrid_raster.fs", GLSL_VERSION));
// Declare Struct used to store camera locs // Declare Struct used to store camera locs
RayLocs marchLocs = {0}; RayLocs marchLocs = { 0 };
// Fill the struct with shader locs // Fill the struct with shader locs
marchLocs.camPos = GetShaderLocation(shdrRaymarch, "camPos"); marchLocs.camPos = GetShaderLocation(shdrRaymarch, "camPos");

View File

@ -41,7 +41,7 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - vertex displacement"); InitWindow(screenWidth, screenHeight, "raylib [shaders] example - vertex displacement");
// set up camera // set up camera
Camera camera = {0}; Camera camera = { 0 };
camera.position = (Vector3) {20.0f, 5.0f, -20.0f}; camera.position = (Vector3) {20.0f, 5.0f, -20.0f};
camera.target = (Vector3) {0.0f, 0.0f, 0.0f}; camera.target = (Vector3) {0.0f, 0.0f, 0.0f};
camera.up = (Vector3) {0.0f, 1.0f, 0.0f}; camera.up = (Vector3) {0.0f, 1.0f, 0.0f};

View File

@ -46,19 +46,19 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics"); InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
Ball balls[MAX_BALLS] = {{ Ball balls[MAX_BALLS] = {{
.pos = { GetScreenWidth()/2, GetScreenHeight()/2 }, .pos = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
.vel = { 200, 200 }, .vel = { 200, 200 },
.ppos = { 0 }, .ppos = { 0 },
.radius = 40, .radius = 40,
.friction = 0.99, .friction = 0.99f,
.elasticity = 0.9, .elasticity = 0.9f,
.color = BLUE, .color = BLUE,
.grabbed = false .grabbed = false
}}; }};
int ballCount = 1; int ballCount = 1;
Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed
Vector2 pressOffset = {0}; // Mouse press offset relative to the ball that grabbedd Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd
float gravity = 100; // World gravity float gravity = 100; // World gravity
@ -110,11 +110,11 @@ int main(void)
{ {
balls[ballCount++] = (Ball){ balls[ballCount++] = (Ball){
.pos = mousePos, .pos = mousePos,
.vel = { GetRandomValue(-300, 300), GetRandomValue(-300, 300) }, .vel = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) },
.ppos = { 0 }, .ppos = { 0 },
.radius = 20 + GetRandomValue(0, 30), .radius = 20.0f + (float)GetRandomValue(0, 30),
.friction = 0.99, .friction = 0.99f,
.elasticity = 0.9, .elasticity = 0.9f,
.color = { GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 }, .color = { GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 },
.grabbed = false .grabbed = false
}; };
@ -126,7 +126,7 @@ int main(void)
{ {
for (int i = 0; i < ballCount; i++) for (int i = 0; i < ballCount; i++)
{ {
if (!balls[i].grabbed) balls[i].vel = (Vector2){ GetRandomValue(-2000, 2000), GetRandomValue(-2000, 2000) }; if (!balls[i].grabbed) balls[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) };
} }
} }

View File

@ -45,7 +45,7 @@ int main(void)
for (int i = 0; i < MAX_COLORS_COUNT; i++) for (int i = 0; i < MAX_COLORS_COUNT; i++)
{ {
colorsRecs[i].x = 20.0f + 100.0f *(i%7) + 10.0f *(i%7); colorsRecs[i].x = 20.0f + 100.0f *(i%7) + 10.0f *(i%7);
colorsRecs[i].y = 80.0f + 100.0f *(i/7) + 10.0f *(i/7); colorsRecs[i].y = 80.0f + 100.0f *((float)i/7) + 10.0f *((float)i/7);
colorsRecs[i].width = 100.0f; colorsRecs[i].width = 100.0f;
colorsRecs[i].height = 100.0f; colorsRecs[i].height = 100.0f;
} }

View File

@ -311,7 +311,7 @@ static void DrawDisplaySegment(Vector2 center, int length, int thick, bool verti
(Vector2){ center.x + thick/2.0f, center.y - length/2.0f }, // Point 3 (Vector2){ center.x + thick/2.0f, center.y - length/2.0f }, // Point 3
(Vector2){ center.x - thick/2.0f, center.y + length/2.0f }, // Point 4 (Vector2){ center.x - thick/2.0f, center.y + length/2.0f }, // Point 4
(Vector2){ center.x + thick/2.0f, center.y + length/2.0f }, // Point 5 (Vector2){ center.x + thick/2.0f, center.y + length/2.0f }, // Point 5
(Vector2){ center.x, center.y + length/2 + thick/2.0f }, // Point 6 (Vector2){ center.x, center.y + (float)length/2 + thick/2.0f }, // Point 6
}; };
DrawTriangleStrip(segmentPointsV, 6, color); DrawTriangleStrip(segmentPointsV, 6, color);

View File

@ -49,8 +49,8 @@ int main(void)
float totalM = m1 + m2; float totalM = m1 + m2;
Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2); Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
previousPosition.x += (screenWidth/2); previousPosition.x += ((float)screenWidth/2);
previousPosition.y += (screenHeight/2 - 100); previousPosition.y += ((float)screenHeight/2 - 100);
// Scale length // Scale length
float L1 = l1*lengthScaler; float L1 = l1*lengthScaler;
@ -105,8 +105,8 @@ int main(void)
// Calculate position // Calculate position
Vector2 currentPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2); Vector2 currentPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
currentPosition.x += screenWidth/2; currentPosition.x += (float)screenWidth/2;
currentPosition.y += screenHeight/2 - 100; currentPosition.y += (float)screenHeight/2 - 100;
// Draw to render texture // Draw to render texture
BeginTextureMode(target); BeginTextureMode(target);

View File

@ -0,0 +1,196 @@
/*******************************************************************************************
*
* raylib [shapes] example - hilbert curve
*
* Example complexity rating: [★★★☆] 3/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example contributed by Hamza RAHAL (@hmz-rhl) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2025 Hamza RAHAL (@hmz-rhl)
*
********************************************************************************************/
#include "raylib.h"
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
#include <stdlib.h> // Required for: calloc(), free()
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static Vector2 *LoadHilbertPath(int order, float size, int *strokeCount);
static void UnloadHilbertPath(Vector2 *hilbertPath);
static Vector2 ComputeHilbertStep(int order, int index);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - hilbert curve");
int order = 2;
float size = GetScreenHeight();
int strokeCount = 0;
Vector2 *hilbertPath = LoadHilbertPath(order, size, &strokeCount);
int prevOrder = order;
int prevSize = (int)size; // NOTE: Size from slider is float but for comparison we use int
int counter = 0;
float thick = 2.0f;
bool animate = true;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
//--------------------------------------------------------------------------------------
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Check if order or size have changed to regenerate
// NOTE: Size from slider is float but for comparison we use int
if ((prevOrder != order) || (prevSize != (int)size))
{
UnloadHilbertPath(hilbertPath);
hilbertPath = LoadHilbertPath(order, size, &strokeCount);
if (animate) counter = 0;
else counter = strokeCount;
prevOrder = order;
prevSize = size;
}
//----------------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
if (counter < strokeCount)
{
// Draw Hilbert path animation, one stroke every frame
for (int i = 1; i <= counter; i++)
{
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f));
}
counter += 1;
}
else
{
// Draw full Hilbert path
for (int i = 1; i < strokeCount; i++)
{
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f));
}
}
// Draw UI using raygui
GuiCheckBox((Rectangle){ 450, 50, 20, 20 }, "ANIMATE GENERATION ON CHANGE", &animate);
GuiSpinner((Rectangle){ 585, 100, 180, 30 }, "HILBERT CURVE ORDER: ", &order, 2, 8, false);
GuiSlider((Rectangle){ 524, 150, 240, 24 }, "THICKNESS: ", NULL, &thick, 1.0f, 10.0f);
GuiSlider((Rectangle){ 524, 190, 240, 24 }, "TOTAL SIZE: ", NULL, &size, 10.0f, GetScreenHeight()*1.5f);
EndDrawing();
//--------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------------
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadHilbertPath(hilbertPath);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
// Load the whole Hilbert Path (including each U and their link)
static Vector2 *LoadHilbertPath(int order, float size, int *strokeCount)
{
int N = 1 << order;
float len = size/N;
*strokeCount = N*N;
Vector2 *hilbertPath = (Vector2 *)RL_CALLOC(*strokeCount, sizeof(Vector2));
for (int i = 0; i < *strokeCount; i++)
{
hilbertPath[i] = ComputeHilbertStep(order, i);
hilbertPath[i].x = hilbertPath[i].x*len + len/2.0f;
hilbertPath[i].y = hilbertPath[i].y*len + len/2.0f;
}
return hilbertPath;
}
// Unload Hilbert path data
static void UnloadHilbertPath(Vector2 *hilbertPath)
{
RL_FREE(hilbertPath);
}
// Compute Hilbert path U positions
static Vector2 ComputeHilbertStep(int order, int index)
{
// Hilbert points base pattern
static const Vector2 hilbertPoints[4] = {
[0] = { .x = 0, .y = 0 },
[1] = { .x = 0, .y = 1 },
[2] = { .x = 1, .y = 1 },
[3] = { .x = 1, .y = 0 },
};
int hilbertIndex = index&3;
Vector2 vect = hilbertPoints[hilbertIndex];
float temp = 0.0f;
int len = 0;
for (int j = 1; j < order; j++)
{
index = index >> 2;
hilbertIndex = index&3;
len = 1 << j;
switch (hilbertIndex)
{
case 0:
{
temp = vect.x;
vect.x = vect.y;
vect.y = temp;
} break;
case 2: vect.x += len;
case 1: vect.y += len; break;
case 3:
{
temp = len - 1 - vect.x;
vect.x = 2*len - 1 - vect.y;
vect.y = temp;
} break;
default: break;
}
}
return vect;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -50,9 +50,9 @@ int main(void)
int symmetry = 6; int symmetry = 6;
float angle = 360.0f/(float)symmetry; float angle = 360.0f/(float)symmetry;
float thickness = 3.0f; float thickness = 3.0f;
Rectangle resetButtonRec = { screenWidth - 55, 5, 50, 25 }; Rectangle resetButtonRec = { screenWidth - 55.0f, 5.0f, 50, 25 };
Rectangle backButtonRec = { screenWidth - 55, screenHeight - 30, 25, 25 }; Rectangle backButtonRec = { screenWidth - 55.0f, screenHeight - 30.0f, 25, 25 };
Rectangle nextButtonRec = { screenWidth - 30, screenHeight - 30, 25, 25 }; Rectangle nextButtonRec = { screenWidth - 30.0f, screenHeight - 30.0f, 25, 25 };
Vector2 mousePos = { 0 }; Vector2 mousePos = { 0 };
Vector2 prevMousePos = { 0 }; Vector2 prevMousePos = { 0 };
Vector2 scaleVector = { 1.0f, -1.0f }; Vector2 scaleVector = { 1.0f, -1.0f };

View File

@ -185,12 +185,12 @@ static void BuildProductionStep(PenroseLSystem *ls)
char *newProduction = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE); char *newProduction = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
newProduction[0] = '\0'; newProduction[0] = '\0';
int productionLength = strnlen(ls->production, STR_MAX_SIZE); int productionLength = (int)strnlen(ls->production, STR_MAX_SIZE);
for (int i = 0; i < productionLength; i++) for (int i = 0; i < productionLength; i++)
{ {
char step = ls->production[i]; char step = ls->production[i];
int remainingSpace = STR_MAX_SIZE - strnlen(newProduction, STR_MAX_SIZE) - 1; int remainingSpace = STR_MAX_SIZE - (int)strnlen(newProduction, STR_MAX_SIZE) - 1;
switch (step) switch (step)
{ {
case 'W': strncat(newProduction, ls->ruleW, remainingSpace); break; case 'W': strncat(newProduction, ls->ruleW, remainingSpace); break;
@ -201,7 +201,7 @@ static void BuildProductionStep(PenroseLSystem *ls)
{ {
if (step != 'F') if (step != 'F')
{ {
int t = strnlen(newProduction, STR_MAX_SIZE); int t = (int)strnlen(newProduction, STR_MAX_SIZE);
newProduction[t] = step; newProduction[t] = step;
newProduction[t + 1] = '\0'; newProduction[t + 1] = '\0';
} }
@ -218,7 +218,7 @@ static void BuildProductionStep(PenroseLSystem *ls)
// Draw penrose tile lines // Draw penrose tile lines
static void DrawPenroseLSystem(PenroseLSystem *ls) static void DrawPenroseLSystem(PenroseLSystem *ls)
{ {
Vector2 screenCenter = { GetScreenWidth()/2, GetScreenHeight()/2 }; Vector2 screenCenter = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
TurtleState turtle = { TurtleState turtle = {
.origin = { 0 }, .origin = { 0 },
@ -245,7 +245,7 @@ static void DrawPenroseLSystem(PenroseLSystem *ls)
Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y }; Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y };
Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y }; Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y };
DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2)); DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2f));
} }
repeats = 1; repeats = 1;

View File

@ -49,8 +49,8 @@ int main(void)
bool showPercentages = false; bool showPercentages = false;
bool showDonut = false; bool showDonut = false;
int hoveredSlice = -1; int hoveredSlice = -1;
Rectangle scrollPanelBounds = {0}; Rectangle scrollPanelBounds = { 0 };
Vector2 scrollContentOffset = {0}; Vector2 scrollContentOffset = { 0 };
Rectangle view = { 0 }; Rectangle view = { 0 };
// UI layout parameters // UI layout parameters

View File

@ -113,7 +113,7 @@ int main(void)
// Set the text (using markdown!) // Set the text (using markdown!)
char text[64] = "Hello ~~World~~ in 3D!"; char text[64] = "Hello ~~World~~ in 3D!";
Vector3 tbox = {0}; Vector3 tbox = { 0 };
int layers = 1; int layers = 1;
int quads = 0; int quads = 0;
float layerDistance = 0.01f; float layerDistance = 0.01f;
@ -133,7 +133,7 @@ int main(void)
Shader alphaDiscard = LoadShader(NULL, TextFormat("resources/shaders/glsl%i/alpha_discard.fs", GLSL_VERSION)); Shader alphaDiscard = LoadShader(NULL, TextFormat("resources/shaders/glsl%i/alpha_discard.fs", GLSL_VERSION));
// Array filled with multiple random colors (when multicolor mode is set) // Array filled with multiple random colors (when multicolor mode is set)
Color multi[TEXT_MAX_LAYERS] = {0}; Color multi[TEXT_MAX_LAYERS] = { 0 };
DisableCursor(); // Limit cursor to relative movement inside the window DisableCursor(); // Limit cursor to relative movement inside the window

View File

@ -97,8 +97,8 @@ int main(void)
if (currentFont == 0) textSize = MeasureTextEx(fontDefault, msg, fontSize, 0); if (currentFont == 0) textSize = MeasureTextEx(fontDefault, msg, fontSize, 0);
else textSize = MeasureTextEx(fontSDF, msg, fontSize, 0); else textSize = MeasureTextEx(fontSDF, msg, fontSize, 0);
fontPosition.x = GetScreenWidth()/2 - textSize.x/2; fontPosition.x = (float)GetScreenWidth()/2 - textSize.x/2;
fontPosition.y = GetScreenHeight()/2 - textSize.y/2 + 80; fontPosition.y = (float)GetScreenHeight()/2 - textSize.y/2 + 80;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw

View File

@ -178,14 +178,14 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float
// Convert hex color text into actual Color // Convert hex color text into actual Color
unsigned int colHexValue = strtoul(colHexText, NULL, 16); unsigned int colHexValue = strtoul(colHexText, NULL, 16);
if (text[i - 1] == 'c') if (text[i - 1] == 'c')
{ {
colFront = GetColor(colHexValue); colFront = GetColor(colHexValue);
colFront.a *= (float)color.a/255.0f; //colFront.a *= (unsigned char)(colFront.a*(float)color.a/255.0f); // TODO: Review
} }
else if (text[i - 1] == 'b') else if (text[i - 1] == 'b')
{ {
colBack = GetColor(colHexValue); colBack = GetColor(colHexValue);
colBack.a *= (float)color.a/255.0f; //colBack.a *= (unsigned char)(colFront.a*(float)color.a/255.0f);
} }
i += (colHexCount + 1); // Skip color value retrieved and ']' i += (colHexCount + 1); // Skip color value retrieved and ']'

View File

@ -226,7 +226,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec,
{ {
if (!wordWrap) if (!wordWrap)
{ {
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor;
textOffsetX = 0; textOffsetX = 0;
} }
} }
@ -234,7 +234,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec,
{ {
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width)) if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
{ {
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor;
textOffsetX = 0; textOffsetX = 0;
} }
@ -258,7 +258,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec,
if (wordWrap && (i == endLine)) if (wordWrap && (i == endLine))
{ {
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor;
textOffsetX = 0; textOffsetX = 0;
startLine = endLine; startLine = endLine;
endLine = -1; endLine = -1;

View File

@ -65,7 +65,7 @@ int main(void)
TextParticle textParticles[MAX_TEXT_PARTICLES] = { 0 }; TextParticle textParticles[MAX_TEXT_PARTICLES] = { 0 };
int particleCount = 0; int particleCount = 0;
TextParticle *grabbedTextParticle = NULL; TextParticle *grabbedTextParticle = NULL;
Vector2 pressOffset = {0}; Vector2 pressOffset = { 0 };
PrepareFirstTextParticle("raylib => fun videogames programming!", textParticles, &particleCount); PrepareFirstTextParticle("raylib => fun videogames programming!", textParticles, &particleCount);
@ -133,7 +133,7 @@ int main(void)
{ {
for (int i = 0; i < particleCount; i++) for (int i = 0; i < particleCount; i++)
{ {
if (!textParticles[i].grabbed) textParticles[i].vel = (Vector2){ GetRandomValue(-2000, 2000), GetRandomValue(-2000, 2000) }; if (!textParticles[i].grabbed) textParticles[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) };
} }
} }
@ -233,9 +233,9 @@ int main(void)
for (int i = 0; i < particleCount; i++) for (int i = 0; i < particleCount; i++)
{ {
TextParticle *tp = &textParticles[i]; TextParticle *tp = &textParticles[i];
DrawRectangle(tp->rect.x-tp->borderWidth, tp->rect.y-tp->borderWidth, tp->rect.width+tp->borderWidth*2, tp->rect.height+tp->borderWidth*2, BLACK); DrawRectangleRec((Rectangle) { tp->rect.x - tp->borderWidth, tp->rect.y - tp->borderWidth, tp->rect.width + tp->borderWidth * 2, tp->rect.height + tp->borderWidth * 2 }, BLACK);
DrawRectangleRec(tp->rect, tp->color); DrawRectangleRec(tp->rect, tp->color);
DrawText(tp->text, tp->rect.x+tp->padding, tp->rect.y+tp->padding, FONT_SIZE, BLACK); DrawText(tp->text, (int)(tp->rect.x+tp->padding), (int)(tp->rect.y+tp->padding), FONT_SIZE, BLACK);
} }
DrawText("grab a text particle by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY); DrawText("grab a text particle by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY);
@ -265,8 +265,8 @@ void PrepareFirstTextParticle(const char* text, TextParticle *tps, int *particle
{ {
tps[0] = CreateTextParticle( tps[0] = CreateTextParticle(
text, text,
GetScreenWidth()/2, GetScreenWidth()/2.0f,
GetScreenHeight()/2, GetScreenHeight()/2.0f,
RAYWHITE RAYWHITE
); );
*particleCount = 1; *particleCount = 1;
@ -277,12 +277,12 @@ TextParticle CreateTextParticle(const char *text, float x, float y, Color color)
TextParticle tp = { TextParticle tp = {
.text = "", .text = "",
.rect = { x, y, 30, 30 }, .rect = { x, y, 30, 30 },
.vel = { GetRandomValue(-200, 200), GetRandomValue(-200, 200) }, .vel = { (float)GetRandomValue(-200, 200), (float)GetRandomValue(-200, 200) },
.ppos = { 0 }, .ppos = { 0 },
.padding = 5.0f, .padding = 5.0f,
.borderWidth = 5.0f, .borderWidth = 5.0f,
.friction = 0.99, .friction = 0.99f,
.elasticity = 0.9, .elasticity = 0.9f,
.color = color, .color = color,
.grabbed = false .grabbed = false
}; };
@ -316,7 +316,7 @@ void SliceTextParticle(TextParticle *tp, int particlePos, int sliceLength, TextP
void SliceTextParticleByChar(TextParticle *tp, char charToSlice, TextParticle *tps, int *particleCount) void SliceTextParticleByChar(TextParticle *tp, char charToSlice, TextParticle *tps, int *particleCount)
{ {
int tokenCount = 0; int tokenCount = 0;
const char **tokens = TextSplit(tp->text, charToSlice, &tokenCount); char **tokens = TextSplit(tp->text, charToSlice, &tokenCount);
if (tokenCount > 1) if (tokenCount > 1)
{ {

View File

@ -277,7 +277,7 @@ int main(void)
DrawTriangle(a, b, c, emoji[selected].color); DrawTriangle(a, b, c, emoji[selected].color);
// Draw the main text message // Draw the main text message
Rectangle textRect = { msgRect.x + horizontalPadding/2, msgRect.y + verticalPadding/2, msgRect.width - horizontalPadding, msgRect.height }; Rectangle textRect = { msgRect.x + (float)horizontalPadding/2, msgRect.y + (float)verticalPadding/2, msgRect.width - horizontalPadding, msgRect.height };
DrawTextBoxed(*font, messages[message].text, textRect, (float)font->baseSize, 1.0f, true, WHITE); DrawTextBoxed(*font, messages[message].text, textRect, (float)font->baseSize, 1.0f, true, WHITE);
// Draw the info text below the main message // Draw the info text below the main message
@ -421,7 +421,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec,
{ {
if (!wordWrap) if (!wordWrap)
{ {
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor;
textOffsetX = 0; textOffsetX = 0;
} }
} }
@ -429,7 +429,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec,
{ {
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width)) if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
{ {
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor;
textOffsetX = 0; textOffsetX = 0;
} }
@ -453,7 +453,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec,
if (wordWrap && (i == endLine)) if (wordWrap && (i == endLine))
{ {
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor;
textOffsetX = 0; textOffsetX = 0;
startLine = endLine; startLine = endLine;
endLine = -1; endLine = -1;

View File

@ -41,7 +41,7 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [text] example - words alignment"); InitWindow(screenWidth, screenHeight, "raylib [text] example - words alignment");
// Define the rectangle we will draw the text in // Define the rectangle we will draw the text in
Rectangle textContainerRect = (Rectangle){ screenWidth/2-screenWidth/4, screenHeight/2-screenHeight/3, screenWidth/2, screenHeight*2/3 }; Rectangle textContainerRect = (Rectangle){ (float)screenWidth/2-(float)screenWidth/4, (float)screenHeight/2-(float)screenHeight/3, (float)screenWidth/2, (float)screenHeight*2/3 };
// Some text to display the current alignment // Some text to display the current alignment
const char *textAlignNameH[] = { "Left", "Centre", "Right" }; const char *textAlignNameH[] = { "Left", "Centre", "Right" };
@ -58,7 +58,7 @@ int main(void)
// And of course the font... // And of course the font...
Font font = GetFontDefault(); Font font = GetFontDefault();
// Intialize the alignment variables // Initialize the alignment variables
TextAlignment hAlign = TEXT_ALIGN_CENTRE; TextAlignment hAlign = TEXT_ALIGN_CENTRE;
TextAlignment vAlign = TEXT_ALIGN_MIDDLE; TextAlignment vAlign = TEXT_ALIGN_MIDDLE;
@ -72,8 +72,7 @@ int main(void)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_LEFT)) if (IsKeyPressed(KEY_LEFT))
{ {
hAlign = hAlign - 1; if (hAlign > 0) hAlign = hAlign - 1;
if (hAlign < 0) hAlign = 0;
} }
if (IsKeyPressed(KEY_RIGHT)) if (IsKeyPressed(KEY_RIGHT))
@ -84,8 +83,7 @@ int main(void)
if (IsKeyPressed(KEY_UP)) if (IsKeyPressed(KEY_UP))
{ {
vAlign = vAlign - 1; if (vAlign > 0) vAlign = vAlign - 1;
if (vAlign < 0) vAlign = 0;
} }
if (IsKeyPressed(KEY_DOWN)) if (IsKeyPressed(KEY_DOWN))
@ -95,7 +93,8 @@ int main(void)
} }
// One word per second // One word per second
wordIndex = (int)GetTime()%wordCount; if (wordCount > 0) wordIndex = (int)GetTime()%wordCount;
else wordIndex = 0;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -132,4 +131,4 @@ int main(void)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -83,10 +83,10 @@ int main(void)
bunnies[i].position.x += bunnies[i].speed.x; bunnies[i].position.x += bunnies[i].speed.x;
bunnies[i].position.y += bunnies[i].speed.y; bunnies[i].position.y += bunnies[i].speed.y;
if (((bunnies[i].position.x + texBunny.width/2) > GetScreenWidth()) || if (((bunnies[i].position.x + (float)texBunny.width/2) > GetScreenWidth()) ||
((bunnies[i].position.x + texBunny.width/2) < 0)) bunnies[i].speed.x *= -1; ((bunnies[i].position.x + (float)texBunny.width/2) < 0)) bunnies[i].speed.x *= -1;
if (((bunnies[i].position.y + texBunny.height/2) > GetScreenHeight()) || if (((bunnies[i].position.y + (float)texBunny.height/2) > GetScreenHeight()) ||
((bunnies[i].position.y + texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1; ((bunnies[i].position.y + (float)texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1;
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -165,7 +165,7 @@ int main(void)
// If the mouse is on this preset, highlight it // If the mouse is on this preset, highlight it
if (mouseInCell == i + 8) if (mouseInCell == i + 8)
DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*(i/2), DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*((float)i/2),
(presetsSizeY + 2.0f)*(i%2), (presetsSizeY + 2.0f)*(i%2),
presetsSizeX + 4.0f, presetsSizeY + 4.0f }, 3, RED); presetsSizeX + 4.0f, presetsSizeY + 4.0f }, 3, RED);
} }

View File

@ -93,8 +93,8 @@ int main(void)
for (unsigned int i = 0; i < map.tilesX*map.tilesY; i++) if (map.tileFog[i] == 1) map.tileFog[i] = 2; for (unsigned int i = 0; i < map.tilesX*map.tilesY; i++) if (map.tileFog[i] == 1) map.tileFog[i] = 2;
// Get current tile position from player pixel position // Get current tile position from player pixel position
playerTileX = (int)((playerPosition.x + MAP_TILE_SIZE/2)/MAP_TILE_SIZE); playerTileX = (int)((playerPosition.x + (float)MAP_TILE_SIZE/2)/MAP_TILE_SIZE);
playerTileY = (int)((playerPosition.y + MAP_TILE_SIZE/2)/MAP_TILE_SIZE); playerTileY = (int)((playerPosition.y + (float)MAP_TILE_SIZE/2)/MAP_TILE_SIZE);
// Check visibility and update fog // Check visibility and update fog
// NOTE: We check tilemap limits to avoid processing tiles out-of-array-bounds (it could crash program) // NOTE: We check tilemap limits to avoid processing tiles out-of-array-bounds (it could crash program)

View File

@ -0,0 +1,208 @@
/*******************************************************************************************
*
* raylib [textures] example - framebuffer rendering
*
* Example complexity rating: [★★☆☆] 2/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example contributed by Jack Boakes (@jackboakes) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2026 Jack Boakes (@jackboakes)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static void DrawCameraPrism(Camera3D camera, float aspect, Color color);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
const int splitWidth = screenWidth/2;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - framebuffer rendering");
// Camera to look at the 3D world
Camera3D subjectCamera = { 0 };
subjectCamera.position = (Vector3){ 5.0f, 5.0f, 5.0f };
subjectCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
subjectCamera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
subjectCamera.fovy = 45.0f;
subjectCamera.projection = CAMERA_PERSPECTIVE;
// Camera to observe the subject camera and 3D world
Camera3D observerCamera = { 0 };
observerCamera.position = (Vector3){ 10.0f, 10.0f, 10.0f };
observerCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
observerCamera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
observerCamera.fovy = 45.0f;
observerCamera.projection = CAMERA_PERSPECTIVE;
// Set up render textures
RenderTexture2D observerTarget = LoadRenderTexture(splitWidth, screenHeight);
Rectangle observerSource = { 0.0f, 0.0f, (float)observerTarget.texture.width, -(float)observerTarget.texture.height };
Rectangle observerDest = { 0.0f, 0.0f, (float)splitWidth, (float)screenHeight };
RenderTexture2D subjectTarget = LoadRenderTexture(splitWidth, screenHeight);
Rectangle subjectSource = { 0.0f, 0.0f, (float)subjectTarget.texture.width, -(float)subjectTarget.texture.height };
Rectangle subjectDest = { (float)splitWidth, 0.0f, (float)splitWidth, (float)screenHeight };
const float textureAspectRatio = (float)subjectTarget.texture.width/(float)subjectTarget.texture.height;
// Rectangles for cropping render texture
const float captureSize = 128.0f;
Rectangle cropSource = { (subjectTarget.texture.width - captureSize)/2.0f, (subjectTarget.texture.height - captureSize)/2.0f, captureSize, -captureSize };
Rectangle cropDest = { splitWidth + 20, 20, captureSize, captureSize};
SetTargetFPS(60);
DisableCursor();
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&observerCamera, CAMERA_FREE);
UpdateCamera(&subjectCamera, CAMERA_ORBITAL);
if (IsKeyPressed(KEY_R)) observerCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
// Build LHS observer view texture
BeginTextureMode(observerTarget);
ClearBackground(RAYWHITE);
BeginMode3D(observerCamera);
DrawGrid(10, 1.0f);
DrawCube((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, GOLD);
DrawCubeWires((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, PINK);
DrawCameraPrism(subjectCamera, textureAspectRatio, GREEN);
EndMode3D();
DrawText("Observer View", 10, observerTarget.texture.height - 30, 20, BLACK);
DrawText("WASD + Mouse to Move", 10, 10, 20, DARKGRAY);
DrawText("Scroll to Zoom", 10, 30, 20, DARKGRAY);
DrawText("R to Reset Observer Target", 10, 50, 20, DARKGRAY);
EndTextureMode();
// Build RHS subject view texture
BeginTextureMode(subjectTarget);
ClearBackground(RAYWHITE);
BeginMode3D(subjectCamera);
DrawCube((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, GOLD);
DrawCubeWires((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, PINK);
DrawGrid(10, 1.0f);
EndMode3D();
DrawRectangleLines((subjectTarget.texture.width - captureSize)/2, (subjectTarget.texture.height - captureSize)/2, captureSize, captureSize, GREEN);
DrawText("Subject View", 10, subjectTarget.texture.height - 30, 20, BLACK);
EndTextureMode();
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(BLACK);
// Draw observer texture LHS
DrawTexturePro(observerTarget.texture, observerSource, observerDest, (Vector2){0.0f, 0.0f }, 0.0f, WHITE);
// Draw subject texture RHS
DrawTexturePro(subjectTarget.texture, subjectSource, subjectDest, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
// Draw the small crop overlay on top
DrawTexturePro(subjectTarget.texture, cropSource, cropDest, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
DrawRectangleLinesEx(cropDest, 2, BLACK);
// Draw split screen divider line
DrawLine(splitWidth, 0, splitWidth, screenHeight, BLACK);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadRenderTexture(observerTarget);
UnloadRenderTexture(subjectTarget);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
static void DrawCameraPrism(Camera3D camera, float aspect, Color color)
{
float length = Vector3Distance(camera.position, camera.target);
// Define the 4 corners of the camera's prism plane sliced at the target in Normalized Device Coordinates
Vector3 planeNDC[4] = {
{ -1.0f, -1.0f, 1.0f }, // Bottom Left
{ 1.0f, -1.0f, 1.0f }, // Bottom Right
{ 1.0f, 1.0f, 1.0f }, // Top Right
{ -1.0f, 1.0f, 1.0f } // Top Left
};
// Build the matrices
Matrix view = GetCameraMatrix(camera);
Matrix proj = MatrixPerspective(camera.fovy * DEG2RAD, aspect, 0.05f, length);
// Combine view and projection so we can reverse the full camera transform
Matrix viewProj = MatrixMultiply(view, proj);
// Invert the view-projection matrix to unproject points from NDC space back into world space
Matrix inverseViewProj = MatrixInvert(viewProj);
// Transform the 4 plane corners from NDC into world space
Vector3 corners[4];
for (int i = 0; i < 4; i++)
{
float x = planeNDC[i].x;
float y = planeNDC[i].y;
float z = planeNDC[i].z;
// Multiply NDC position by the inverse view-projection matrix
// This produces a homogeneous (x, y, z, w) position in world space
float vx = inverseViewProj.m0*x + inverseViewProj.m4*y + inverseViewProj.m8*z + inverseViewProj.m12;
float vy = inverseViewProj.m1*x + inverseViewProj.m5*y + inverseViewProj.m9*z + inverseViewProj.m13;
float vz = inverseViewProj.m2*x + inverseViewProj.m6*y + inverseViewProj.m10*z + inverseViewProj.m14;
float vw = inverseViewProj.m3*x + inverseViewProj.m7*y + inverseViewProj.m11*z + inverseViewProj.m15;
corners[i] = (Vector3){ vx/vw, vy/vw, vz/vw };
}
// Draw the far plane sliced at the target
DrawLine3D(corners[0], corners[1], color);
DrawLine3D(corners[1], corners[2], color);
DrawLine3D(corners[2], corners[3], color);
DrawLine3D(corners[3], corners[0], color);
// Draw the prism lines from the far plane to the camera position
for (int i = 0; i < 4; i++)
{
DrawLine3D(camera.position, corners[i], color);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -156,7 +156,7 @@ int main(void)
{ {
DrawRectangleRec(toggleRecs[i], ((i == currentProcess) || (i == mouseHoverRec)) ? SKYBLUE : LIGHTGRAY); DrawRectangleRec(toggleRecs[i], ((i == currentProcess) || (i == mouseHoverRec)) ? SKYBLUE : LIGHTGRAY);
DrawRectangleLines((int)toggleRecs[i].x, (int) toggleRecs[i].y, (int) toggleRecs[i].width, (int) toggleRecs[i].height, ((i == currentProcess) || (i == mouseHoverRec)) ? BLUE : GRAY); DrawRectangleLines((int)toggleRecs[i].x, (int) toggleRecs[i].y, (int) toggleRecs[i].width, (int) toggleRecs[i].height, ((i == currentProcess) || (i == mouseHoverRec)) ? BLUE : GRAY);
DrawText( processText[i], (int)( toggleRecs[i].x + toggleRecs[i].width/2 - MeasureText(processText[i], 10)/2), (int) toggleRecs[i].y + 11, 10, ((i == currentProcess) || (i == mouseHoverRec)) ? DARKBLUE : DARKGRAY); DrawText( processText[i], (int)( toggleRecs[i].x + toggleRecs[i].width/2 - (float)MeasureText(processText[i], 10)/2), (int) toggleRecs[i].y + 11, 10, ((i == currentProcess) || (i == mouseHoverRec)) ? DARKBLUE : DARKGRAY);
} }
DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE); DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE);

View File

@ -38,7 +38,7 @@ int main(void)
Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM) Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
Vector2 position = { (float)(screenWidth/2 - texture.width/2), (float)(screenHeight/2 - texture.height/2 - 20) }; Vector2 position = { (float)screenWidth/2 - (float)texture.width/2, (float)screenHeight/2 - (float)texture.height/2 - 20 };
bool showFont = false; bool showFont = false;

View File

@ -66,7 +66,7 @@ int main(void)
// Grow flameRoot // Grow flameRoot
for (int x = 2; x < flameWidth; x++) for (int x = 2; x < flameWidth; x++)
{ {
unsigned short flame = flameRootBuffer[x]; unsigned char flame = flameRootBuffer[x];
if (flame == 255) continue; if (flame == 255) continue;
flame += GetRandomValue(0, 2); flame += GetRandomValue(0, 2);
if (flame > 255) flame = 255; if (flame > 255) flame = 255;

View File

@ -39,7 +39,7 @@ int main(void)
Rectangle sourceRec = { 0, 0, (float)button.width, frameHeight }; Rectangle sourceRec = { 0, 0, (float)button.width, frameHeight };
// Define button bounds on screen // Define button bounds on screen
Rectangle btnBounds = { screenWidth/2.0f - button.width/2.0f, screenHeight/2.0f - button.height/NUM_FRAMES/2.0f, (float)button.width, frameHeight }; Rectangle btnBounds = { screenWidth/2.0f - button.width/2.0f, screenHeight/2.0f - (float)button.height/NUM_FRAMES/2.0f, (float)button.width, frameHeight };
int btnState = 0; // Button state: 0-NORMAL, 1-MOUSE_HOVER, 2-PRESSED int btnState = 0; // Button state: 0-NORMAL, 1-MOUSE_HOVER, 2-PRESSED
bool btnAction = false; // Button action should be activated bool btnAction = false; // Button action should be activated

View File

@ -39,8 +39,8 @@ int main(void)
Texture2D explosion = LoadTexture("resources/explosion.png"); Texture2D explosion = LoadTexture("resources/explosion.png");
// Init variables for animation // Init variables for animation
float frameWidth = (float)(explosion.width/NUM_FRAMES_PER_LINE); // Sprite one frame rectangle width float frameWidth = (float)explosion.width/NUM_FRAMES_PER_LINE; // Sprite one frame rectangle width
float frameHeight = (float)(explosion.height/NUM_LINES); // Sprite one frame rectangle height float frameHeight = (float)explosion.height/NUM_LINES; // Sprite one frame rectangle height
int currentFrame = 0; int currentFrame = 0;
int currentLine = 0; int currentLine = 0;

View File

@ -190,7 +190,7 @@ static void DrawTexturedCurve(void)
Vector2 normal = Vector2Normalize((Vector2){ -delta.y, delta.x }); Vector2 normal = Vector2Normalize((Vector2){ -delta.y, delta.x });
// The v texture coordinate of the segment (add up the length of all the segments so far) // The v texture coordinate of the segment (add up the length of all the segments so far)
float v = previousV + Vector2Length(delta); float v = previousV + Vector2Length(delta) / (float)(texRoad.height * 2);
// Make sure the start point has a normal // Make sure the start point has a normal
if (!tangentSet) if (!tangentSet)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

After

Width:  |  Height:  |  Size: 490 B

View File

@ -0,0 +1,569 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug.DLL|ARM64">
<Configuration>Debug.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|Win32">
<Configuration>Debug.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|x64">
<Configuration>Debug.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|ARM64">
<Configuration>Release.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|Win32">
<Configuration>Release.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|x64">
<Configuration>Release.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D35D2FDA-B53F-4F70-81CA-24D95812B89C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>core_keyboard_testbed</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>core_keyboard_testbed</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\core\core_keyboard_testbed.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\examples\examples.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,569 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug.DLL|ARM64">
<Configuration>Debug.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|Win32">
<Configuration>Debug.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|x64">
<Configuration>Debug.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|ARM64">
<Configuration>Release.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|Win32">
<Configuration>Release.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|x64">
<Configuration>Release.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{DC163251-16C3-4B72-B965-ACDBA0F02BD1}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>shapes_hilbert_curve</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>shapes_hilbert_curve</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\shapes\shapes_hilbert_curve.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\examples\examples.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -292,7 +292,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -309,7 +309,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
@ -345,7 +345,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -366,7 +366,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -410,7 +410,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -432,7 +432,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -476,7 +476,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -504,7 +504,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>

View File

@ -292,7 +292,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -309,7 +309,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
@ -345,7 +345,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -366,7 +366,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -410,7 +410,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -432,7 +432,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -476,7 +476,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -504,7 +504,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>

View File

@ -0,0 +1,569 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug.DLL|ARM64">
<Configuration>Debug.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|Win32">
<Configuration>Debug.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|x64">
<Configuration>Debug.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|ARM64">
<Configuration>Release.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|Win32">
<Configuration>Release.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|x64">
<Configuration>Release.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>textures_framebuffer_rendering</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>textures_framebuffer_rendering</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\textures\textures_framebuffer_rendering.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\examples\examples.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -57,7 +57,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_custom_logging", "exam
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_drop_files", "examples\core_drop_files.vcxproj", "{0199E349-0701-40BC-8A7F-06A54FFA3E7C}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_drop_files", "examples\core_drop_files.vcxproj", "{0199E349-0701-40BC-8A7F-06A54FFA3E7C}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_high_dpi", "examples\core_high_dpi.vcxproj", "{BCB71111-8505-4B35-8CEF-EC6115DC9D4D}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_highdpi_demo", "examples\core_highdpi_demo.vcxproj", "{BCB71111-8505-4B35-8CEF-EC6115DC9D4D}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gamepad", "examples\core_input_gamepad.vcxproj", "{8F19E3DA-8929-4000-87B5-3CA6929636CC}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gamepad", "examples\core_input_gamepad.vcxproj", "{8F19E3DA-8929-4000-87B5-3CA6929636CC}"
EndProject EndProject
@ -431,6 +431,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_strings_management", "
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_cellular_automata", "examples\textures_cellular_automata.vcxproj", "{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_cellular_automata", "examples\textures_cellular_automata.vcxproj", "{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_hilbert_curve", "examples\shapes_hilbert_curve.vcxproj", "{DC163251-16C3-4B72-B965-ACDBA0F02BD1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_keyboard_testbed", "examples\core_keyboard_testbed.vcxproj", "{D35D2FDA-B53F-4F70-81CA-24D95812B89C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_rendering", "examples\textures_framebuffer_rendering.vcxproj", "{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug.DLL|ARM64 = Debug.DLL|ARM64 Debug.DLL|ARM64 = Debug.DLL|ARM64
@ -5365,6 +5371,78 @@ Global
{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x64.Build.0 = Release|x64 {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x64.Build.0 = Release|x64
{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x86.ActiveCfg = Release|Win32 {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x86.ActiveCfg = Release|Win32
{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x86.Build.0 = Release|Win32 {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x86.Build.0 = Release|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.ActiveCfg = Debug|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.Build.0 = Debug|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.ActiveCfg = Debug|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.Build.0 = Debug|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.ActiveCfg = Debug|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.Build.0 = Debug|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.Build.0 = Release.DLL|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.ActiveCfg = Release|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.Build.0 = Release|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.ActiveCfg = Release|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.Build.0 = Release|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.ActiveCfg = Release|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.Build.0 = Release|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.Build.0 = Debug|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.ActiveCfg = Debug|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.Build.0 = Debug|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.ActiveCfg = Debug|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.Build.0 = Debug|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.Build.0 = Release.DLL|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.ActiveCfg = Release|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.Build.0 = Release|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.ActiveCfg = Release|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.Build.0 = Release|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.ActiveCfg = Release|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.Build.0 = Release|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.Build.0 = Debug|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.ActiveCfg = Debug|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.Build.0 = Debug|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.ActiveCfg = Debug|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.Build.0 = Debug|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.Build.0 = Release.DLL|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.ActiveCfg = Release|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.Build.0 = Release|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.ActiveCfg = Release|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.Build.0 = Release|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.ActiveCfg = Release|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -5532,7 +5610,7 @@ Global
{C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} {9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}
{0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
@ -5541,9 +5619,9 @@ Global
{3B27F358-2679-4F38-B297-17B536F580BB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {3B27F358-2679-4F38-B297-17B536F580BB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {718FCBD0-591D-448C-B7D5-9F1CA8544E7B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{19CA0070-B4B2-4394-90B7-D0C259AA35BA} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {19CA0070-B4B2-4394-90B7-D0C259AA35BA} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {278D8859-20B1-428F-8448-064F46E1F021} {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
{9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{8E132D5A-2C00-48D0-8747-97E41356F26F} = {278D8859-20B1-428F-8448-064F46E1F021} {8E132D5A-2C00-48D0-8747-97E41356F26F} = {278D8859-20B1-428F-8448-064F46E1F021}
{A4662163-83E7-4309-8CAA-B0BF13655FE6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {A4662163-83E7-4309-8CAA-B0BF13655FE6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{5F4B766F-DD52-4B53-B6C3-BC7611E17F20} = {278D8859-20B1-428F-8448-064F46E1F021} {5F4B766F-DD52-4B53-B6C3-BC7611E17F20} = {278D8859-20B1-428F-8448-064F46E1F021}
@ -5559,7 +5637,7 @@ Global
{124935CC-73BB-489E-92E8-4F922A85DB5D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {124935CC-73BB-489E-92E8-4F922A85DB5D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{AC215730-2B5F-4498-B7F5-5DB80AEFCA5F} = {278D8859-20B1-428F-8448-064F46E1F021} {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F} = {278D8859-20B1-428F-8448-064F46E1F021}
{0835E6BF-0170-4E99-A55C-E06E1EF4C3B2} = {278D8859-20B1-428F-8448-064F46E1F021} {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2} = {278D8859-20B1-428F-8448-064F46E1F021}
{EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {278D8859-20B1-428F-8448-064F46E1F021}
{1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{9DE2FC01-A839-4F89-8319-9071D4C54821} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {9DE2FC01-A839-4F89-8319-9071D4C54821} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{2F578155-D51F-4C03-AB7F-5C5122CA46CC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {2F578155-D51F-4C03-AB7F-5C5122CA46CC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
@ -5582,6 +5660,9 @@ Global
{7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC} = {278D8859-20B1-428F-8448-064F46E1F021} {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC} = {278D8859-20B1-428F-8448-064F46E1F021}
{1F4722E7-F78E-413F-A106-D3490211EA57} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {1F4722E7-F78E-413F-A106-D3490211EA57} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{0A0FC982-6E31-401F-BA77-3C5E8AB02C68} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {0A0FC982-6E31-401F-BA77-3C5E8AB02C68} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
{DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021}
{D35D2FDA-B53F-4F70-81CA-24D95812B89C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}

View File

@ -582,7 +582,6 @@
<ClCompile Include="..\..\..\src\rshapes.c" /> <ClCompile Include="..\..\..\src\rshapes.c" />
<ClCompile Include="..\..\..\src\rtext.c" /> <ClCompile Include="..\..\..\src\rtext.c" />
<ClCompile Include="..\..\..\src\rtextures.c" /> <ClCompile Include="..\..\..\src\rtextures.c" />
<ClCompile Include="..\..\..\src\utils.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\src\external\cgltf.h" /> <ClInclude Include="..\..\..\src\external\cgltf.h" />
@ -602,7 +601,6 @@
<ClInclude Include="..\..\..\src\raylib.h" /> <ClInclude Include="..\..\..\src\raylib.h" />
<ClInclude Include="..\..\..\src\raymath.h" /> <ClInclude Include="..\..\..\src\raymath.h" />
<ClInclude Include="..\..\..\src\rlgl.h" /> <ClInclude Include="..\..\..\src\rlgl.h" />
<ClInclude Include="..\..\..\src\utils.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\..\..\src\raylib.dll.rc" /> <ResourceCompile Include="..\..\..\src\raylib.dll.rc" />

View File

@ -22,9 +22,6 @@
<ClCompile Include="..\..\..\src\rtextures.c"> <ClCompile Include="..\..\..\src\rtextures.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\utils.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\platforms\rcore_android.c"> <ClCompile Include="..\..\..\src\platforms\rcore_android.c">
<Filter>Source Files\Platform Files</Filter> <Filter>Source Files\Platform Files</Filter>
</ClCompile> </ClCompile>

View File

@ -15,7 +15,7 @@
* This example has been created using raylib 1.0 (www.raylib.com) * This example has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -36,7 +36,6 @@ set(raylib_sources
rshapes.c rshapes.c
rtext.c rtext.c
rtextures.c rtextures.c
utils.c
) )
# <root>/cmake/GlfwImport.cmake handles the details around the inclusion of glfw # <root>/cmake/GlfwImport.cmake handles the details around the inclusion of glfw

View File

@ -33,7 +33,7 @@
# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline. # Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline.
# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline. # Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
# #
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.
@ -658,8 +658,7 @@ endif
OBJS = rcore.o \ OBJS = rcore.o \
rshapes.o \ rshapes.o \
rtextures.o \ rtextures.o \
rtext.o \ rtext.o
utils.o
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(USE_EXTERNAL_GLFW),FALSE) ifeq ($(USE_EXTERNAL_GLFW),FALSE)
@ -758,7 +757,7 @@ endif
rcore.o : platforms/*.c rcore.o : platforms/*.c
# Compile core module # Compile core module
rcore.o : rcore.c raylib.h rlgl.h utils.h raymath.h rcamera.h rgestures.h rcore.o : rcore.c raylib.h rlgl.h raymath.h rcamera.h rgestures.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile rglfw module # Compile rglfw module
@ -770,15 +769,11 @@ rshapes.o : rshapes.c raylib.h rlgl.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile textures module # Compile textures module
rtextures.o : rtextures.c raylib.h rlgl.h utils.h rtextures.o : rtextures.c raylib.h rlgl.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile text module # Compile text module
rtext.o : rtext.c raylib.h utils.h rtext.o : rtext.c raylib.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile utils module
utils.o : utils.c utils.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile models module # Compile models module

View File

@ -6,7 +6,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2018-2025 Ahmad Fatoum & Ramon Santamaria (@raysan5) * Copyright (c) 2018-2026 Ahmad Fatoum and Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -30,17 +30,24 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module selection - Some modules could be avoided // Module selection - Some modules could be avoided
// Mandatory modules: rcore, rlgl, utils // Mandatory modules: rcore, rlgl
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#define SUPPORT_MODULE_RSHAPES 1 #if !defined(EXTERNAL_CONFIG_FLAGS)
#define SUPPORT_MODULE_RTEXTURES 1 #define SUPPORT_MODULE_RSHAPES 1
#define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures #define SUPPORT_MODULE_RTEXTURES 1
#define SUPPORT_MODULE_RMODELS 1 #define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures
#define SUPPORT_MODULE_RAUDIO 1 #define SUPPORT_MODULE_RMODELS 1
#define SUPPORT_MODULE_RAUDIO 1
#endif
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rcore - Configuration Flags // Module: rcore - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Standard file io library (stdio.h) included
#define SUPPORT_STANDARD_FILEIO 1
// Show TRACELOG() output messages
#define SUPPORT_TRACELOG 1
// Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital // Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
#define SUPPORT_CAMERA_SYSTEM 1 #define SUPPORT_CAMERA_SYSTEM 1
// Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag // Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
@ -69,10 +76,10 @@
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // 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 // Enabling this flag allows manual control of the frame processes, use at your own risk
//#define SUPPORT_CUSTOM_FRAME_CONTROL 1 //#define SUPPORT_CUSTOM_FRAME_CONTROL 1
// Support for clipboard image loading // Support for clipboard image loading
// NOTE: Only working on SDL3, GLFW (Windows) and RGFW (Windows) // NOTE: Only working on SDL3, GLFW (Windows) and RGFW (Windows)
#define SUPPORT_CLIPBOARD_IMAGE 1 #define SUPPORT_CLIPBOARD_IMAGE 1
#endif
// NOTE: Clipboard image loading requires support for some image file formats // NOTE: Clipboard image loading requires support for some image file formats
// TODO: Those defines should probably be removed from here, letting the user manage them // TODO: Those defines should probably be removed from here, letting the user manage them
@ -94,8 +101,15 @@
#endif #endif
#endif #endif
#if defined(SUPPORT_TRACELOG)
#define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__)
#else
#define TRACELOG(level, ...) (void)0
#endif
// rcore: Configuration values // rcore: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
#define MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity #define MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity
#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) #define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value)
@ -105,7 +119,7 @@
#define MAX_GAMEPAD_AXES 8 // Maximum number of axes supported (per gamepad) #define MAX_GAMEPAD_AXES 8 // Maximum number of axes supported (per gamepad)
#define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad)
#define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds #define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds
#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #define MAX_TOUCH_POINTS 10 // Maximum number of touch points supported
#define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue
#define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue
@ -116,7 +130,7 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rlgl - Configuration values // Module: rlgl - Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Enable OpenGL Debug Context (only available on OpenGL 4.3) // Enable OpenGL Debug Context (only available on OpenGL 4.3)
//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1 //#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1
@ -124,6 +138,7 @@
//#define RLGL_SHOW_GL_DETAILS_INFO 1 //#define RLGL_SHOW_GL_DETAILS_INFO 1
#define RL_SUPPORT_MESH_GPU_SKINNING 1 // GPU skinning, comment if your GPU does not support more than 8 VBOs #define RL_SUPPORT_MESH_GPU_SKINNING 1 // GPU skinning, comment if your GPU does not support more than 8 VBOs
#endif
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits //#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits
#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
@ -173,9 +188,11 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rshapes - Configuration Flags // Module: rshapes - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Use QUADS instead of TRIANGLES for drawing when possible // Use QUADS instead of TRIANGLES for drawing when possible
// Some lines-based shapes could still use lines // Some lines-based shapes could still use lines
#define SUPPORT_QUADS_DRAW_MODE 1 #define SUPPORT_QUADS_DRAW_MODE 1
#endif
// rshapes: Configuration values // rshapes: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -184,6 +201,7 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rtextures - Configuration Flags // Module: rtextures - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Selected desired fileformats to be supported for image data loading // Selected desired fileformats to be supported for image data loading
#define SUPPORT_FILEFORMAT_PNG 1 #define SUPPORT_FILEFORMAT_PNG 1
//#define SUPPORT_FILEFORMAT_BMP 1 //#define SUPPORT_FILEFORMAT_BMP 1
@ -207,10 +225,12 @@
// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... // Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop...
// If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT() // If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT()
#define SUPPORT_IMAGE_MANIPULATION 1 #define SUPPORT_IMAGE_MANIPULATION 1
#endif
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rtext - Configuration Flags // Module: rtext - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Default font is loaded on window initialization to be available for the user to render simple text // Default font is loaded on window initialization to be available for the user to render simple text
// NOTE: If enabled, uses external module functions to load default raylib font // NOTE: If enabled, uses external module functions to load default raylib font
#define SUPPORT_DEFAULT_FONT 1 #define SUPPORT_DEFAULT_FONT 1
@ -230,6 +250,7 @@
// Support conservative font atlas size estimation // Support conservative font atlas size estimation
//#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE 1 //#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE 1
#endif
// rtext: Configuration values // rtext: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -240,6 +261,7 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rmodels - Configuration Flags // Module: rmodels - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Selected desired model fileformats to be supported for loading // Selected desired model fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_OBJ 1 #define SUPPORT_FILEFORMAT_OBJ 1
#define SUPPORT_FILEFORMAT_MTL 1 #define SUPPORT_FILEFORMAT_MTL 1
@ -250,6 +272,7 @@
// Support procedural mesh generation functions, uses external par_shapes.h library // Support procedural mesh generation functions, uses external par_shapes.h library
// NOTE: Some generated meshes DO NOT include generated texture coordinates // NOTE: Some generated meshes DO NOT include generated texture coordinates
#define SUPPORT_MESH_GENERATION 1 #define SUPPORT_MESH_GENERATION 1
#endif
// rmodels: Configuration values // rmodels: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -264,6 +287,7 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: raudio - Configuration Flags // Module: raudio - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Desired audio fileformats to be supported for loading // Desired audio fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_WAV 1 #define SUPPORT_FILEFORMAT_WAV 1
#define SUPPORT_FILEFORMAT_OGG 1 #define SUPPORT_FILEFORMAT_OGG 1
@ -272,6 +296,7 @@
//#define SUPPORT_FILEFORMAT_FLAC 1 //#define SUPPORT_FILEFORMAT_FLAC 1
#define SUPPORT_FILEFORMAT_XM 1 #define SUPPORT_FILEFORMAT_XM 1
#define SUPPORT_FILEFORMAT_MOD 1 #define SUPPORT_FILEFORMAT_MOD 1
#endif
// raudio: Configuration values // raudio: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -281,18 +306,4 @@
#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels
//------------------------------------------------------------------------------------
// Module: utils - Configuration Flags
//------------------------------------------------------------------------------------
// Standard file io library (stdio.h) included
#define SUPPORT_STANDARD_FILEIO 1
// Show TRACELOG() output messages
// NOTE: By default LOG_DEBUG traces not shown
#define SUPPORT_TRACELOG 1
//#define SUPPORT_TRACELOG_DEBUG 1
// utils: Configuration values
//------------------------------------------------------------------------------------
#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
#endif // CONFIG_H #endif // CONFIG_H

22
src/external/RGFW.h vendored
View File

@ -669,7 +669,8 @@ typedef struct RGFW_event {
typedef struct RGFW_window_src { typedef struct RGFW_window_src {
HWND window; /*!< source window */ HWND window; /*!< source window */
HDC hdc; /*!< source HDC */ HDC hdc; /*!< source HDC */
u32 hOffset; /*!< height offset for window */ i32 wOffset; /*!< width offset for window */
i32 hOffset; /*!< height offset for window */
HICON hIconSmall, hIconBig; /*!< source window icons */ HICON hIconSmall, hIconBig; /*!< source window icons */
#if (defined(RGFW_OPENGL)) && !defined(RGFW_OSMESA) && !defined(RGFW_EGL) #if (defined(RGFW_OPENGL)) && !defined(RGFW_OSMESA) && !defined(RGFW_EGL)
HGLRC ctx; /*!< source graphics context */ HGLRC ctx; /*!< source graphics context */
@ -6522,8 +6523,8 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (win->src.aspectRatio.w != 0 && win->src.aspectRatio.h != 0) { if (win->src.aspectRatio.w != 0 && win->src.aspectRatio.h != 0) {
double aspectRatio = (double)win->src.aspectRatio.w / win->src.aspectRatio.h; double aspectRatio = (double)win->src.aspectRatio.w / win->src.aspectRatio.h;
int width = windowRect.right - windowRect.left; int width = (windowRect.right - windowRect.left) - win->src.wOffset;
int height = windowRect.bottom - windowRect.top; int height = (windowRect.bottom - windowRect.top) - win->src.hOffset;
int newHeight = (int)(width / aspectRatio); int newHeight = (int)(width / aspectRatio);
int newWidth = (int)(height * aspectRatio); int newWidth = (int)(height * aspectRatio);
@ -6537,11 +6538,11 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
else windowRect.bottom = windowRect.top + newHeight; else windowRect.bottom = windowRect.top + newHeight;
} }
RGFW_window_resize(win, RGFW_AREA((windowRect.right - windowRect.left), RGFW_window_resize(win, RGFW_AREA((u32)(windowRect.right - windowRect.left) - (u32)win->src.wOffset,
(u32)(windowRect.bottom - windowRect.top) - (u32)win->src.hOffset)); (u32)(windowRect.bottom - windowRect.top) - (u32)win->src.hOffset));
} }
win->r.w = windowRect.right - windowRect.left; win->r.w = (windowRect.right - windowRect.left) - (i32)win->src.wOffset;
win->r.h = (windowRect.bottom - windowRect.top) - (i32)win->src.hOffset; win->r.h = (windowRect.bottom - windowRect.top) - (i32)win->src.hOffset;
RGFW_eventQueuePushEx(e.type = RGFW_windowResized; e._win = win); RGFW_eventQueuePushEx(e.type = RGFW_windowResized; e._win = win);
RGFW_windowResizedCallback(win, win->r); RGFW_windowResizedCallback(win, win->r);
@ -6561,12 +6562,12 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
#endif #endif
case WM_GETMINMAXINFO: { case WM_GETMINMAXINFO: {
MINMAXINFO* mmi = (MINMAXINFO*) lParam; MINMAXINFO* mmi = (MINMAXINFO*) lParam;
mmi->ptMinTrackSize.x = (LONG)win->src.minSize.w; mmi->ptMinTrackSize.x = (LONG)(win->src.minSize.w + win->src.wOffset);
mmi->ptMinTrackSize.y = (LONG)(win->src.minSize.h + win->src.hOffset); mmi->ptMinTrackSize.y = (LONG)(win->src.minSize.h + win->src.hOffset);
if (win->src.maxSize.w == 0 && win->src.maxSize.h == 0) if (win->src.maxSize.w == 0 && win->src.maxSize.h == 0)
return DefWindowProcW(hWnd, message, wParam, lParam); return DefWindowProcW(hWnd, message, wParam, lParam);
mmi->ptMaxTrackSize.x = (LONG)win->src.maxSize.w; mmi->ptMaxTrackSize.x = (LONG)(win->src.maxSize.w + win->src.wOffset);
mmi->ptMaxTrackSize.y = (LONG)(win->src.maxSize.h + win->src.hOffset); mmi->ptMaxTrackSize.y = (LONG)(win->src.maxSize.h + win->src.hOffset);
return DefWindowProcW(hWnd, message, wParam, lParam); return DefWindowProcW(hWnd, message, wParam, lParam);
} }
@ -6968,7 +6969,8 @@ RGFW_window* RGFW_createWindowPtr(const char* name, RGFW_rect rect, RGFW_windowF
DestroyWindow(dummyWin); DestroyWindow(dummyWin);
win->src.hOffset = (u32)(windowRect.bottom - windowRect.top) - (u32)(clientRect.bottom - clientRect.top); win->src.hOffset = (u32)(windowRect.bottom - windowRect.top) - (u32)(clientRect.bottom - clientRect.top);
win->src.window = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->r.x, win->r.y, win->r.w, win->r.h + (i32)win->src.hOffset, 0, 0, inh, 0); win->src.wOffset = (u32)(windowRect.right - windowRect.left) - (u32)(clientRect.right - clientRect.left);
win->src.window = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->r.x, win->r.y, win->r.w + (i32)win->src.wOffset, win->r.h + (i32)win->src.hOffset, 0, 0, inh, 0);
SetPropW(win->src.window, L"RGFW", win); SetPropW(win->src.window, L"RGFW", win);
RGFW_window_resize(win, RGFW_AREA(win->r.w, win->r.h)); /* so WM_GETMINMAXINFO gets called again */ RGFW_window_resize(win, RGFW_AREA(win->r.w, win->r.h)); /* so WM_GETMINMAXINFO gets called again */
@ -7064,7 +7066,7 @@ void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) {
if (fullscreen == RGFW_FALSE) { if (fullscreen == RGFW_FALSE) {
RGFW_window_setBorder(win, 1); RGFW_window_setBorder(win, 1);
SetWindowPos(win->src.window, HWND_NOTOPMOST, win->_oldRect.x, win->_oldRect.y, win->_oldRect.w, win->_oldRect.h + (i32)win->src.hOffset, SetWindowPos(win->src.window, HWND_NOTOPMOST, win->_oldRect.x, win->_oldRect.y, win->_oldRect.w + (i32)win->src.wOffset, win->_oldRect.h + (i32)win->src.hOffset,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED); SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
win->_flags &= ~(u32)RGFW_windowFullscreen; win->_flags &= ~(u32)RGFW_windowFullscreen;
@ -7898,7 +7900,7 @@ void RGFW_window_resize(RGFW_window* win, RGFW_area a) {
win->r.w = (i32)a.w; win->r.w = (i32)a.w;
win->r.h = (i32)a.h; win->r.h = (i32)a.h;
SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w, win->r.h + (i32)win->src.hOffset, SWP_NOMOVE); SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w + (i32)win->src.wOffset, win->r.h + (i32)win->src.hOffset, SWP_NOMOVE);
} }

File diff suppressed because it is too large Load Diff

View File

@ -62,7 +62,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -308,7 +308,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
unsigned char alpha = 0; unsigned char alpha = 0;
// NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1 // NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1
for (int i = 0; i < image_pixel_size; i++) for (int i = 0; i < data_size/sizeof(unsigned short); i++)
{ {
alpha = ((unsigned short *)image_data)[i] >> 15; alpha = ((unsigned short *)image_data)[i] >> 15;
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 1; ((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 1;
@ -328,7 +328,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
unsigned char alpha = 0; unsigned char alpha = 0;
// NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4 // NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4
for (int i = 0; i < image_pixel_size; i++) for (int i = 0; i < data_size/sizeof(unsigned short); i++)
{ {
alpha = ((unsigned short *)image_data)[i] >> 12; alpha = ((unsigned short *)image_data)[i] >> 12;
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 4; ((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 4;
@ -339,7 +339,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
} }
} }
} }
else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed
{ {
int data_size = image_pixel_size*3*sizeof(unsigned char); int data_size = image_pixel_size*3*sizeof(unsigned char);
if (header->mipmap_count > 1) data_size = data_size + data_size/3; if (header->mipmap_count > 1) data_size = data_size + data_size/3;
@ -362,7 +362,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
// NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment) // NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment)
// DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA // DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA
// So, we must realign B8G8R8A8 to R8G8B8A8 // So, we must realign B8G8R8A8 to R8G8B8A8
for (int i = 0; i < image_pixel_size*4; i += 4) for (int i = 0; i < data_size; i += 4)
{ {
blue = ((unsigned char *)image_data)[i]; blue = ((unsigned char *)image_data)[i];
((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2]; ((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2];

58
src/external/rlsw.h vendored
View File

@ -1177,7 +1177,7 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4])
static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4])
{ {
#if defined(SW_HAS_NEON) #if defined(SW_HAS_NEON)
uint8x8_t bytes8 = vld1_u8(src); //< Read 8 bytes, faster, but let's hope we're not at the end of the page (unlikely)... uint8x8_t bytes8 = vld1_u8(src); // Reading 8 bytes, faster, but let's hope not hitting the end of the page (unlikely)...
uint16x8_t bytes16 = vmovl_u8(bytes8); uint16x8_t bytes16 = vmovl_u8(bytes8);
uint32x4_t ints = vmovl_u16(vget_low_u16(bytes16)); uint32x4_t ints = vmovl_u16(vget_low_u16(bytes16));
float32x4_t floats = vcvtq_f32_u32(ints); float32x4_t floats = vcvtq_f32_u32(ints);
@ -1224,8 +1224,8 @@ static inline uint32_t sw_half_to_float_ui(uint16_t h)
// denormal: flush to zero // denormal: flush to zero
r = (em < (1 << 10))? 0 : r; r = (em < (1 << 10))? 0 : r;
// infinity/NaN; note that we preserve NaN payload as a byproduct of unifying inf/nan cases // NOTE: infinity/NaN; NaN payload is preserved as a byproduct of unifying inf/nan cases
// 112 is an exponent bias fixup; since we already applied it once, applying it twice converts 31 to 255 // 112 is an exponent bias fixup; since it is already applied once, applying it twice converts 31 to 255
r += (em >= (31 << 10))? (112 << 23) : 0; r += (em >= (31 << 10))? (112 << 23) : 0;
return s | r; return s | r;
@ -1252,7 +1252,7 @@ static inline uint16_t sw_half_from_float_ui(uint32_t ui)
// Overflow: infinity; 143 encodes exponent 16 // Overflow: infinity; 143 encodes exponent 16
h = (em >= (143 << 23))? 0x7c00 : h; h = (em >= (143 << 23))? 0x7c00 : h;
// NaN; note that we convert all types of NaN to qNaN // NOTE: NaN; all types of NaN aree converted to qNaN
h = (em > (255 << 23))? 0x7e00 : h; h = (em > (255 << 23))? 0x7e00 : h;
return (uint16_t)(s | h); return (uint16_t)(s | h);
@ -1918,8 +1918,8 @@ static inline void sw_texture_sample_nearest(float *color, const sw_texture_t *t
static inline void sw_texture_sample_linear(float *color, const sw_texture_t *tex, float u, float v) static inline void sw_texture_sample_linear(float *color, const sw_texture_t *tex, float u, float v)
{ {
// TODO: With a bit more cleverness we could clearly reduce the // TODO: With a bit more cleverness thee number of operations can
// number of operations here, but for now it works fine // be clearly reduced, but for now it works fine
float xf = (u*tex->width) - 0.5f; float xf = (u*tex->width) - 0.5f;
float yf = (v*tex->height) - 0.5f; float yf = (v*tex->height) - 0.5f;
@ -1933,7 +1933,7 @@ static inline void sw_texture_sample_linear(float *color, const sw_texture_t *te
int x1 = x0 + 1; int x1 = x0 + 1;
int y1 = y0 + 1; int y1 = y0 + 1;
// NOTE: If the textures are POT we could avoid the division for SW_REPEAT // NOTE: If the textures are POT, avoid the division for SW_REPEAT
if (tex->sWrap == SW_CLAMP) if (tex->sWrap == SW_CLAMP)
{ {
@ -1974,7 +1974,7 @@ static inline void sw_texture_sample_linear(float *color, const sw_texture_t *te
static inline void sw_texture_sample(float *color, const sw_texture_t *tex, float u, float v, float dUdx, float dUdy, float dVdx, float dVdy) static inline void sw_texture_sample(float *color, const sw_texture_t *tex, float u, float v, float dUdx, float dUdy, float dVdx, float dVdy)
{ {
// Previous method: There is no need to compute the square root // Previous method: There is no need to compute the square root
// because using the squared value, the comparison remains `L2 > 1.0f*1.0f` // because using the squared value, the comparison remains (L2 > 1.0f*1.0f)
//float du = sqrtf(dUdx*dUdx + dUdy*dUdy); //float du = sqrtf(dUdx*dUdx + dUdy*dUdy);
//float dv = sqrtf(dVdx*dVdx + dVdy*dVdy); //float dv = sqrtf(dVdx*dVdx + dVdy*dVdy);
//float L = (du > dv)? du : dv; //float L = (du > dv)? du : dv;
@ -2204,12 +2204,12 @@ static inline bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VE
static inline bool sw_triangle_face_culling(void) static inline bool sw_triangle_face_culling(void)
{ {
// NOTE: Face culling is done before clipping to avoid unnecessary computations // NOTE: Face culling is done before clipping to avoid unnecessary computations
// To handle triangles crossing the w=0 plane correctly, // To handle triangles crossing the w=0 plane correctly,
// we perform the winding order test in homogeneous coordinates directly, // the winding order test is performeed in homogeneous coordinates directly,
// before the perspective division (division by w) // before the perspective division (division by w)
// This test determines the orientation of the triangle in the (x,y,w) plane, // This test determines the orientation of the triangle in the (x,y,w) plane,
// which corresponds to the projected 2D winding order sign, // which corresponds to the projected 2D winding order sign,
// even with negative w values // even with negative w values
// Preload homogeneous coordinates into local variables // Preload homogeneous coordinates into local variables
const float *h0 = RLSW.vertexBuffer[0].homogeneous; const float *h0 = RLSW.vertexBuffer[0].homogeneous;
@ -2217,7 +2217,7 @@ static inline bool sw_triangle_face_culling(void)
const float *h2 = RLSW.vertexBuffer[2].homogeneous; const float *h2 = RLSW.vertexBuffer[2].homogeneous;
// Compute a value proportional to the signed area in the projected 2D plane, // Compute a value proportional to the signed area in the projected 2D plane,
// calculated directly using homogeneous coordinates BEFORE division by w. // calculated directly using homogeneous coordinates BEFORE division by w
// This is the determinant of the matrix formed by the (x, y, w) components // This is the determinant of the matrix formed by the (x, y, w) components
// of the vertices, which correctly captures the winding order in homogeneous // of the vertices, which correctly captures the winding order in homogeneous
// space and its relationship to the projected 2D winding order, even with // space and its relationship to the projected 2D winding order, even with
@ -2235,13 +2235,13 @@ static inline bool sw_triangle_face_culling(void)
// Discard the triangle if its winding order (determined by the sign // Discard the triangle if its winding order (determined by the sign
// of the homogeneous area/determinant) matches the culled direction // of the homogeneous area/determinant) matches the culled direction
// A positive hSgnArea typically corresponds to a counter-clockwise // A positive hSgnArea typically corresponds to a counter-clockwise
// winding in the projected space when all w > 0. // winding in the projected space when all w > 0
// This test is robust for points with w > 0 or w < 0, correctly // This test is robust for points with w > 0 or w < 0, correctly
// capturing the change in orientation when crossing the w=0 plane // capturing the change in orientation when crossing the w=0 plane
// The culling logic remains the same based on the signed area/determinant // The culling logic remains the same based on the signed area/determinant
// A value of 0 for hSgnArea means the points are collinear in (x, y, w) // A value of 0 for hSgnArea means the points are collinear in (x, y, w)
// space, which corresponds to a degenerate triangle projection. // space, which corresponds to a degenerate triangle projection
// Such triangles are typically not culled by this test (0 < 0 is false, 0 > 0 is false) // Such triangles are typically not culled by this test (0 < 0 is false, 0 > 0 is false)
// and should be handled by the clipper if necessary // and should be handled by the clipper if necessary
return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0) : (hSgnArea > 0); // Cull if winding is "clockwise" : "counter-clockwise" return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0) : (hSgnArea > 0); // Cull if winding is "clockwise" : "counter-clockwise"
@ -2558,13 +2558,13 @@ static inline void sw_triangle_render(void)
static inline bool sw_quad_face_culling(void) static inline bool sw_quad_face_culling(void)
{ {
// NOTE: Face culling is done before clipping to avoid unnecessary computations // NOTE: Face culling is done before clipping to avoid unnecessary computations
// To handle quads crossing the w=0 plane correctly, // To handle quads crossing the w=0 plane correctly,
// we perform the winding order test in homogeneous coordinates directly, // the winding order test is performed in homogeneous coordinates directly,
// before the perspective division (division by w) // before the perspective division (division by w)
// For a convex quad with vertices P0, P1, P2, P3 in sequential order, // For a convex quad with vertices P0, P1, P2, P3 in sequential order,
// the winding order of the quad is the same as the winding order // the winding order of the quad is the same as the winding order
// of the triangle P0 P1 P2. We use the homogeneous triangle // of the triangle P0 P1 P2. The homogeneous triangle is used on
// winding test on this first triangle // winding test on this first triangle
// Preload homogeneous coordinates into local variables // Preload homogeneous coordinates into local variables
const float *h0 = RLSW.vertexBuffer[0].homogeneous; const float *h0 = RLSW.vertexBuffer[0].homogeneous;
@ -2602,7 +2602,7 @@ static inline bool sw_quad_face_culling(void)
// space, which corresponds to a degenerate triangle projection // space, which corresponds to a degenerate triangle projection
// Such quads might also be degenerate or non-planar. They are typically // Such quads might also be degenerate or non-planar. They are typically
// not culled by this test (0 < 0 is false, 0 > 0 is false) // not culled by this test (0 < 0 is false, 0 > 0 is false)
// and should be handled by the clipper if necessary. // and should be handled by the clipper if necessary
return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0.0f) : (hSgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise" return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0.0f) : (hSgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise"
} }
@ -2649,7 +2649,7 @@ static inline bool sw_quad_is_axis_aligned(void)
{ {
// Reject quads with perspective projection // Reject quads with perspective projection
// The fast path assumes affine (non-perspective) quads, // The fast path assumes affine (non-perspective) quads,
// so we require all vertices to have homogeneous w = 1.0 // so it's required for all vertices to have homogeneous w = 1.0
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
if (RLSW.vertexBuffer[i].homogeneous[3] != 1.0f) return false; if (RLSW.vertexBuffer[i].homogeneous[3] != 1.0f) return false;
@ -2721,7 +2721,7 @@ static inline void sw_quad_sort_cw(const sw_vertex_t* *output)
// TODO: REVIEW: Could a perfectly aligned quad, where one of the four points has a different depth, // TODO: REVIEW: Could a perfectly aligned quad, where one of the four points has a different depth,
// still appear perfectly aligned from a certain point of view? // still appear perfectly aligned from a certain point of view?
// Because in that case, we would still need to perform perspective division for textures and colors... // Because in that case, it's still needed to perform perspective division for textures and colors...
#define DEFINE_QUAD_RASTER_AXIS_ALIGNED(FUNC_NAME, ENABLE_TEXTURE, ENABLE_DEPTH_TEST, ENABLE_COLOR_BLEND) \ #define DEFINE_QUAD_RASTER_AXIS_ALIGNED(FUNC_NAME, ENABLE_TEXTURE, ENABLE_DEPTH_TEST, ENABLE_COLOR_BLEND) \
static inline void FUNC_NAME(void) \ static inline void FUNC_NAME(void) \
{ \ { \
@ -3090,7 +3090,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \
\ \
for (int i = 0; i < numPixels; i++) \ for (int i = 0; i < numPixels; i++) \
{ \ { \
/* REVIEW: May require reviewing projection details */ \ /* TODO: REVIEW: May require reviewing projection details */ \
int px = (int)(x - 0.5f); \ int px = (int)(x - 0.5f); \
int py = (int)(y - 0.5f); \ int py = (int)(y - 0.5f); \
\ \
@ -3721,7 +3721,7 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr
ySrc = sw_clampi(ySrc, 0, hSrc); ySrc = sw_clampi(ySrc, 0, hSrc);
// Check if the sizes are identical after clamping the source to avoid unexpected issues // Check if the sizes are identical after clamping the source to avoid unexpected issues
// REVIEW: This repeats the operations if true, so we could make a copy function without these checks // TODO: REVIEW: This repeats the operations if true, so a copy function can be made without these checks
if (xDst == xSrc && yDst == ySrc && wDst == wSrc && hDst == hSrc) if (xDst == xSrc && yDst == ySrc && wDst == wSrc && hDst == hSrc)
{ {
swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels); swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels);

View File

@ -54,6 +54,12 @@
// 'Ask where to save each file before downloading' - which you can set true/false. // 'Ask where to save each file before downloading' - which you can set true/false.
// If you enable this setting it would always ask you and bring the SaveAsDialog // If you enable this setting it would always ask you and bring the SaveAsDialog
saveAs(blob, localFSname); saveAs(blob, localFSname);
// Alternative implementation to avoid FileSaver.js
//const link = document.createElement("a");
//link.href = URL.createObjectURL(blob);
//link.download = localFSname;
//link.click();
} }
</script> </script>
</head> </head>

View File

@ -13,9 +13,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -27,7 +24,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -48,7 +45,11 @@
#include <android_native_app_glue.h> // Required for: android_app struct and activity management #include <android_native_app_glue.h> // Required for: android_app struct and activity management
#include <android/window.h> // Required for: AWINDOW_FLAG_FULLSCREEN definition and others #include <android/window.h> // Required for: AWINDOW_FLAG_FULLSCREEN definition and others
#include <android/log.h> // Required for: Android log system: __android_log_vprint()
#include <android/asset_manager.h> // Required for: AAssetManager
//#include <android/sensor.h> // Required for: Android sensors functions (accelerometer, gyroscope, light...) //#include <android/sensor.h> // Required for: Android sensors functions (accelerometer, gyroscope, light...)
#include <errno.h> // Required for: error types
#include <jni.h> // Required for: JNIEnv and JavaVM [Used in OpenURL() and GetCurrentMonitor()] #include <jni.h> // Required for: JNIEnv and JavaVM [Used in OpenURL() and GetCurrentMonitor()]
#include <EGL/egl.h> // Native platform windowing system interface #include <EGL/egl.h> // Native platform windowing system interface
@ -267,6 +268,19 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd);
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs
static GamepadButton AndroidTranslateGamepadButton(int button); // Map Android gamepad button to raylib gamepad button static GamepadButton AndroidTranslateGamepadButton(int button); // Map Android gamepad button to raylib gamepad button
static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform())
static int android_read(void *cookie, char *buf, int size);
static int android_write(void *cookie, const char *buf, int size);
static fpos_t android_seek(void *cookie, fpos_t offset, int whence);
static int android_close(void *cookie);
FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only!
FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int),
fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));
#define fopen(name, mode) android_fopen(name, mode)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Declaration // Module Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -357,13 +371,17 @@ void RestoreWindow(void)
// Set window configuration state using flags // Set window configuration state using flags
void SetWindowState(unsigned int flags) void SetWindowState(unsigned int flags)
{ {
TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform"); if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead");
// State change: FLAG_WINDOW_ALWAYS_RUN
if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN);
} }
// Clear window configuration state flags // Clear window configuration state flags
void ClearWindowState(unsigned int flags) void ClearWindowState(unsigned int flags)
{ {
TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform"); // State change: FLAG_WINDOW_ALWAYS_RUN
if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN);
} }
// Set icon for window // Set icon for window
@ -601,7 +619,7 @@ void DisableCursor(void)
// Swap back buffer with front buffer (screen drawing) // Swap back buffer with front buffer (screen drawing)
void SwapScreenBuffer(void) void SwapScreenBuffer(void)
{ {
eglSwapBuffers(platform.device, platform.surface); if (platform.surface != EGL_NO_SURFACE) eglSwapBuffers(platform.device, platform.surface);
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -740,8 +758,8 @@ void PollInputEvents(void)
int pollEvents = 0; int pollEvents = 0;
// Poll Events (registered events) until we reach TIMEOUT which indicates there are no events left to poll // Poll Events (registered events) until we reach TIMEOUT which indicates there are no events left to poll
// NOTE: Activity is paused if not enabled (platform.appEnabled) // NOTE: Activity is paused if not enabled (platform.appEnabled) and always run flag is not set (FLAG_WINDOW_ALWAYS_RUN)
while ((pollResult = ALooper_pollOnce(platform.appEnabled? 0 : -1, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT)) while ((pollResult = ALooper_pollOnce((platform.appEnabled || FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN))? 0 : -1, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT))
{ {
// Process this event // Process this event
if (platform.source != NULL) platform.source->process(platform.app, platform.source); if (platform.source != NULL) platform.source->process(platform.app, platform.source);
@ -813,8 +831,6 @@ int InitPlatform(void)
// Initialize storage system // Initialize storage system
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath); // Initialize assets manager
CORE.Storage.basePath = platform.app->activity->internalDataPath; // Define base path for storage CORE.Storage.basePath = platform.app->activity->internalDataPath; // Define base path for storage
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -870,8 +886,8 @@ void ClosePlatform(void)
// NOTE: Reset global state in case the activity is being relaunched // NOTE: Reset global state in case the activity is being relaunched
if (platform.app->destroyRequested != 0) if (platform.app->destroyRequested != 0)
{ {
CORE = (CoreData){0}; CORE = (CoreData){ 0 };
platform = (PlatformData){0}; platform = (PlatformData){ 0 };
} }
} }
@ -881,7 +897,6 @@ void ClosePlatform(void)
// NOTE: returns false in case graphic device could not be created // NOTE: returns false in case graphic device could not be created
static int InitGraphicsDevice(void) static int InitGraphicsDevice(void)
{ {
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
EGLint samples = 0; EGLint samples = 0;
@ -915,6 +930,7 @@ static int InitGraphicsDevice(void)
// Get an EGL device connection // Get an EGL device connection
platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY); platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (platform.device == EGL_NO_DISPLAY) if (platform.device == EGL_NO_DISPLAY)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
@ -1173,7 +1189,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) ||
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD))
{ {
// For now we'll assume a single gamepad which we "detect" on its input event // Assuming a single gamepad, "detected" on its input event
CORE.Input.Gamepad.ready[0] = true; CORE.Input.Gamepad.ready[0] = true;
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_X] = AMotionEvent_getAxisValue( CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_X] = AMotionEvent_getAxisValue(
@ -1234,10 +1250,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
//int32_t AKeyEvent_getMetaState(event); //int32_t AKeyEvent_getMetaState(event);
// Handle gamepad button presses and releases // Handle gamepad button presses and releases
if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || // NOTE: Skip gamepad handling if this is a keyboard event, as some devices
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) // report both AINPUT_SOURCE_KEYBOARD and AINPUT_SOURCE_GAMEPAD flags
if ((FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) ||
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) &&
!FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD))
{ {
// For now we'll assume a single gamepad which we "detect" on its input event // Assuming a single gamepad, "detected" on its input event
CORE.Input.Gamepad.ready[0] = true; CORE.Input.Gamepad.ready[0] = true;
GamepadButton button = AndroidTranslateGamepadButton(keycode); GamepadButton button = AndroidTranslateGamepadButton(keycode);
@ -1328,30 +1347,17 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
} }
} }
if ((flags == AMOTION_EVENT_ACTION_POINTER_UP) || (flags == AMOTION_EVENT_ACTION_UP) || (flags == AMOTION_EVENT_ACTION_HOVER_EXIT)) #if defined(SUPPORT_GESTURES_SYSTEM)
{ GestureEvent gestureEvent = { 0 };
// One of the touchpoints is released, remove it from touch point arrays
if (flags == AMOTION_EVENT_ACTION_HOVER_EXIT) gestureEvent.pointCount = 0;
{
// If the touchPoint is hover, remove it from hoverPoints // Register touch actions
for (int i = 0; i < MAX_TOUCH_POINTS; i++) if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_ACTION_DOWN;
{ else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_ACTION_UP;
if (touchRaw.hoverPoints[i] == touchRaw.pointId[pointerIndex]) else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_ACTION_MOVE;
{ else if (flags == AMOTION_EVENT_ACTION_CANCEL) gestureEvent.touchAction = TOUCH_ACTION_CANCEL;
touchRaw.hoverPoints[i] = -1;
break;
}
}
}
for (int i = pointerIndex; (i < touchRaw.pointCount - 1) && (i < MAX_TOUCH_POINTS - 1); i++)
{
touchRaw.pointId[i] = touchRaw.pointId[i+1];
touchRaw.position[i] = touchRaw.position[i+1];
}
touchRaw.pointCount--;
}
int pointCount = 0;
for (int i = 0; (i < touchRaw.pointCount) && (i < MAX_TOUCH_POINTS); i++) for (int i = 0; (i < touchRaw.pointCount) && (i < MAX_TOUCH_POINTS); i++)
{ {
// If the touchPoint is hover, Ignore it // If the touchPoint is hover, Ignore it
@ -1367,35 +1373,62 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
} }
if (hover) continue; if (hover) continue;
CORE.Input.Touch.pointId[pointCount] = touchRaw.pointId[i]; gestureEvent.pointId[gestureEvent.pointCount] = touchRaw.pointId[i];
CORE.Input.Touch.position[pointCount] = touchRaw.position[i]; gestureEvent.position[gestureEvent.pointCount] = touchRaw.position[i];
pointCount++; gestureEvent.position[gestureEvent.pointCount].x /= (float)GetScreenWidth();
} gestureEvent.position[gestureEvent.pointCount].y /= (float)GetScreenHeight();
CORE.Input.Touch.pointCount = pointCount; gestureEvent.pointCount++;
#if defined(SUPPORT_GESTURES_SYSTEM)
GestureEvent gestureEvent = { 0 };
gestureEvent.pointCount = CORE.Input.Touch.pointCount;
// Register touch actions
if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_ACTION_DOWN;
else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_ACTION_UP;
else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_ACTION_MOVE;
else if (flags == AMOTION_EVENT_ACTION_CANCEL) gestureEvent.touchAction = TOUCH_ACTION_CANCEL;
for (int i = 0; (i < gestureEvent.pointCount) && (i < MAX_TOUCH_POINTS); i++)
{
gestureEvent.pointId[i] = CORE.Input.Touch.pointId[i];
gestureEvent.position[i] = CORE.Input.Touch.position[i];
gestureEvent.position[i].x /= (float)GetScreenWidth();
gestureEvent.position[i].y /= (float)GetScreenHeight();
} }
// Gesture data is sent to gestures system for processing // Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
#endif #endif
if (flags == AMOTION_EVENT_ACTION_HOVER_EXIT)
{
// Hover exited. So, remove it from hoverPoints
for (int i = 0; i < MAX_TOUCH_POINTS; i++)
{
if (touchRaw.hoverPoints[i] == touchRaw.pointId[pointerIndex])
{
touchRaw.hoverPoints[i] = -1;
break;
}
}
}
if ((flags == AMOTION_EVENT_ACTION_POINTER_UP) || (flags == AMOTION_EVENT_ACTION_UP))
{
// One of the touchpoints is released, remove it from touch point arrays
for (int i = pointerIndex; (i < touchRaw.pointCount - 1) && (i < MAX_TOUCH_POINTS - 1); i++)
{
touchRaw.pointId[i] = touchRaw.pointId[i+1];
touchRaw.position[i] = touchRaw.position[i+1];
}
touchRaw.pointCount--;
}
CORE.Input.Touch.pointCount = 0;
for (int i = 0; (i < touchRaw.pointCount) && (i < MAX_TOUCH_POINTS); i++)
{
// If the touchPoint is hover, Ignore it
bool hover = false;
for (int j = 0; j < MAX_TOUCH_POINTS; j++)
{
// Check if the touchPoint is in hoverPointers
if (touchRaw.hoverPoints[j] == touchRaw.pointId[i])
{
hover = true;
break;
}
}
if (hover) continue;
CORE.Input.Touch.pointId[CORE.Input.Touch.pointCount] = touchRaw.pointId[i];
CORE.Input.Touch.position[CORE.Input.Touch.pointCount] = touchRaw.position[i];
CORE.Input.Touch.pointCount++;
}
// When all touchpoints are tapped and released really quickly, this event is generated // When all touchpoints are tapped and released really quickly, this event is generated
if (flags == AMOTION_EVENT_ACTION_CANCEL) CORE.Input.Touch.pointCount = 0; if (flags == AMOTION_EVENT_ACTION_CANCEL) CORE.Input.Touch.pointCount = 0;
@ -1413,4 +1446,144 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
return 0; return 0;
} }
// Compute framebuffer size relative to screen size and display size
// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
static void SetupFramebuffer(int width, int height)
{
// Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var)
if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
// Downscaling to fit display with border-bars
float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width;
float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height;
if (widthRatio <= heightRatio)
{
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio);
CORE.Window.render.height = CORE.Window.display.height;
CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width);
CORE.Window.renderOffset.y = 0;
}
// Screen scaling required
float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width;
CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f);
// NOTE: We render to full display resolution!
// We just need to calculate above parameters for downscale matrix and offsets
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = CORE.Window.display.height;
TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height);
}
else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height))
{
// Required screen size is smaller than display size
TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{
CORE.Window.screen.width = CORE.Window.display.width;
CORE.Window.screen.height = CORE.Window.display.height;
}
// Upscaling to fit display with border-bars
float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height;
float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height;
if (displayRatio <= screenRatio)
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio);
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width);
CORE.Window.renderOffset.y = 0;
}
}
else
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = 0;
}
}
// Replacement for fopen()
// REF: https://developer.android.com/ndk/reference/group/asset
FILE *android_fopen(const char *fileName, const char *mode)
{
FILE *file = NULL;
if (mode[0] == 'w')
{
// NOTE: fopen() is mapped to android_fopen() that only grants read access to
// assets directory through AAssetManager but we want to also be able to
// write data when required using the standard stdio FILE access functions
// REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only
#undef fopen
file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
#define fopen(name, mode) android_fopen(name, mode)
}
else
{
// NOTE: AAsset provides access to read-only asset
AAsset *asset = AAssetManager_open(platform.app->activity->assetManager, fileName, AASSET_MODE_UNKNOWN);
if (asset != NULL)
{
// Get pointer to file in the assets
file = funopen(asset, android_read, android_write, android_seek, android_close);
}
else
{
#undef fopen
// Just do a regular open if file is not found in the assets
file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
if (file == NULL) file = fopen(fileName, mode);
#define fopen(name, mode) android_fopen(name, mode)
}
}
return file;
}
static int android_read(void *cookie, char *data, int dataSize)
{
return AAsset_read((AAsset *)cookie, data, dataSize);
}
static int android_write(void *cookie, const char *data, int dataSize)
{
TRACELOG(LOG_WARNING, "ANDROID: Failed to provide write access to APK");
return EACCES;
}
static fpos_t android_seek(void *cookie, fpos_t offset, int whence)
{
return AAsset_seek((AAsset *)cookie, offset, whence);
}
static int android_close(void *cookie)
{
AAsset_close((AAsset *)cookie);
return 0;
}
// EOF // EOF

View File

@ -16,9 +16,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -30,7 +27,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -103,7 +100,7 @@
#include <unistd.h> // Required for: usleep() #include <unistd.h> // Required for: usleep()
//#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition //#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition
void *glfwGetCocoaWindow(GLFWwindow* handle); void *glfwGetCocoaWindow(GLFWwindow *handle);
#include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow() #include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow()
#endif #endif
@ -134,12 +131,13 @@ static void ErrorCallback(int error, const char *description);
// Window callbacks events // Window callbacks events
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
static void WindowPosCallback(GLFWwindow* window, int x, int y); // GLFW3 WindowPos Callback, runs when window is moved static void FramebufferSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 FramebufferSize Callback, runs when window is resized
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley); // GLFW3 Window Content Scale Callback, runs when window changes scale
static void WindowPosCallback(GLFWwindow *window, int x, int y); // GLFW3 WindowPos Callback, runs when window is moved
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
static void WindowMaximizeCallback(GLFWwindow* window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized static void WindowMaximizeCallback(GLFWwindow *window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley); // GLFW3 Window Content Scale Callback, runs when window changes scale
// Input callbacks events // Input callbacks events
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
@ -155,8 +153,6 @@ static void *AllocateWrapper(size_t size, void *user);
static void *ReallocateWrapper(void *block, size_t size, void *user); // GLFW3 GLFWreallocatefun, wrapps around RL_REALLOC macro static void *ReallocateWrapper(void *block, size_t size, void *user); // GLFW3 GLFWreallocatefun, wrapps around RL_REALLOC macro
static void DeallocateWrapper(void *block, void *user); // GLFW3 GLFWdeallocatefun, wraps around RL_FREE macro static void DeallocateWrapper(void *block, void *user); // GLFW3 GLFWdeallocatefun, wraps around RL_FREE macro
static void SetDimensionsFromMonitor(GLFWmonitor *monitor); // Set screen dimensions from monitor/display dimensions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Declaration // Module Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -177,46 +173,72 @@ bool WindowShouldClose(void)
// Toggle fullscreen mode // Toggle fullscreen mode
void ToggleFullscreen(void) void ToggleFullscreen(void)
{ {
if (!CORE.Window.fullscreen) if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// Store previous window position (in case we exit fullscreen) // Store previous screen data (in case exiting fullscreen)
CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousPosition = CORE.Window.position;
CORE.Window.previousScreen = CORE.Window.screen;
// Use current monitor the window is on to get fullscreen required size
int monitorCount = 0; int monitorCount = 0;
int monitorIndex = GetCurrentMonitor(); int monitorIndex = GetCurrentMonitor();
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
// Use current monitor, so we correctly get the display the window is on
GLFWmonitor *monitor = (monitorIndex < monitorCount)? monitors[monitorIndex] : NULL; GLFWmonitor *monitor = (monitorIndex < monitorCount)? monitors[monitorIndex] : NULL;
if (monitor == NULL) if (monitor != NULL)
{ {
TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor"); // Get current monitor video mode
const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitorIndex]);
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
CORE.Window.fullscreen = false; CORE.Window.position = (Point){ 0, 0 };
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); CORE.Window.screen = CORE.Window.display;
glfwSetWindowMonitor(platform.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); // Set fullscreen flag to be processed on FramebufferSizeCallback() accordingly
}
else
{
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
// NOTE: X11 requires undecorating the window before switching to
// fullscreen to avoid issues with framebuffer scaling
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_FALSE);
FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED);
#endif
// WARNING: This function launches FramebufferSizeCallback()
glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
} }
else TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor");
} }
else else
{ {
CORE.Window.fullscreen = false; // Restore previous window position and size
CORE.Window.position = CORE.Window.previousPosition;
CORE.Window.screen = CORE.Window.previousScreen;
// Set fullscreen flag to be processed on FramebufferSizeCallback() accordingly
// and considered by GetWindowScaleDPI()
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); #if !defined(__APPLE__)
// Make sure to restore render size considering HighDPI scaling
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{
Vector2 scaleDpi = GetWindowScaleDPI();
CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x);
CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height*scaleDpi.y);
}
#endif
// we update the window position right away // WARNING: This function launches FramebufferSizeCallback()
CORE.Window.position.x = CORE.Window.previousPosition.x; glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y,
CORE.Window.position.y = CORE.Window.previousPosition.y; CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
// NOTE: X11 requires restoring the decorated window after switching from
// fullscreen to avoid issues with framebuffer scaling
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE);
FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED);
#endif
} }
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
@ -228,29 +250,24 @@ void ToggleFullscreen(void)
void ToggleBorderlessWindowed(void) void ToggleBorderlessWindowed(void)
{ {
// Leave fullscreen before attempting to set borderless windowed mode // Leave fullscreen before attempting to set borderless windowed mode
bool wasOnFullscreen = false; // NOTE: Fullscreen already saves the previous position so it does not need to be set again later
if (CORE.Window.fullscreen) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) ToggleFullscreen();
{
// fullscreen already saves the previous position so it does not need to be set here again
ToggleFullscreen();
wasOnFullscreen = true;
}
const int monitor = GetCurrentMonitor(); int monitorCount = 0;
int monitorCount;
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
const int monitor = GetCurrentMonitor();
if ((monitor >= 0) && (monitor < monitorCount)) if ((monitor >= 0) && (monitor < monitorCount))
{ {
const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]); const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]);
if (mode) if (mode != NULL)
{ {
if (!IsWindowState(FLAG_BORDERLESS_WINDOWED_MODE)) if (!FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE))
{ {
// Store screen position and size // Store screen position and size
// NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here // NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here
if (!wasOnFullscreen) CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousPosition = CORE.Window.position;
CORE.Window.previousScreen = CORE.Window.screen; CORE.Window.previousScreen = CORE.Window.screen;
// Set undecorated flag // Set undecorated flag
@ -258,22 +275,13 @@ void ToggleBorderlessWindowed(void)
FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED);
// Get monitor position and size // Get monitor position and size
int monitorPosX = 0; glfwGetMonitorPos(monitors[monitor], &CORE.Window.position.x, &CORE.Window.position.y);
int monitorPosY = 0; CORE.Window.screen.width = mode->width;
glfwGetMonitorPos(monitors[monitor], &monitorPosX, &monitorPosY); CORE.Window.screen.height = mode->height;
const int monitorWidth = mode->width;
const int monitorHeight = mode->height;
// Set screen position and size // Set screen position and size
glfwSetWindowMonitor( glfwSetWindowMonitor(platform.handle, monitors[monitor], CORE.Window.position.x, CORE.Window.position.y,
platform.handle, CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate);
monitors[monitor],
monitorPosX,
monitorPosY,
monitorWidth,
monitorHeight,
mode->refreshRate
);
// Refocus window // Refocus window
glfwFocusWindow(platform.handle); glfwFocusWindow(platform.handle);
@ -282,29 +290,32 @@ void ToggleBorderlessWindowed(void)
} }
else else
{ {
// Restore previous screen values
CORE.Window.position = CORE.Window.previousPosition;
CORE.Window.screen = CORE.Window.previousScreen;
// Remove undecorated flag // Remove undecorated flag
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE); glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE);
FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED);
// Return previous screen size and position #if !defined(__APPLE__)
// NOTE: The order matters here, it must set size first, then set position, otherwise the screen will be positioned incorrectly // Make sure to restore size considering HighDPI scaling
glfwSetWindowMonitor( if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
platform.handle, {
NULL, Vector2 scaleDpi = GetWindowScaleDPI();
CORE.Window.previousPosition.x, CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x);
CORE.Window.previousPosition.y, CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height*scaleDpi.y);
CORE.Window.previousScreen.width, }
CORE.Window.previousScreen.height, #endif
mode->refreshRate
); // Return to previous screen size and position
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y,
CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate);
// Refocus window // Refocus window
glfwFocusWindow(platform.handle); glfwFocusWindow(platform.handle);
FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
CORE.Window.position.x = CORE.Window.previousPosition.x;
CORE.Window.position.y = CORE.Window.previousPosition.y;
} }
} }
else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor"); else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor");
@ -475,13 +486,13 @@ void ClearWindowState(unsigned int flags)
// NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running // NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running
if ((FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) && (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE))) if ((FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) && (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)))
{ {
ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function
} }
// State change: FLAG_FULLSCREEN_MODE // State change: FLAG_FULLSCREEN_MODE
if ((FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) && (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))) if ((FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) && (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)))
{ {
ToggleFullscreen(); // NOTE: Window state flag updated inside function ToggleFullscreen(); // NOTE: Window state flag updated inside function
} }
// State change: FLAG_WINDOW_RESIZABLE // State change: FLAG_WINDOW_RESIZABLE
@ -591,7 +602,7 @@ void SetWindowIcon(Image image)
icon[0].height = image.height; icon[0].height = image.height;
icon[0].pixels = (unsigned char *)image.data; icon[0].pixels = (unsigned char *)image.data;
// NOTE 1: We only support one image icon // NOTE 1: Only one image icon supported
// NOTE 2: The specified image data is copied before this function returns // NOTE 2: The specified image data is copied before this function returns
glfwSetWindowIcon(platform.handle, 1, icon); glfwSetWindowIcon(platform.handle, 1, icon);
} }
@ -658,7 +669,7 @@ void SetWindowMonitor(int monitor)
if ((monitor >= 0) && (monitor < monitorCount)) if ((monitor >= 0) && (monitor < monitorCount))
{ {
if (CORE.Window.fullscreen) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
TRACELOG(LOG_INFO, "GLFW: Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor])); TRACELOG(LOG_INFO, "GLFW: Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
@ -822,7 +833,7 @@ int GetCurrentMonitor(void)
} }
else else
{ {
// In case the window is between two monitors, we use below logic // In case the window is between two monitors, below logic is used
// to try to detect the "current monitor" for that window, note that // to try to detect the "current monitor" for that window, note that
// this is probably an overengineered solution for a very side case // this is probably an overengineered solution for a very side case
// trying to match SDL behaviour // trying to match SDL behaviour
@ -894,7 +905,8 @@ Vector2 GetMonitorPosition(int monitor)
if ((monitor >= 0) && (monitor < monitorCount)) if ((monitor >= 0) && (monitor < monitorCount))
{ {
int x, y; int x = 0;
int y = 0;
glfwGetMonitorPos(monitors[monitor], &x, &y); glfwGetMonitorPos(monitors[monitor], &x, &y);
return (Vector2){ (float)x, (float)y }; return (Vector2){ (float)x, (float)y };
@ -1004,19 +1016,15 @@ const char *GetMonitorName(int monitor)
// Get window position XY on monitor // Get window position XY on monitor
Vector2 GetWindowPosition(void) Vector2 GetWindowPosition(void)
{ {
int x = 0; return (Vector2){ (float)CORE.Window.position.x, (float)CORE.Window.position.y };
int y = 0;
glfwGetWindowPos(platform.handle, &x, &y);
return (Vector2){ (float)x, (float)y };
} }
// Get window scale DPI factor for current monitor // Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void) Vector2 GetWindowScaleDPI(void)
{ {
Vector2 scale = { 0 }; Vector2 scale = { 1.0f, 1.0f };
glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && !FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y);
return scale; return scale;
} }
@ -1178,7 +1186,7 @@ void SetMouseCursor(int cursor)
if (cursor == MOUSE_CURSOR_DEFAULT) glfwSetCursor(platform.handle, NULL); if (cursor == MOUSE_CURSOR_DEFAULT) glfwSetCursor(platform.handle, NULL);
else else
{ {
// NOTE: We are relating internal GLFW enum values to our MouseCursor enum values // NOTE: Mapping internal GLFW enum values to MouseCursor enum values
glfwSetCursor(platform.handle, glfwCreateStandardCursor(0x00036000 + cursor)); glfwSetCursor(platform.handle, glfwCreateStandardCursor(0x00036000 + cursor));
} }
} }
@ -1203,7 +1211,7 @@ void PollInputEvents(void)
CORE.Input.Keyboard.charPressedQueueCount = 0; CORE.Input.Keyboard.charPressedQueueCount = 0;
// Reset last gamepad button/axis registered state // Reset last gamepad button/axis registered state
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
//CORE.Input.Gamepad.axisCount = 0; //CORE.Input.Gamepad.axisCount = 0;
// Keyboard/Mouse input polling (automatically managed by GLFW3 through callback) // Keyboard/Mouse input polling (automatically managed by GLFW3 through callback)
@ -1239,7 +1247,7 @@ void PollInputEvents(void)
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
// Check if gamepads are ready // Check if gamepads are ready
// NOTE: We do it here in case of disconnection // NOTE: Doing it here in case of disconnection
for (int i = 0; i < MAX_GAMEPADS; i++) for (int i = 0; i < MAX_GAMEPADS; i++)
{ {
if (glfwJoystickPresent(i)) CORE.Input.Gamepad.ready[i] = true; if (glfwJoystickPresent(i)) CORE.Input.Gamepad.ready[i] = true;
@ -1255,9 +1263,15 @@ void PollInputEvents(void)
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k];
// Get current gamepad state // Get current gamepad state
// NOTE: There is no callback available, so we get it manually // NOTE: There is no callback available, getting it manually
GLFWgamepadstate state = { 0 }; GLFWgamepadstate state = { 0 };
glfwGetGamepadState(i, &state); // This remapps all gamepads so they have their buttons mapped like an xbox controller int result = glfwGetGamepadState(i, &state); // This remaps all gamepads so they have their buttons mapped like an xbox controller
if (result == GLFW_FALSE) // No joystick is connected, no gamepad mapping or an error occurred
{
// Setting axes to expected resting value instead of GLFW 0.0f default when gamepad is not connected
state.axes[GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
state.axes[GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
}
const unsigned char *buttons = state.buttons; const unsigned char *buttons = state.buttons;
@ -1328,7 +1342,8 @@ void PollInputEvents(void)
CORE.Window.resizedLastFrame = false; CORE.Window.resizedLastFrame = false;
if ((CORE.Window.eventWaiting) || (IsWindowState(FLAG_WINDOW_MINIMIZED) && !IsWindowState(FLAG_WINDOW_ALWAYS_RUN))) if ((CORE.Window.eventWaiting) ||
(FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED) && !FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN)))
{ {
glfwWaitEvents(); // Wait for in input events before continue (drawing is paused) glfwWaitEvents(); // Wait for in input events before continue (drawing is paused)
CORE.Time.previous = GetTime(); CORE.Time.previous = GetTime();
@ -1344,9 +1359,8 @@ void PollInputEvents(void)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Internal Functions Definition // Module Internal Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Function wrappers around RL_*alloc macros, used by glfwInitAllocator() inside of InitPlatform() // Function wrappers around RL_*ALLOC macros, used by glfwInitAllocator() inside of InitPlatform()
// We need to provide these because GLFWallocator expects function pointers with specific signatures // GLFWallocator expects function pointers with specific signatures to be provided
// Similar wrappers exist in utils.c but we cannot reuse them here due to declaration mismatch
// REF: https://www.glfw.org/docs/latest/intro_guide.html#init_allocator // REF: https://www.glfw.org/docs/latest/intro_guide.html#init_allocator
static void *AllocateWrapper(size_t size, void *user) static void *AllocateWrapper(size_t size, void *user)
{ {
@ -1406,8 +1420,6 @@ int InitPlatform(void)
unsigned int requestedWindowFlags = CORE.Window.flags; unsigned int requestedWindowFlags = CORE.Window.flags;
// Check window creation flags // Check window creation flags
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window
else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden
@ -1433,31 +1445,27 @@ int InitPlatform(void)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer
else glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE); // Opaque framebuffer else glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE); // Opaque framebuffer
// HACK: Most of this was written before GLFW_SCALE_FRAMEBUFFER existed and
// was enabled by default. Disabling it gets back the old behavior. A
// complete fix will require removing a lot of CORE.Window.render
// manipulation code
// NOTE: This currently doesn't work on macOS(see #5185), so we skip it there
// when FLAG_WINDOW_HIGHDPI is *unset*
#if !defined(__APPLE__)
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
#endif
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{ {
// since we skipped it before, now make sure to set this on macOS
#if defined(__APPLE__) #if defined(__APPLE__)
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
#endif #endif
// Resize window content area based on the monitor content scale // Resize window content area based on the monitor content scale
// NOTE: This hint only has an effect on platforms where screen coordinates and pixels always map 1:1 such as Windows and X11 // NOTE: This hint only has an effect on platforms where screen coordinates and
// pixels always map 1:1 such as Windows and X11
// On platforms like macOS the resolution of the framebuffer is changed independently of the window size // On platforms like macOS the resolution of the framebuffer is changed independently of the window size
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); // Scale content area based on the monitor content scale where window is placed on glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
#if defined(__APPLE__) #if defined(__APPLE__)
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
#endif #endif
} }
else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); else
{
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
#if defined(__APPLE__)
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
#endif
}
// Mouse passthrough // Mouse passthrough
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) glfwWindowHint(GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) glfwWindowHint(GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE);
@ -1524,91 +1532,61 @@ int InitPlatform(void)
// REF: https://github.com/raysan5/raylib/issues/1554 // REF: https://github.com/raysan5/raylib/issues/1554
glfwSetJoystickCallback(NULL); glfwSetJoystickCallback(NULL);
GLFWmonitor *monitor = NULL; if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0)) FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
if (CORE.Window.fullscreen)
{
// According to glfwCreateWindow(), if the user does not have a choice, fullscreen applications
// should default to the primary monitor
monitor = glfwGetPrimaryMonitor(); // Init window in fullscreen mode if requested
// NOTE: Keeping original screen size for toggle
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{
// NOTE: Fullscreen applications default to the primary monitor
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor) if (!monitor)
{ {
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor"); TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return -1; return -1;
} }
SetDimensionsFromMonitor(monitor); // Set dimensions from monitor
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
// Remember center for switching from fullscreen to window // Default display resolution to that of the current mode
if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width)) CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Check if user requested some screen size
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{ {
// If screen width/height equal to the display, we can't calculate the window pos for toggling full-screened/windowed // Set some default screen size in case user decides to exit fullscreen mode
// Toggling full-screened/windowed with pos(0, 0) can cause problems in some platforms, such as X11 CORE.Window.previousScreen.width = 800;
CORE.Window.position.x = CORE.Window.display.width/4; CORE.Window.previousScreen.height = 450;
CORE.Window.position.y = CORE.Window.display.height/4; CORE.Window.previousPosition.x = CORE.Window.display.width/2 - 800/2;
CORE.Window.previousPosition.y = CORE.Window.display.height/2 - 450/2;
// Set screen width/height to the display width/height
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
} }
else else
{ {
CORE.Window.position.x = CORE.Window.display.width/2 - CORE.Window.screen.width/2; CORE.Window.previousScreen = CORE.Window.screen;
CORE.Window.position.y = CORE.Window.display.height/2 - CORE.Window.screen.height/2; CORE.Window.screen = CORE.Window.display;
} }
if (CORE.Window.position.x < 0) CORE.Window.position.x = 0; platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", monitor, NULL);
if (CORE.Window.position.y < 0) CORE.Window.position.y = 0;
// Obtain recommended CORE.Window.display.width/CORE.Window.display.height from a valid videomode for the monitor
int count = 0;
const GLFWvidmode *modes = glfwGetVideoModes(monitor, &count);
// Get closest video mode to desired CORE.Window.screen.width/CORE.Window.screen.height
for (int i = 0; i < count; i++)
{
if ((unsigned int)modes[i].width >= CORE.Window.screen.width)
{
if ((unsigned int)modes[i].height >= CORE.Window.screen.height)
{
CORE.Window.display.width = modes[i].width;
CORE.Window.display.height = modes[i].height;
break;
}
}
}
TRACELOG(LOG_INFO, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
// framebuffer is rendered correctly but once displayed on a 16:9 monitor, it gets stretched
// by the sides to fit all monitor space...
// Try to setup the most appropriate fullscreen framebuffer for the requested screenWidth/screenHeight
// It considers device display resolution mode and setups a framebuffer with black bars if required (render size/offset)
// Modified global variables: CORE.Window.screen.width/CORE.Window.screen.height - CORE.Window.render.width/CORE.Window.render.height - CORE.Window.renderOffset.x/CORE.Window.renderOffset.y - CORE.Window.screenScale
// TODO: It is a quite cumbersome solution to display size vs requested size, it should be reviewed or removed...
// HighDPI monitors are properly considered in a following similar function: SetupViewport()
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", monitor, NULL);
if (!platform.handle) if (!platform.handle)
{ {
glfwTerminate(); glfwTerminate();
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window"); TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
return -1; return -1;
} }
// NOTE: Full-screen change, not working properly...
//glfwSetWindowMonitor(platform.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
} }
else else
{ {
// No-fullscreen window creation
bool requestWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0);
// Default to at least one pixel in size, as creation with a zero dimension is not allowed // Default to at least one pixel in size, as creation with a zero dimension is not allowed
int creationWidth = (CORE.Window.screen.width != 0)? CORE.Window.screen.width : 1; if (CORE.Window.screen.width == 0) CORE.Window.screen.width = 1;
int creationHeight = (CORE.Window.screen.height != 0)? CORE.Window.screen.height : 1; if (CORE.Window.screen.height == 0) CORE.Window.screen.height = 1;
platform.handle = glfwCreateWindow(creationWidth, creationHeight, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL); platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
if (!platform.handle) if (!platform.handle)
{ {
glfwTerminate(); glfwTerminate();
@ -1617,7 +1595,7 @@ int InitPlatform(void)
} }
// After the window was created, determine the monitor that the window manager assigned // After the window was created, determine the monitor that the window manager assigned
// Derive display sizes, and, if possible, window size in case it was zero at beginning // Derive display sizes and, if possible, window size in case it was zero at beginning
int monitorCount = 0; int monitorCount = 0;
int monitorIndex = GetCurrentMonitor(); int monitorIndex = GetCurrentMonitor();
@ -1625,10 +1603,18 @@ int InitPlatform(void)
if (monitorIndex < monitorCount) if (monitorIndex < monitorCount)
{ {
monitor = monitors[monitorIndex]; GLFWmonitor *monitor = monitors[monitorIndex];
SetDimensionsFromMonitor(monitor); const GLFWvidmode *mode = glfwGetVideoMode(monitor);
if (requestWindowedFullscreen) glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height); // Default display resolution to that of the current mode
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
} }
else else
{ {
@ -1638,19 +1624,20 @@ int InitPlatform(void)
return -1; return -1;
} }
// NOTE: Not considering scale factor now, considered below
CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height; CORE.Window.render.height = CORE.Window.screen.height;
} }
glfwMakeContextCurrent(platform.handle); glfwMakeContextCurrent(platform.handle);
result = glfwGetError(NULL); result = glfwGetError(NULL);
if ((result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR)) CORE.Window.ready = true; // Checking context activation
// Check context activation if (CORE.Window.ready)
if ((result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR))
{ {
CORE.Window.ready = true; // Setup additional windows configs and register required window size info
glfwSwapInterval(0); // No V-Sync by default glfwSwapInterval(0); // No V-Sync by default
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
// NOTE: V-Sync can be enabled by graphic driver configuration, it doesn't need // NOTE: V-Sync can be enabled by graphic driver configuration, it doesn't need
@ -1668,16 +1655,17 @@ int InitPlatform(void)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{ {
// NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling // NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling
// Framebuffer scaling should be activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); // Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
#if !defined(__APPLE__)
// Get current framebuffer size, on high-dpi it could be bigger than screen size
glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight);
// Screen scaling matrix is required in case desired screen area is different from display area // Screen scaling matrix is required in case desired screen area is different from display area
CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f); CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f);
#if !defined(__APPLE__)
// Mouse input scaling for the new screen size // Mouse input scaling for the new screen size
SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight); SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight);
#endif #endif
} }
CORE.Window.render.width = fbWidth; CORE.Window.render.width = fbWidth;
@ -1690,37 +1678,34 @@ int InitPlatform(void)
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
}
else
{
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device");
return -1;
}
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow();
// If graphic device is no properly initialized, we end program
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
else
{
// Try to center window on screen but avoiding window-bar outside of screen // Try to center window on screen but avoiding window-bar outside of screen
int monitorCount = 0;
int monitorIndex = GetCurrentMonitor();
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
GLFWmonitor *monitor = monitors[monitorIndex];
int monitorX = 0; int monitorX = 0;
int monitorY = 0; int monitorY = 0;
int monitorWidth = 0; int monitorWidth = 0;
int monitorHeight = 0; int monitorHeight = 0;
glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight); glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);
// Here CORE.Window.render.width/height should be used instead of // TODO: Here CORE.Window.render.width/height should be used instead of
// CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled // CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled
int posX = monitorX + (monitorWidth - (int)CORE.Window.render.width)/2; CORE.Window.position.x = monitorX + (monitorWidth - (int)CORE.Window.screen.width)/2;
int posY = monitorY + (monitorHeight - (int)CORE.Window.render.height)/2; CORE.Window.position.y = monitorY + (monitorHeight - (int)CORE.Window.screen.height)/2;
if (posX < monitorX) posX = monitorX; //if (CORE.Window.position.x < monitorX) CORE.Window.position.x = monitorX;
if (posY < monitorY) posY = monitorY; //if (CORE.Window.position.y < monitorY) CORE.Window.position.y = monitorY;
SetWindowPosition(posX, posY);
// Update CORE.Window.position here so it is correct from the start SetWindowPosition(CORE.Window.position.x, CORE.Window.position.y);
CORE.Window.position.x = posX;
CORE.Window.position.y = posY; if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow();
}
else
{
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device");
return -1;
} }
// Apply window flags requested previous to initialization // Apply window flags requested previous to initialization
@ -1734,34 +1719,30 @@ int InitPlatform(void)
// Initialize input events callbacks // Initialize input events callbacks
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Set window callback events // Set window callback events
glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default! glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing is not enabled by default
glfwSetFramebufferSizeCallback(platform.handle, FramebufferSizeCallback);
glfwSetWindowPosCallback(platform.handle, WindowPosCallback); glfwSetWindowPosCallback(platform.handle, WindowPosCallback);
glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback); glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback);
glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback); glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback);
glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback); glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback);
glfwSetDropCallback(platform.handle, WindowDropCallback); glfwSetDropCallback(platform.handle, WindowDropCallback);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) glfwSetWindowContentScaleCallback(platform.handle, WindowContentScaleCallback);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{
glfwSetWindowContentScaleCallback(platform.handle, WindowContentScaleCallback);
}
// Set input callback events // Set input callback events
glfwSetKeyCallback(platform.handle, KeyCallback); glfwSetKeyCallback(platform.handle, KeyCallback);
glfwSetCharCallback(platform.handle, CharCallback); glfwSetCharCallback(platform.handle, CharCallback);
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback); glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
glfwSetScrollCallback(platform.handle, MouseScrollCallback); glfwSetScrollCallback(platform.handle, MouseScrollCallback);
glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback); glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback);
glfwSetJoystickCallback(JoystickCallback); glfwSetJoystickCallback(JoystickCallback);
glfwSetInputMode(platform.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM)
glfwSetInputMode(platform.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM)
// Retrieve gamepad names // Retrieve gamepad names
for (int i = 0; i < MAX_GAMEPADS; i++) for (int i = 0; i < MAX_GAMEPADS; i++)
{ {
// WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH, // WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH,
// we can get a not-NULL terminated string, so, we only copy up to (MAX_GAMEPAD_NAME_LENGTH - 1) // only copying up to (MAX_GAMEPAD_NAME_LENGTH - 1)
if (glfwJoystickPresent(i)) if (glfwJoystickPresent(i))
{ {
CORE.Input.Gamepad.ready[i] = true; CORE.Input.Gamepad.ready[i] = true;
@ -1813,84 +1794,139 @@ void ClosePlatform(void)
#endif #endif
} }
// GLFW3 Error Callback, runs on GLFW3 error //----------------------------------------------------------------------------------
// Module Internal Functions Definition
// NOTE: Those functions are only required for current platform
//----------------------------------------------------------------------------------
// GLFW3: Error callback, runs on GLFW3 error
static void ErrorCallback(int error, const char *description) static void ErrorCallback(int error, const char *description)
{ {
TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description); TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description);
} }
// GLFW3 WindowSize Callback, runs when window is resizedLastFrame // GLFW3: Window size change callback, runs when window is resized
// NOTE: Window resizing not enabled by default, use SetConfigFlags() // NOTE: Window resizing not enabled by default, use SetConfigFlags()
static void WindowSizeCallback(GLFWwindow *window, int width, int height) static void WindowSizeCallback(GLFWwindow *window, int width, int height)
{ {
// WARNING: On window minimization, callback is called, // Nothing to do for now on window resize...
// but we don't want to change internal screen values, it breaks things //TRACELOG(LOG_INFO, "GLFW3: Window size callback called [%i,%i]", width, height);
}
// GLFW3: Framebuffer size change callback, runs when framebuffer is resized
// WARNING: If FLAG_WINDOW_HIGHDPI is set, WindowContentScaleCallback() is called before this function
static void FramebufferSizeCallback(GLFWwindow *window, int width, int height)
{
//TRACELOG(LOG_INFO, "GLFW3: Window framebuffer size callback called [%i,%i]", width, height);
// WARNING: On window minimization, callback is called with 0 values,
// but internal screen values should not be changed, it breaks things
if ((width == 0) || (height == 0)) return; if ((width == 0) || (height == 0)) return;
// Reset viewport and projection matrix for new size // Reset viewport and projection matrix for new size
// NOTE: Stores current render size: CORE.Window.render
SetupViewport(width, height); SetupViewport(width, height);
// Set render size
CORE.Window.currentFbo.width = width; CORE.Window.currentFbo.width = width;
CORE.Window.currentFbo.height = height; CORE.Window.currentFbo.height = height;
CORE.Window.resizedLastFrame = true; CORE.Window.resizedLastFrame = true;
if (IsWindowFullscreen()) return; if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
// if we are doing automatic DPI scaling, then the "screen" size is divided by the window scale
if (IsWindowState(FLAG_WINDOW_HIGHDPI))
{ {
width = (int)(width/GetWindowScaleDPI().x); // On fullscreen mode, strategy is ignoring high-dpi and
height = (int)(height/GetWindowScaleDPI().y); // use the all available display size
// Set screen size to render size (physical pixel size)
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
CORE.Window.screenScale = MatrixScale(1.0f, 1.0f, 1.0f);
SetMouseScale(1.0f, 1.0f);
}
else // Window mode (including borderless window)
{
// Check if render size was actually scaled for high-dpi
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{
// Set screen size to logical pixel size, considering content scaling
Vector2 scaleDpi = GetWindowScaleDPI();
CORE.Window.screen.width = (int)((float)width/scaleDpi.x);
CORE.Window.screen.height = (int)((float)height/scaleDpi.y);
CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f);
#if !defined(__APPLE__)
// Mouse input scaling for the new screen size
SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y);
#endif
}
else
{
// Set screen size to render size (physical pixel size)
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
}
} }
// Set render size
CORE.Window.render.width = width;
CORE.Window.render.height = height;
// Set current screen size
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
// WARNING: If using a render texture, it is not scaled to new size // WARNING: If using a render texture, it is not scaled to new size
} }
static void WindowPosCallback(GLFWwindow* window, int x, int y)
// GLFW3: Window content scale callback, runs on monitor content scale change detected
// WARNING: If FLAG_WINDOW_HIGHDPI is not set, this function is not called
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
{
//TRACELOG(LOG_INFO, "GLFW3: Window content scale changed, scale: [%.2f,%.2f]", scalex, scaley);
float fbWidth = (float)CORE.Window.screen.width*scalex;
float fbHeight = (float)CORE.Window.screen.height*scaley;
// NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling
// Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f);
#if !defined(__APPLE__)
// Mouse input scaling for the new screen size
SetMouseScale(1.0f/scalex, 1.0f/scaley);
#endif
CORE.Window.render.width = (int)fbWidth;
CORE.Window.render.height = (int)fbHeight;
CORE.Window.currentFbo = CORE.Window.render;
}
// GLFW3: Window position callback, runs when window position changes
static void WindowPosCallback(GLFWwindow *window, int x, int y)
{ {
// Set current window position // Set current window position
CORE.Window.position.x = x; CORE.Window.position.x = x;
CORE.Window.position.y = y; CORE.Window.position.y = y;
} }
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
{
CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f);
}
// GLFW3 WindowIconify Callback, runs when window is minimized/restored // GLFW3: Window iconify callback, runs when window is minimized/restored
static void WindowIconifyCallback(GLFWwindow *window, int iconified) static void WindowIconifyCallback(GLFWwindow *window, int iconified)
{ {
if (iconified) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified if (iconified) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified
else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored
} }
// GLFW3 WindowMaximize Callback, runs when window is maximized/restored // GLFW3: Window maximize callback, runs when window is maximized/restored
static void WindowMaximizeCallback(GLFWwindow *window, int maximized) static void WindowMaximizeCallback(GLFWwindow *window, int maximized)
{ {
if (maximized) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized if (maximized) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized
else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored
} }
// GLFW3 WindowFocus Callback, runs when window get/lose focus // GLFW3: Window focus callback, runs when window get/lose focus
static void WindowFocusCallback(GLFWwindow *window, int focused) static void WindowFocusCallback(GLFWwindow *window, int focused)
{ {
if (focused) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused if (focused) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused
else FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus else FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus
} }
// GLFW3 Window Drop Callback, runs when drop files into window // GLFW3: Window drop callback, runs when files are dropped into window
static void WindowDropCallback(GLFWwindow *window, int count, const char **paths) static void WindowDropCallback(GLFWwindow *window, int count, const char **paths)
{ {
if (count > 0) if (count > 0)
{ {
// In case previous dropped filepaths have not been freed, we free them // In case previous dropped filepaths have not been freed, free them
if (CORE.Window.dropFileCount > 0) if (CORE.Window.dropFileCount > 0)
{ {
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilepaths[i]); for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilepaths[i]);
@ -1901,24 +1937,24 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
CORE.Window.dropFilepaths = NULL; CORE.Window.dropFilepaths = NULL;
} }
// WARNING: Paths are freed by GLFW when the callback returns, we must keep an internal copy // WARNING: Paths are freed by GLFW when the callback returns, keeping an internal copy
CORE.Window.dropFileCount = count; CORE.Window.dropFileCount = count;
CORE.Window.dropFilepaths = (char **)RL_CALLOC(CORE.Window.dropFileCount, sizeof(char *)); CORE.Window.dropFilepaths = (char **)RL_CALLOC(CORE.Window.dropFileCount, sizeof(char *));
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{ {
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strcpy(CORE.Window.dropFilepaths[i], paths[i]); strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
} }
} }
} }
// GLFW3 Keyboard Callback, runs on key pressed // GLFW3: Keyboard callback, runs on key pressed
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{ {
if (key < 0) return; // Security check, macOS fn key generates -1 if (key < 0) return; // Security check, macOS fn key generates -1
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 // WARNING: GLFW could return GLFW_REPEAT, it needs to be considered as 1
// to work properly with our implementation (IsKeyDown/IsKeyUp checks) // to work properly with our implementation (IsKeyDown/IsKeyUp checks)
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
else if (action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1; else if (action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1;
@ -1940,7 +1976,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(platform.handle, GLFW_TRUE); if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(platform.handle, GLFW_TRUE);
} }
// GLFW3 Char Callback, get unicode codepoint value // GLFW3: Char callback, runs on key pressed to get unicode codepoint value
static void CharCallback(GLFWwindow *window, unsigned int codepoint) static void CharCallback(GLFWwindow *window, unsigned int codepoint)
{ {
// NOTE: Registers any key down considering OS keyboard layout but // NOTE: Registers any key down considering OS keyboard layout but
@ -1957,7 +1993,7 @@ static void CharCallback(GLFWwindow *window, unsigned int codepoint)
} }
} }
// GLFW3 Mouse Button Callback, runs on mouse button pressed // GLFW3: Mouse button callback, runs on mouse button pressed
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods) static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
{ {
// WARNING: GLFW could only return GLFW_PRESS (1) or GLFW_RELEASE (0) for now, // WARNING: GLFW could only return GLFW_PRESS (1) or GLFW_RELEASE (0) for now,
@ -1993,7 +2029,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
#endif #endif
} }
// GLFW3 Cursor Position Callback, runs on mouse move // GLFW3: Cursor position callback, runs on mouse movement
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y) static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
{ {
CORE.Input.Mouse.currentPosition.x = (float)x; CORE.Input.Mouse.currentPosition.x = (float)x;
@ -2024,26 +2060,26 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
#endif #endif
} }
// GLFW3 Scrolling Callback, runs on mouse wheel // GLFW3: Mouse wheel scroll callback, runs on mouse wheel changes
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset) static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset)
{ {
CORE.Input.Mouse.currentWheelMove = (Vector2){ (float)xoffset, (float)yoffset }; CORE.Input.Mouse.currentWheelMove = (Vector2){ (float)xoffset, (float)yoffset };
} }
// GLFW3 CursorEnter Callback, when cursor enters the window // GLFW3: Cursor ennter callback, when cursor enters the window
static void CursorEnterCallback(GLFWwindow *window, int enter) static void CursorEnterCallback(GLFWwindow *window, int enter)
{ {
if (enter) CORE.Input.Mouse.cursorOnScreen = true; if (enter) CORE.Input.Mouse.cursorOnScreen = true;
else CORE.Input.Mouse.cursorOnScreen = false; else CORE.Input.Mouse.cursorOnScreen = false;
} }
// GLFW3 Joystick Connected/Disconnected Callback // GLFW3: Joystick connected/disconnected callback
static void JoystickCallback(int jid, int event) static void JoystickCallback(int jid, int event)
{ {
if (event == GLFW_CONNECTED) if (event == GLFW_CONNECTED)
{ {
// WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH, // WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH,
// we can get a not-NULL terminated string, so, we clean destination and only copy up to -1 // only copy up to (MAX_GAMEPAD_NAME_LENGTH -1) to destination string
memset(CORE.Input.Gamepad.name[jid], 0, MAX_GAMEPAD_NAME_LENGTH); memset(CORE.Input.Gamepad.name[jid], 0, MAX_GAMEPAD_NAME_LENGTH);
strncpy(CORE.Input.Gamepad.name[jid], glfwGetJoystickName(jid), MAX_GAMEPAD_NAME_LENGTH - 1); strncpy(CORE.Input.Gamepad.name[jid], glfwGetJoystickName(jid), MAX_GAMEPAD_NAME_LENGTH - 1);
} }
@ -2053,20 +2089,6 @@ static void JoystickCallback(int jid, int event)
} }
} }
// Set screen dimensions from monitor/display dimensions
static void SetDimensionsFromMonitor(GLFWmonitor *monitor)
{
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
// Default display resolution to that of the current mode
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
}
#ifdef _WIN32 #ifdef _WIN32
# define WIN32_CLIPBOARD_IMPLEMENTATION # define WIN32_CLIPBOARD_IMPLEMENTATION
# include "../external/win32_clipboard.h" # include "../external/win32_clipboard.h"

View File

@ -13,10 +13,7 @@
* - TODO * - TODO
* *
* POSSIBLE IMPROVEMENTS: * POSSIBLE IMPROVEMENTS:
* - TODO * - TBD
*
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
* *
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_RGFW * #define RCORE_PLATFORM_RGFW
@ -29,7 +26,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5), Colleague Riley and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5), Colleague Riley and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -48,11 +45,6 @@
* *
**********************************************************************************************/ **********************************************************************************************/
#ifndef RAYLIB_H /* this should never actually happen, it's only here for IDEs */
#include "raylib.h"
#include "../rcore.c"
#endif
#if defined(PLATFORM_WEB_RGFW) #if defined(PLATFORM_WEB_RGFW)
#define RGFW_NO_GL_HEADER #define RGFW_NO_GL_HEADER
#endif #endif
@ -295,14 +287,13 @@ bool WindowShouldClose(void)
// Toggle fullscreen mode // Toggle fullscreen mode
void ToggleFullscreen(void) void ToggleFullscreen(void)
{ {
if (!CORE.Window.fullscreen) if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// Store previous window position (in case we exit fullscreen) // Store previous window position (in case we exit fullscreen)
CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousPosition = CORE.Window.position;
CORE.Window.previousScreen = CORE.Window.screen; CORE.Window.previousScreen = CORE.Window.screen;
platform.mon = RGFW_window_getMonitor(platform.window); platform.mon = RGFW_window_getMonitor(platform.window);
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
RGFW_monitor_scaleToWindow(platform.mon, platform.window); RGFW_monitor_scaleToWindow(platform.mon, platform.window);
@ -310,7 +301,6 @@ void ToggleFullscreen(void)
} }
else else
{ {
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
if (platform.mon.mode.area.w) if (platform.mon.mode.area.w)
@ -336,7 +326,9 @@ void ToggleFullscreen(void)
// Toggle borderless windowed mode // Toggle borderless windowed mode
void ToggleBorderlessWindowed(void) void ToggleBorderlessWindowed(void)
{ {
if (CORE.Window.fullscreen) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) ToggleFullscreen();
if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE))
{ {
CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousPosition = CORE.Window.position;
CORE.Window.previousScreen = CORE.Window.screen; CORE.Window.previousScreen = CORE.Window.screen;
@ -353,8 +345,6 @@ void ToggleBorderlessWindowed(void)
CORE.Window.position = CORE.Window.previousPosition; CORE.Window.position = CORE.Window.previousPosition;
RGFW_window_resize(platform.window, RGFW_AREA(CORE.Window.previousScreen.width, CORE.Window.previousScreen.height)); RGFW_window_resize(platform.window, RGFW_AREA(CORE.Window.previousScreen.width, CORE.Window.previousScreen.height));
} }
CORE.Window.fullscreen = !CORE.Window.fullscreen;
} }
// Set window state: maximized, if resizable // Set window state: maximized, if resizable
@ -390,7 +380,7 @@ void SetWindowState(unsigned int flags)
} }
if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))
{ {
if (!CORE.Window.fullscreen) ToggleFullscreen(); ToggleFullscreen();
} }
if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))
{ {
@ -464,7 +454,7 @@ void ClearWindowState(unsigned int flags)
} }
if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))
{ {
if (CORE.Window.fullscreen) ToggleFullscreen(); ToggleFullscreen();
} }
if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))
{ {
@ -515,7 +505,7 @@ void ClearWindowState(unsigned int flags)
} }
if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE))
{ {
if (CORE.Window.fullscreen) ToggleBorderlessWindowed(); ToggleBorderlessWindowed();
} }
if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT))
{ {
@ -527,46 +517,15 @@ void ClearWindowState(unsigned int flags)
} }
} }
int RGFW_formatToChannels(int format)
{
switch (format)
{
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE:
case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float)
case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float)
return 1;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels)
case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp
return 2;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha)
case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp
return 3;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha)
case PIXELFORMAT_COMPRESSED_DXT3_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_DXT5_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp
return 4;
default: return 4;
}
}
// Set icon for window // Set icon for window
void SetWindowIcon(Image image) void SetWindowIcon(Image image)
{ {
RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), RGFW_formatToChannels(image.format)); if (image.format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
{
TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format");
return;
}
RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), 4);
} }
// Set icon for window // Set icon for window
@ -583,12 +542,17 @@ void SetWindowIcons(Image *images, int count)
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
if (images[i].format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
{
TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format");
continue;
}
if ((bigIcon == NULL) || ((images[i].width > bigIcon->width) && (images[i].height > bigIcon->height))) bigIcon = &images[i]; if ((bigIcon == NULL) || ((images[i].width > bigIcon->width) && (images[i].height > bigIcon->height))) bigIcon = &images[i];
if ((smallIcon == NULL) || ((images[i].width < smallIcon->width) && (images[i].height > smallIcon->height))) smallIcon = &images[i]; if ((smallIcon == NULL) || ((images[i].width < smallIcon->width) && (images[i].height > smallIcon->height))) smallIcon = &images[i];
} }
if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), RGFW_formatToChannels(smallIcon->format), RGFW_iconWindow); if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), 4, RGFW_iconWindow);
if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), RGFW_formatToChannels(bigIcon->format), RGFW_iconTaskbar); if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), 4, RGFW_iconTaskbar);
} }
} }
@ -1289,13 +1253,11 @@ int InitPlatform(void)
// Check window creation flags // Check window creation flags
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
CORE.Window.fullscreen = true;
FLAG_SET(flags, RGFW_windowFullscreen); FLAG_SET(flags, RGFW_windowFullscreen);
} }
if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE))
{ {
CORE.Window.fullscreen = true;
FLAG_SET(flags, RGFW_windowedFullscreen); FLAG_SET(flags, RGFW_windowedFullscreen);
} }
@ -1346,10 +1308,6 @@ int InitPlatform(void)
CORE.Window.display.width = CORE.Window.screen.width; CORE.Window.display.width = CORE.Window.screen.width;
CORE.Window.display.height = CORE.Window.screen.height; CORE.Window.display.height = CORE.Window.screen.height;
#endif #endif
// TODO: Is this needed by raylib now?
// If so, rcore_desktop_sdl should be updated too
//SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) RGFW_window_swapInterval(platform.window, 1); if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) RGFW_window_swapInterval(platform.window, 1);
RGFW_window_makeCurrent(platform.window); RGFW_window_makeCurrent(platform.window);

View File

@ -15,9 +15,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -29,7 +26,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -52,12 +49,12 @@
#define USING_SDL3_PROJECT #define USING_SDL3_PROJECT
#endif #endif
#ifndef SDL_ENABLE_OLD_NAMES #ifndef SDL_ENABLE_OLD_NAMES
#define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily #define SDL_ENABLE_OLD_NAMES // Just in case on SDL3, some in-between compatibily is needed
#endif #endif
// SDL base library (window/rendered, input, timing... functionality) // SDL base library (window/rendered, input, timing... functionality)
#ifdef USING_SDL3_PROJECT #ifdef USING_SDL3_PROJECT
#include "SDL3/SDL.h" #include "SDL3/SDL.h"
#elif USING_SDL2_PROJECT #elif defined(USING_SDL2_PROJECT)
#include "SDL2/SDL.h" #include "SDL2/SDL.h"
#else #else
#include "SDL.h" #include "SDL.h"
@ -71,7 +68,7 @@
// SDL OpenGL functionality (if required, instead of internal renderer) // SDL OpenGL functionality (if required, instead of internal renderer)
#ifdef USING_SDL3_PROJECT #ifdef USING_SDL3_PROJECT
#include "SDL3/SDL_opengl.h" #include "SDL3/SDL_opengl.h"
#elif USING_SDL2_PROJECT #elif defined(USING_SDL2_PROJECT)
#include "SDL2/SDL_opengl.h" #include "SDL2/SDL_opengl.h"
#else #else
#include "SDL_opengl.h" #include "SDL_opengl.h"
@ -257,10 +254,10 @@ static const int CursorsLUT[] = {
#if defined(USING_VERSION_SDL3) #if defined(USING_VERSION_SDL3)
// SDL3 Migration: // SDL3 Migration:
// SDL_WINDOW_FULLSCREEN_DESKTOP has been removed, // SDL_WINDOW_FULLSCREEN_DESKTOP has been removed,
// and you can call SDL_GetWindowFullscreenMode() // and you can call SDL_GetWindowFullscreenMode()
// to see whether an exclusive fullscreen mode will be used // to see whether an exclusive fullscreen mode will be used
// or the borderless fullscreen desktop mode will be used // or the borderless fullscreen desktop mode will be used
#define SDL_WINDOW_FULLSCREEN_DESKTOP SDL_WINDOW_FULLSCREEN #define SDL_WINDOW_FULLSCREEN_DESKTOP SDL_WINDOW_FULLSCREEN
#define SDL_IGNORE false #define SDL_IGNORE false
@ -326,7 +323,7 @@ Uint8 SDL_EventState(Uint32 type, int state)
return stateBefore; return stateBefore;
} }
void SDL_GetCurrentDisplayMode_Adapter(SDL_DisplayID displayID, SDL_DisplayMode* mode) void SDL_GetCurrentDisplayMode_Adapter(SDL_DisplayID displayID, SDL_DisplayMode *mode)
{ {
const SDL_DisplayMode *currentMode = SDL_GetCurrentDisplayMode(displayID); const SDL_DisplayMode *currentMode = SDL_GetCurrentDisplayMode(displayID);
@ -343,9 +340,8 @@ SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth
} }
// SDL3 Migration: // SDL3 Migration:
// SDL_GetDisplayDPI() - // SDL_GetDisplayDPI() not reliable across platforms, approximately replaced by multiplying
// not reliable across platforms, approximately replaced by multiplying // SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms
// SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms
// returns 0 on success or a negative error code on failure // returns 0 on success or a negative error code on failure
int SDL_GetDisplayDPI(int displayIndex, float *ddpi, float *hdpi, float *vdpi) int SDL_GetDisplayDPI(int displayIndex, float *ddpi, float *hdpi, float *vdpi)
{ {
@ -416,7 +412,7 @@ int SDL_GetNumTouchFingers(SDL_TouchID touchID)
return count; return count;
} }
#else // We're on SDL2 #else // SDL2 fallback
// Since SDL2 doesn't have this function we leave a stub // Since SDL2 doesn't have this function we leave a stub
// SDL_GetClipboardData function is available since SDL 3.1.3. (e.g. SDL3) // SDL_GetClipboardData function is available since SDL 3.1.3. (e.g. SDL3)
@ -472,13 +468,11 @@ void ToggleFullscreen(void)
{ {
SDL_SetWindowFullscreen(platform.window, 0); SDL_SetWindowFullscreen(platform.window, 0);
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
CORE.Window.fullscreen = false;
} }
else else
{ {
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN);
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
CORE.Window.fullscreen = true;
} }
} }
else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor");
@ -554,7 +548,7 @@ void SetWindowState(unsigned int flags)
#endif #endif
{ {
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN);
CORE.Window.fullscreen = true; FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor");
} }
@ -644,7 +638,6 @@ void ClearWindowState(unsigned int flags)
if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))
{ {
SDL_SetWindowFullscreen(platform.window, 0); SDL_SetWindowFullscreen(platform.window, 0);
CORE.Window.fullscreen = false;
} }
if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))
{ {
@ -679,6 +672,7 @@ void ClearWindowState(unsigned int flags)
{ {
TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_SDL"); TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_SDL");
} }
if (FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI))
{ {
// NOTE: There also doesn't seem to be a feature to disable high DPI once enabled // NOTE: There also doesn't seem to be a feature to disable high DPI once enabled
TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_SDL"); TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_SDL");
@ -838,10 +832,9 @@ void SetWindowMonitor(int monitor)
if ((monitor >= 0) && (monitor < monitorCount)) if ((monitor >= 0) && (monitor < monitorCount))
#endif #endif
{ {
// NOTE: // NOTE 1: SDL started supporting moving exclusive fullscreen windows between displays on SDL3,
// 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3, // see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba
// see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba // NOTE 2: A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again
// 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again
const bool wasFullscreen = (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))? true : false; const bool wasFullscreen = (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))? true : false;
const int screenWidth = CORE.Window.screen.width; const int screenWidth = CORE.Window.screen.width;
@ -859,14 +852,13 @@ void SetWindowMonitor(int monitor)
// If the screen size is larger than the monitor usable area, anchor it on the top left corner, otherwise, center it // If the screen size is larger than the monitor usable area, anchor it on the top left corner, otherwise, center it
if ((screenWidth >= usableBounds.w) || (screenHeight >= usableBounds.h)) if ((screenWidth >= usableBounds.w) || (screenHeight >= usableBounds.h))
{ {
// NOTE: // NOTE 1: There's a known issue where if the window larger than the target display bounds,
// 1. There's a known issue where if the window larger than the target display bounds, // when moving the windows to that display, the window could be clipped back
// when moving the windows to that display, the window could be clipped back // ending up positioned partly outside the target display
// ending up positioned partly outside the target display // NOTE 2: The workaround for that is, previously to moving the window,
// 2. The workaround for that is, previously to moving the window, // setting the window size to the target display size, so they match
// setting the window size to the target display size, so they match // NOTE 3: It wasn't done here because we can't assume changing the window size automatically
// 3. It wasn't done here because we can't assume changing the window size automatically // is acceptable behavior by the user
// is acceptable behavior by the user
SDL_SetWindowPosition(platform.window, usableBounds.x, usableBounds.y); SDL_SetWindowPosition(platform.window, usableBounds.x, usableBounds.y);
CORE.Window.position.x = usableBounds.x; CORE.Window.position.x = usableBounds.x;
CORE.Window.position.y = usableBounds.y; CORE.Window.position.y = usableBounds.y;
@ -1041,7 +1033,7 @@ int GetMonitorPhysicalWidth(int monitor)
SDL_DisplayMode mode; SDL_DisplayMode mode;
SDL_GetCurrentDisplayMode(monitor, &mode); SDL_GetCurrentDisplayMode(monitor, &mode);
// Calculate size on inches, then convert to millimeter // Calculate size on inches, then convert to millimeter
if (ddpi > 0.0f) width = (mode.w/ddpi)*25.4f; if (ddpi > 0.0f) width = (int)((mode.w/ddpi)*25.4f);
} }
else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor");
@ -1065,7 +1057,7 @@ int GetMonitorPhysicalHeight(int monitor)
SDL_DisplayMode mode; SDL_DisplayMode mode;
SDL_GetCurrentDisplayMode(monitor, &mode); SDL_GetCurrentDisplayMode(monitor, &mode);
// Calculate size on inches, then convert to millimeter // Calculate size on inches, then convert to millimeter
if (ddpi > 0.0f) height = (mode.h/ddpi)*25.4f; if (ddpi > 0.0f) height = (int)((mode.h/ddpi)*25.4f);
} }
else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor");
@ -1127,14 +1119,15 @@ Vector2 GetWindowScaleDPI(void)
{ {
Vector2 scale = { 1.0f, 1.0f }; Vector2 scale = { 1.0f, 1.0f };
#ifndef USING_VERSION_SDL3 #if defined(USING_VERSION_SDL3)
// NOTE: SDL_GetWindowDisplayScale was only added on SDL3 // NOTE: SDL_GetWindowDisplayScale added on SDL3
// REF: https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale // REF: https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale
// TODO: Implement the window scale factor calculation manually
TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
#else
scale.x = SDL_GetWindowDisplayScale(platform.window); scale.x = SDL_GetWindowDisplayScale(platform.window);
scale.y = scale.x; scale.y = scale.x;
#else
// NOTE: SDL_GetWindowDisplayScale not available on SDL2
// TODO: Implement the window scale factor calculation manually
TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
#endif #endif
return scale; return scale;
@ -1195,7 +1188,7 @@ Image GetClipboardImage(void)
if (fileData) if (fileData)
{ {
image = LoadImageFromMemory(imageExtensions[i], fileData, dataSize); image = LoadImageFromMemory(imageExtensions[i], fileData, (int)dataSize);
if (IsImageValid(image)) if (IsImageValid(image))
{ {
TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]); TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]);
@ -1254,7 +1247,7 @@ void DisableCursor(void)
void SwapScreenBuffer(void) void SwapScreenBuffer(void)
{ {
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) #if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
// NOTE: We use a preprocessor condition here because `rlCopyFramebuffer` is only declared for software rendering // NOTE: We use a preprocessor condition here because rlCopyFramebuffer() is only declared for software rendering
SDL_Surface *surface = SDL_GetWindowSurface(platform.window); SDL_Surface *surface = SDL_GetWindowSurface(platform.window);
rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, surface->pixels); rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, surface->pixels);
SDL_UpdateWindowSurface(platform.window); SDL_UpdateWindowSurface(platform.window);
@ -1426,12 +1419,12 @@ void PollInputEvents(void)
#if defined(USING_VERSION_SDL3) #if defined(USING_VERSION_SDL3)
// const char *data; // The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events // const char *data; // The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events
// Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, // Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE,
// and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, // and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events,
// you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed // you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data); strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1);
#else #else
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file); strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1);
SDL_free(event.drop.file); SDL_free(event.drop.file);
#endif #endif
@ -1442,9 +1435,9 @@ void PollInputEvents(void)
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
#if defined(USING_VERSION_SDL3) #if defined(USING_VERSION_SDL3)
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data); strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1);
#else #else
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file); strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1);
SDL_free(event.drop.file); SDL_free(event.drop.file);
#endif #endif
@ -1454,7 +1447,7 @@ void PollInputEvents(void)
} break; } break;
// Window events are also polled (Minimized, maximized, close...) // Window events are also polled (minimized, maximized, close...)
#ifndef USING_VERSION_SDL3 #ifndef USING_VERSION_SDL3
// SDL3 states: // SDL3 states:
@ -1473,7 +1466,7 @@ void PollInputEvents(void)
const int height = event.window.data2; const int height = event.window.data2;
SetupViewport(width, height); SetupViewport(width, height);
// if we are doing automatic DPI scaling, then the "screen" size is divided by the window scale // if we are doing automatic DPI scaling, then the "screen" size is divided by the window scale
if (IsWindowState(FLAG_WINDOW_HIGHDPI)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{ {
CORE.Window.screen.width = (int)(width/GetWindowScaleDPI().x); CORE.Window.screen.width = (int)(width/GetWindowScaleDPI().x);
CORE.Window.screen.height = (int)(height/GetWindowScaleDPI().y); CORE.Window.screen.height = (int)(height/GetWindowScaleDPI().y);
@ -1488,7 +1481,8 @@ void PollInputEvents(void)
CORE.Window.resizedLastFrame = true; CORE.Window.resizedLastFrame = true;
#ifndef USING_VERSION_SDL3 #ifndef USING_VERSION_SDL3
// Manually detect if the window was maximized (due to SDL2 restore being unreliable on some platforms) to remove the FLAG_WINDOW_MAXIMIZED accordingly // Manually detect if the window was maximized (due to SDL2 restore being unreliable on some platforms)
// to remove the FLAG_WINDOW_MAXIMIZED accordingly
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED))
{ {
int borderTop = 0; int borderTop = 0;
@ -1504,14 +1498,8 @@ void PollInputEvents(void)
#endif #endif
} break; } break;
case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_ENTER: CORE.Input.Mouse.cursorOnScreen = true; break;
{ case SDL_WINDOWEVENT_LEAVE: CORE.Input.Mouse.cursorOnScreen = false; break;
CORE.Input.Mouse.cursorOnScreen = true;
} break;
case SDL_WINDOWEVENT_LEAVE:
{
CORE.Input.Mouse.cursorOnScreen = false;
} break;
case SDL_WINDOWEVENT_MINIMIZED: case SDL_WINDOWEVENT_MINIMIZED:
{ {
@ -1626,7 +1614,7 @@ void PollInputEvents(void)
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
{ {
// NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW // NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW
// The following conditions align SDL with raylib.h MouseButton enum order // The following conditions align SDL with raylib.h MouseButton enum order
int btn = event.button.button - 1; int btn = event.button.button - 1;
if (btn == 2) btn = 1; if (btn == 2) btn = 1;
else if (btn == 1) btn = 2; else if (btn == 1) btn = 2;
@ -1639,7 +1627,7 @@ void PollInputEvents(void)
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
{ {
// NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW // NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW
// The following conditions align SDL with raylib.h MouseButton enum order // The following conditions align SDL with raylib.h MouseButton enum order
int btn = event.button.button - 1; int btn = event.button.button - 1;
if (btn == 2) btn = 1; if (btn == 2) btn = 1;
else if (btn == 1) btn = 2; else if (btn == 1) btn = 2;
@ -1750,7 +1738,11 @@ void PollInputEvents(void)
{ {
int button = -1; int button = -1;
#if defined(USING_VERSION_SDL3)
switch (event.gbutton.button) switch (event.gbutton.button)
#else
switch (event.jbutton.button)
#endif
{ {
case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break;
case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
@ -1778,7 +1770,11 @@ void PollInputEvents(void)
{ {
for (int i = 0; i < MAX_GAMEPADS; i++) for (int i = 0; i < MAX_GAMEPADS; i++)
{ {
#if defined(USING_VERSION_SDL3)
if (platform.gamepadId[i] == event.gbutton.which) if (platform.gamepadId[i] == event.gbutton.which)
#else
if (platform.gamepadId[i] == event.jbutton.which)
#endif
{ {
CORE.Input.Gamepad.currentButtonState[i][button] = 1; CORE.Input.Gamepad.currentButtonState[i][button] = 1;
CORE.Input.Gamepad.lastButtonPressed = button; CORE.Input.Gamepad.lastButtonPressed = button;
@ -1791,7 +1787,11 @@ void PollInputEvents(void)
{ {
int button = -1; int button = -1;
#if defined(USING_VERSION_SDL3)
switch (event.gbutton.button) switch (event.gbutton.button)
#else
switch (event.jbutton.button)
#endif
{ {
case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break;
case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
@ -1819,7 +1819,11 @@ void PollInputEvents(void)
{ {
for (int i = 0; i < MAX_GAMEPADS; i++) for (int i = 0; i < MAX_GAMEPADS; i++)
{ {
#if defined(USING_VERSION_SDL3)
if (platform.gamepadId[i] == event.gbutton.which) if (platform.gamepadId[i] == event.gbutton.which)
#else
if (platform.gamepadId[i] == event.jbutton.which)
#endif
{ {
CORE.Input.Gamepad.currentButtonState[i][button] = 0; CORE.Input.Gamepad.currentButtonState[i][button] = 0;
if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
@ -1924,11 +1928,7 @@ int InitPlatform(void)
FLAG_SET(flags, SDL_WINDOW_MOUSE_CAPTURE); // Window has mouse captured FLAG_SET(flags, SDL_WINDOW_MOUSE_CAPTURE); // Window has mouse captured
// Check window creation flags // Check window creation flags
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) FLAG_SET(flags, SDL_WINDOW_FULLSCREEN);
{
CORE.Window.fullscreen = true;
FLAG_SET(flags, SDL_WINDOW_FULLSCREEN);
}
//if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, SDL_WINDOW_HIDDEN); //if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, SDL_WINDOW_HIDDEN);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, SDL_WINDOW_BORDERLESS); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, SDL_WINDOW_BORDERLESS);
@ -2054,28 +2054,23 @@ int InitPlatform(void)
platform.gamepadId[i] = -1; // Set all gamepad initial instance ids as invalid to not conflict with instance id zero platform.gamepadId[i] = -1; // Set all gamepad initial instance ids as invalid to not conflict with instance id zero
} }
int numJoysticks = 0; int numJoysticks = SDL_NumJoysticks();
SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks); // array of joystick IDs, they do not start from 0
if (joysticks) for (int i = 0; (i < numJoysticks) && (i < MAX_GAMEPADS); i++)
{ {
for (int i = 0; (i < numJoysticks) && (i < MAX_GAMEPADS); i++) platform.gamepad[i] = SDL_GameControllerOpen(i);
{ platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i]));
platform.gamepad[i] = SDL_GameControllerOpen(joysticks[i]);
platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i]));
if (platform.gamepad[i]) if (platform.gamepad[i])
{ {
CORE.Input.Gamepad.ready[i] = true; CORE.Input.Gamepad.ready[i] = true;
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i])); CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i]));
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1); strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1);
CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0'; CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0';
}
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
} }
SDL_free(joysticks); else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
} }
// Disable mouse events being interpreted as touch events // Disable mouse events being interpreted as touch events
@ -2196,7 +2191,7 @@ static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
for (int i = 0; i < CORE.Input.Touch.pointCount; i++) for (int i = 0; i < CORE.Input.Touch.pointCount; i++)
{ {
SDL_Finger *finger = SDL_GetTouchFinger(event.touchId, i); SDL_Finger *finger = SDL_GetTouchFinger(event.touchId, i);
CORE.Input.Touch.pointId[i] = finger->id; CORE.Input.Touch.pointId[i] = (int)finger->id;
CORE.Input.Touch.position[i].x = finger->x*CORE.Window.screen.width; CORE.Input.Touch.position[i].x = finger->x*CORE.Window.screen.width;
CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height; CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height;
CORE.Input.Touch.currentTouchState[i] = 1; CORE.Input.Touch.currentTouchState[i] = 1;

View File

@ -13,9 +13,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -26,7 +23,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -263,7 +260,7 @@ static bool DecoratedFromStyle(DWORD style)
static DWORD MakeWindowStyle(unsigned flags) static DWORD MakeWindowStyle(unsigned flags)
{ {
// Flag is not needed because there are no child windows, // Flag is not needed because there are no child windows,
// but supposedly it improves efficiency, plus, windows adds this // but supposedly it improves efficiency, plus, windows adds this
// flag automatically anyway so it keeps flags in sync with the OS // flag automatically anyway so it keeps flags in sync with the OS
DWORD style = WS_CLIPSIBLINGS; DWORD style = WS_CLIPSIBLINGS;
@ -436,7 +433,7 @@ static bool UpdateWindowSize(int mode, HWND hwnd, int width, int height, unsigne
return true; return true;
} }
// Verify if we are running in Windows 10 version 1703 (Creators Update) // Check if running in Windows 10 version 1703 (Creators Update)
static BOOL IsWindows10Version1703OrGreaterWin32(void) static BOOL IsWindows10Version1703OrGreaterWin32(void)
{ {
HMODULE ntdll = LoadLibraryW(L"ntdll.dll"); HMODULE ntdll = LoadLibraryW(L"ntdll.dll");
@ -1141,7 +1138,7 @@ void ShowCursor(void)
// Hides mouse cursor // Hides mouse cursor
void HideCursor(void) void HideCursor(void)
{ {
// NOTE: We use SetCursor() instead of ShowCursor() because // NOTE: Using SetCursor() instead of ShowCursor() because
// it makes it easy to only hide the cursor while it's inside the client area // it makes it easy to only hide the cursor while it's inside the client area
SetCursor(NULL); SetCursor(NULL);
CORE.Input.Mouse.cursorHidden = true; CORE.Input.Mouse.cursorHidden = true;
@ -1230,7 +1227,7 @@ void SwapScreenBuffer(void)
// Get elapsed time measure in seconds // Get elapsed time measure in seconds
double GetTime(void) double GetTime(void)
{ {
LARGE_INTEGER now = 0; LARGE_INTEGER now = { 0 };
QueryPerformanceCounter(&now); QueryPerformanceCounter(&now);
return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart; return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart;
} }
@ -1348,7 +1345,7 @@ void PollInputEvents(void)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Initialize modern OpenGL context // Initialize modern OpenGL context
// NOTE: We need to create a dummy context first to query required extensions // NOTE: Creating a dummy context first to query required extensions
HGLRC InitOpenGL(HWND hwnd, HDC hdc) HGLRC InitOpenGL(HWND hwnd, HDC hdc)
{ {
// First, create a dummy context to get WGL extensions // First, create a dummy context to get WGL extensions
@ -1463,7 +1460,7 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
0 // Terminator 0 // Terminator
}; };
// NOTE: We are not sharing context resources so, second parameters is NULL // NOTE: Not sharing context resources so, second parameters is NULL
realContext = wglCreateContextAttribsARB(hdc, NULL, contextAttribs); realContext = wglCreateContextAttribsARB(hdc, NULL, contextAttribs);
// Check for error context creation errors // Check for error context creation errors
@ -1479,8 +1476,8 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
// Activate real context // Activate real context
if (realContext) wglMakeCurrent(hdc, realContext); if (realContext) wglMakeCurrent(hdc, realContext);
// Once we got a real modern OpenGL context, // Once a real modern OpenGL context is created,
// we can load required extensions (function pointers) // required extensions can be loaded (function pointers)
rlLoadExtensions(WglGetProcAddress); rlLoadExtensions(WglGetProcAddress);
return realContext; return realContext;
@ -1524,7 +1521,7 @@ int InitPlatform(void)
.lpfnWndProc = WndProc, // Custom procedure assigned .lpfnWndProc = WndProc, // Custom procedure assigned
.cbWndExtra = sizeof(LONG_PTR), // extra space for the Tuple object ptr .cbWndExtra = sizeof(LONG_PTR), // extra space for the Tuple object ptr
.hInstance = hInstance, .hInstance = hInstance,
.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW), // TODO: Audit if we want to set this since we're implementing WM_SETCURSOR .hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW), // TODO: Check if this is really required, since WM_SETCURSOR event is processed
.lpszClassName = CLASS_NAME // Class name: L"raylibWindow" .lpszClassName = CLASS_NAME // Class name: L"raylibWindow"
}; };
@ -1857,8 +1854,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
SIZE *inoutSize = (SIZE *)lparam; SIZE *inoutSize = (SIZE *)lparam;
UINT newDpi = (UINT)wparam; // TODO: WARNING: Converting from WPARAM = UINT_PTR UINT newDpi = (UINT)wparam; // TODO: WARNING: Converting from WPARAM = UINT_PTR
// for any of these other cases, we might want to post a window // For the following flag changes, a window resize event should be posted,
// resize event after the dpi changes? // TODO: Should it be done after dpi changes?
if (CORE.Window.flags & FLAG_WINDOW_MINIMIZED) return TRUE; if (CORE.Window.flags & FLAG_WINDOW_MINIMIZED) return TRUE;
if (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) return TRUE; if (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) return TRUE;
if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) return TRUE; if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) return TRUE;
@ -1877,14 +1874,24 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
} break; } break;
case WM_DPICHANGED: case WM_DPICHANGED:
{ {
// Get current dpi scale factor
float scalex = HIWORD(wparam)/96.0f;
float scaley = LOWORD(wparam)/96.0f;
RECT *suggestedRect = (RECT *)lparam; RECT *suggestedRect = (RECT *)lparam;
// Never set the window size to anything other than the suggested rect here // Never set the window size to anything other than the suggested rect here
// Doing so can cause a window to stutter between monitors when transitioning between them // Doing so can cause a window to stutter between monitors when transitioning between them
int result = (int)SetWindowPos(hwnd, NULL, suggestedRect->left, suggestedRect->top, int result = (int)SetWindowPos(hwnd, NULL,
suggestedRect->right - suggestedRect->left, suggestedRect->bottom - suggestedRect->top, SWP_NOZORDER | SWP_NOACTIVATE); suggestedRect->left, suggestedRect->top,
suggestedRect->right - suggestedRect->left,
suggestedRect->bottom - suggestedRect->top,
SWP_NOZORDER | SWP_NOACTIVATE);
if (result == 0) TRACELOG(LOG_ERROR, "Failed to set window position [ERROR: %lu]", GetLastError()); if (result == 0) TRACELOG(LOG_ERROR, "Failed to set window position [ERROR: %lu]", GetLastError());
// TODO: Update screen data, render size, screen scaling, viewport...
} break; } break;
case WM_SETCURSOR: case WM_SETCURSOR:
{ {
@ -2018,8 +2025,8 @@ static void HandleRawInput(LPARAM lparam)
if (input.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) TRACELOG(LOG_ERROR, "TODO: handle virtual desktop mouse inputs!"); if (input.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) TRACELOG(LOG_ERROR, "TODO: handle virtual desktop mouse inputs!");
// Trick to keep the mouse position at 0,0 and instead move // Trick to keep the mouse position at (0,0) and instead move
// the previous position so we can still get a proper mouse delta // the previous position so a proper mouse delta can still be retrieved
//CORE.Input.Mouse.previousPosition.x -= input.data.mouse.lLastX; //CORE.Input.Mouse.previousPosition.x -= input.data.mouse.lLastX;
//CORE.Input.Mouse.previousPosition.y -= input.data.mouse.lLastY; //CORE.Input.Mouse.previousPosition.y -= input.data.mouse.lLastY;
//if (CORE.Input.Mouse.currentPosition.x != 0) abort(); //if (CORE.Input.Mouse.currentPosition.x != 0) abort();
@ -2039,8 +2046,7 @@ static void HandleWindowResize(HWND hwnd, int *width, int *height)
// TODO: Update framebuffer on resize // TODO: Update framebuffer on resize
CORE.Window.currentFbo.width = (int)clientSize.cx; CORE.Window.currentFbo.width = (int)clientSize.cx;
CORE.Window.currentFbo.height = (int)clientSize.cy; CORE.Window.currentFbo.height = (int)clientSize.cy;
//glViewport(0, 0, clientSize.cx, clientSize.cy); //SetupViewport(0, 0, clientSize.cx, clientSize.cy);
//SetupFramebuffer(0, 0);
SetupViewport(clientSize.cx, clientSize.cy); SetupViewport(clientSize.cx, clientSize.cy);
CORE.Window.resizedLastFrame = true; CORE.Window.resizedLastFrame = true;
@ -2132,12 +2138,12 @@ static unsigned SanitizeFlags(int mode, unsigned flags)
// This design takes care of many odd corner cases. For example, if you want to restore // This design takes care of many odd corner cases. For example, if you want to restore
// a window that was previously maximized AND minimized and you want to remove both these // a window that was previously maximized AND minimized and you want to remove both these
// flags, you actually need to call ShowWindow with SW_RESTORE twice. Another example is // flags, you actually need to call ShowWindow with SW_RESTORE twice. Another example is
// if you have a maximized window, if the undecorated flag is modified then we'd need to // if you have a maximized window, if the undecorated flag is modified then the window style
// update the window style, but updating the style would mean the window size would change // needs to be updated, but updating the style would mean the window size would change
// causing the window to lose its Maximized state which would mean we'd need to update the // causing the window to lose its Maximized state which would mean the window size
// window size and then update the window style a second time to restore that maximized // needs to be updated, followed by the update of window style, a second time, to restore that maximized
// state. This implementation is able to handle any/all of these special situations with a // state. This implementation is able to handle any/all of these special situations with a
// retry loop that continues until we either reach the desired state or the state stops changing // retry loop that continues until either the desired state is reached or the state stops changing
static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height) static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height)
{ {
// Flags that just apply immediately without needing any operations // Flags that just apply immediately without needing any operations

View File

@ -13,9 +13,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only) * #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only)
* Reconfigure standard input to receive key inputs, works with SSH connection * Reconfigure standard input to receive key inputs, works with SSH connection
@ -29,7 +26,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -89,6 +86,10 @@
#define EGL_OPENGL_ES3_BIT 0x40 #define EGL_OPENGL_ES3_BIT 0x40
#endif #endif
#ifndef EGL_PLATFORM_GBM_KHR
#define EGL_PLATFORM_GBM_KHR 0x31D7
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -135,8 +136,12 @@ typedef struct {
char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab
bool cursorRelative; // Relative cursor mode bool cursorRelative; // Relative cursor mode
int mouseFd; // File descriptor for the evdev mouse/touch/gestures int mouseFd; // File descriptor for the evdev mouse/touch/gestures
bool mouseIsTouch; // Check if the current mouse device is actually a touchscreen
Rectangle absRange; // Range of values for absolute pointing devices (touchscreens) Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)
int touchSlot; // Hold the touch slot number of the currently being sent multitouch block int touchSlot; // Hold the touch slot number of the currently being sent multitouch block
bool touchActive[MAX_TOUCH_POINTS]; // Track which touch points are currently active
Vector2 touchPosition[MAX_TOUCH_POINTS]; // Track touch positions for each slot
int touchId[MAX_TOUCH_POINTS]; // Track touch IDs for each slot
// Gamepad data // Gamepad data
int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor
@ -265,6 +270,8 @@ static int FindMatchingConnectorMode(const drmModeConnector *connector, const dr
static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list
static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list
static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform())
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Declaration // Module Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -908,7 +915,7 @@ void SwapScreenBuffer(void)
{ {
TRACELOG(LOG_ERROR, "DISPLAY: Failed to get DRM resources"); TRACELOG(LOG_ERROR, "DISPLAY: Failed to get DRM resources");
drmModeRmFB(platform.fd, fb); drmModeRmFB(platform.fd, fb);
struct drm_mode_destroy_dumb dreq = {0}; struct drm_mode_destroy_dumb dreq = { 0 };
dreq.handle = creq.handle; dreq.handle = creq.handle;
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
return; return;
@ -948,7 +955,7 @@ void SwapScreenBuffer(void)
{ {
TRACELOG(LOG_ERROR, "DISPLAY: No compatible CRTC found"); TRACELOG(LOG_ERROR, "DISPLAY: No compatible CRTC found");
drmModeRmFB(platform.fd, fb); drmModeRmFB(platform.fd, fb);
struct drm_mode_destroy_dumb dreq = {0}; struct drm_mode_destroy_dumb dreq = { 0 };
dreq.handle = creq.handle; dreq.handle = creq.handle;
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
return; return;
@ -964,7 +971,7 @@ void SwapScreenBuffer(void)
TRACELOG(LOG_ERROR, "DISPLAY: Mode: %dx%d@%d", mode->hdisplay, mode->vdisplay, mode->vrefresh); TRACELOG(LOG_ERROR, "DISPLAY: Mode: %dx%d@%d", mode->hdisplay, mode->vdisplay, mode->vrefresh);
drmModeRmFB(platform.fd, fb); drmModeRmFB(platform.fd, fb);
struct drm_mode_destroy_dumb dreq = {0}; struct drm_mode_destroy_dumb dreq = { 0 };
dreq.handle = creq.handle; dreq.handle = creq.handle;
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
return; return;
@ -982,7 +989,7 @@ void SwapScreenBuffer(void)
// Clean up previous dumb buffer // Clean up previous dumb buffer
if (platform.prevDumbHandle) if (platform.prevDumbHandle)
{ {
struct drm_mode_destroy_dumb dreq = {0}; struct drm_mode_destroy_dumb dreq = { 0 };
dreq.handle = platform.prevDumbHandle; dreq.handle = platform.prevDumbHandle;
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
} }
@ -1113,9 +1120,6 @@ void PollInputEvents(void)
// Register previous touch states // Register previous touch states
for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
// Reset touch positions to invalid state
for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ -1, -1 };
// Map touch position to mouse position for convenience // Map touch position to mouse position for convenience
// NOTE: For DRM touchscreen devices, this mapping is disabled to avoid false touch detection // NOTE: For DRM touchscreen devices, this mapping is disabled to avoid false touch detection
// CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; // CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
@ -1147,7 +1151,6 @@ int InitPlatform(void)
// Initialize graphic device: display/window and graphic context // Initialize graphic device: display/window and graphic context
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM) #if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
@ -1158,7 +1161,8 @@ int InitPlatform(void)
platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4) platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: platform-gpu-card opened successfully"); if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: platform-gpu-card opened successfully");
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL)) drmModeRes *res = NULL;
if ((platform.fd == -1) || ((res = drmModeGetResources(platform.fd)) == NULL))
{ {
if (platform.fd != -1) close(platform.fd); if (platform.fd != -1) close(platform.fd);
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open platform-gpu-card, trying card1"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to open platform-gpu-card, trying card1");
@ -1166,7 +1170,7 @@ int InitPlatform(void)
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card1 opened successfully"); if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card1 opened successfully");
} }
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL)) if ((platform.fd == -1) || ((res = drmModeGetResources(platform.fd)) == NULL))
{ {
if (platform.fd != -1) close(platform.fd); if (platform.fd != -1) close(platform.fd);
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card1, trying card0"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card1, trying card0");
@ -1174,7 +1178,7 @@ int InitPlatform(void)
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card0 opened successfully"); if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card0 opened successfully");
} }
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL)) if ((platform.fd == -1) || ((res = drmModeGetResources(platform.fd)) == NULL))
{ {
if (platform.fd != -1) close(platform.fd); if (platform.fd != -1) close(platform.fd);
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card0, trying card2"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card0, trying card2");
@ -1189,7 +1193,6 @@ int InitPlatform(void)
return -1; return -1;
} }
drmModeRes *res = drmModeGetResources(platform.fd);
if (!res) if (!res)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources"); TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
@ -1412,9 +1415,27 @@ int InitPlatform(void)
}; };
EGLint numConfigs = 0; EGLint numConfigs = 0;
const char *eglClientExtensions = NULL;
// Get an EGL device connection // Get an EGL device connection
platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice); // NOTE: eglGetPlatformDisplay() is preferred over eglGetDisplay() legacy call
platform.device = EGL_NO_DISPLAY;
#if defined(EGL_VERSION_1_5)
platform.device = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL);
#else
// Check if extension is available for eglGetPlatformDisplayEXT()
// NOTE: Better compatibility with some drivers (e.g. Mali Midgard)
eglClientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if ((eglClientExtensions != NULL) && (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL))
{
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
if (eglGetPlatformDisplayEXT != NULL) platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL);
}
// In case extension not found or display could not be retrieved, try useing legacy version
if (platform.device == EGL_NO_DISPLAY) platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice);
#endif
if (platform.device == EGL_NO_DISPLAY) if (platform.device == EGL_NO_DISPLAY)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
@ -1494,8 +1515,21 @@ int InitPlatform(void)
} }
// Create an EGL window surface // Create an EGL window surface
platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL); platform.surface = EGL_NO_SURFACE;
if (EGL_NO_SURFACE == platform.surface)
if ((eglClientExtensions != NULL) && (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL))
{
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
if (eglCreatePlatformWindowSurfaceEXT != NULL) platform.surface = eglCreatePlatformWindowSurfaceEXT(platform.device, platform.config, platform.gbmSurface, NULL);
}
if (platform.surface == EGL_NO_SURFACE)
{
platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL);
}
if (platform.surface == EGL_NO_SURFACE)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError()); TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());
return -1; return -1;
@ -1564,7 +1598,11 @@ int InitPlatform(void)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow();
// If graphic device is no properly initialized, we end program // If graphic device is no properly initialized, we end program
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } if (!CORE.Window.ready)
{
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device");
return -1;
}
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2); else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
// Set some default window flags // Set some default window flags
@ -1882,8 +1920,15 @@ static void InitEvdevInput(void)
{ {
CORE.Input.Touch.position[i].x = -1; CORE.Input.Touch.position[i].x = -1;
CORE.Input.Touch.position[i].y = -1; CORE.Input.Touch.position[i].y = -1;
platform.touchActive[i] = false;
platform.touchPosition[i].x = -1;
platform.touchPosition[i].y = -1;
platform.touchId[i] = -1;
} }
// Initialize touch slot
platform.touchSlot = 0;
// Reset keyboard key state // Reset keyboard key state
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)
{ {
@ -2046,17 +2091,49 @@ static void ConfigureEvdevDevice(char *device)
const char *deviceKindStr = "unknown"; const char *deviceKindStr = "unknown";
if (isMouse || isTouch) if (isMouse || isTouch)
{ {
deviceKindStr = "mouse"; bool prioritize = false;
if (platform.mouseFd != -1) close(platform.mouseFd);
platform.mouseFd = fd;
if (absAxisCount > 0) // Priority logic: touchscreens override Mice
// 1. No device set yet? Take it
if (platform.mouseFd == -1) prioritize = true;
// 2. Current is mouse, new is touch? Upgrade to touch
else if (isTouch && !platform.mouseIsTouch) prioritize = true;
// 3. Current is touch, new is touch? Use the new one (last one found wins, standard behavior)
else if (isTouch && platform.mouseIsTouch) prioritize = true;
// 4. Current is mouse, new is mouse? Use the new one
else if (!isTouch && !platform.mouseIsTouch) prioritize = true;
// 5. Current is touch, new is mouse? Ignore the mouse, keep the touchscreen
else prioritize = false;
if (prioritize)
{ {
platform.absRange.x = absinfo[ABS_X].info.minimum; deviceKindStr = isTouch? "touchscreen" : "mouse";
platform.absRange.width = absinfo[ABS_X].info.maximum - absinfo[ABS_X].info.minimum;
platform.absRange.y = absinfo[ABS_Y].info.minimum; if (platform.mouseFd != -1)
platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum; {
TRACELOG(LOG_INFO, "INPUT: Overwriting previous input device with new %s", deviceKindStr);
close(platform.mouseFd);
}
platform.mouseFd = fd;
platform.mouseIsTouch = isTouch;
if (absAxisCount > 0)
{
platform.absRange.x = absinfo[ABS_X].info.minimum;
platform.absRange.width = absinfo[ABS_X].info.maximum - absinfo[ABS_X].info.minimum;
platform.absRange.y = absinfo[ABS_Y].info.minimum;
platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum;
}
TRACELOG(LOG_INFO, "INPUT: Initialized input device %s as %s", device, deviceKindStr);
}
else
{
TRACELOG(LOG_INFO, "INPUT: Ignoring device %s (keeping higher priority %s device)", device, platform.mouseIsTouch ? "touchscreen" : "mouse");
close(fd);
return;
} }
} }
else if (isGamepad && !isMouse && !isKeyboard && (platform.gamepadCount < MAX_GAMEPADS)) else if (isGamepad && !isMouse && !isKeyboard && (platform.gamepadCount < MAX_GAMEPADS))
@ -2127,18 +2204,15 @@ static void PollKeyboardEvents(void)
// If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard // If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard
platform.eventKeyboardMode = true; platform.eventKeyboardMode = true;
#endif #endif
// Keyboard keys appear for codes 1 to 255, ignore everthing else // Keyboard keys appear for codes 1 to 255, ignore everthing else
if ((event.code >= 1) && (event.code <= 255)) if ((event.code >= 1) && (event.code <= 255))
{ {
// Lookup the scancode in the keymap to get a keycode // Lookup the scancode in the keymap to get a keycode
keycode = linuxToRaylibMap[event.code]; keycode = linuxToRaylibMap[event.code];
// Make sure we got a valid keycode // Make sure we got a valid keycode
if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS)) if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS))
{ {
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt // WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL, // Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat // absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
@ -2187,16 +2261,15 @@ static void PollGamepadEvents(void)
{ {
if (event.code < KEYMAP_SIZE) if (event.code < KEYMAP_SIZE)
{ {
short keycodeRaylib = linuxToRaylibMap[event.code]; short keycode = linuxToRaylibMap[event.code]; // raylib keycode
TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0)? "UP" : "DOWN", event.code, keycodeRaylib); TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0)? "UP" : "DOWN", event.code, keycode);
if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS)) if ((keycode != 0) && (keycode < MAX_GAMEPAD_BUTTONS))
{ {
// 1 - button pressed, 0 - button released // 1 - button pressed, 0 - button released
CORE.Input.Gamepad.currentButtonState[i][keycodeRaylib] = event.value; CORE.Input.Gamepad.currentButtonState[i][keycode] = event.value;
CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycode : GAMEPAD_BUTTON_UNKNOWN;
CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycodeRaylib : GAMEPAD_BUTTON_UNKNOWN;
} }
} }
} }
@ -2230,6 +2303,7 @@ static void PollMouseEvents(void)
struct input_event event = { 0 }; struct input_event event = { 0 };
int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE
static bool isMultitouch = false; // Detect if device supports MT events
// Try to read data from the mouse/touch/gesture and only continue if successful // Try to read data from the mouse/touch/gesture and only continue if successful
while (read(fd, &event, sizeof(event)) == (int)sizeof(event)) while (read(fd, &event, sizeof(event)) == (int)sizeof(event))
@ -2275,39 +2349,102 @@ static void PollMouseEvents(void)
if (event.code == ABS_X) if (event.code == ABS_X)
{ {
CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange
CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange
touchAction = 2; // TOUCH_ACTION_MOVE // Update single touch position only if it's active and no MT events are being used
if (platform.touchActive[0] && !isMultitouch)
{
platform.touchPosition[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width;
if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
} }
if (event.code == ABS_Y) if (event.code == ABS_Y)
{ {
CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange
CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange
touchAction = 2; // TOUCH_ACTION_MOVE // Update single touch position only if it's active and no MT events are being used
if (platform.touchActive[0] && !isMultitouch)
{
platform.touchPosition[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height;
if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
} }
// Multitouch movement // Multitouch movement
if (event.code == ABS_MT_SLOT) platform.touchSlot = event.value; // Remember the slot number for the folowing events if (event.code == ABS_MT_SLOT)
{
platform.touchSlot = event.value;
isMultitouch = true;
}
if (event.code == ABS_MT_POSITION_X) if (event.code == ABS_MT_POSITION_X)
{ {
if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange isMultitouch = true;
if (platform.touchSlot < MAX_TOUCH_POINTS)
{
platform.touchPosition[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width;
// If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active.
// Only set to MOVE if we haven't already detected a DOWN or UP event this frame
if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
} }
if (event.code == ABS_MT_POSITION_Y) if (event.code == ABS_MT_POSITION_Y)
{ {
if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange if (platform.touchSlot < MAX_TOUCH_POINTS)
{
platform.touchPosition[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height;
// If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active.
// Only set to MOVE if we haven't already detected a DOWN or UP event this frame
if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
} }
if (event.code == ABS_MT_TRACKING_ID) if (event.code == ABS_MT_TRACKING_ID)
{ {
if ((event.value < 0) && (platform.touchSlot < MAX_TOUCH_POINTS)) if (platform.touchSlot < MAX_TOUCH_POINTS)
{ {
// Touch has ended for this point if (event.value >= 0)
CORE.Input.Touch.position[platform.touchSlot].x = -1; {
CORE.Input.Touch.position[platform.touchSlot].y = -1;
platform.touchActive[platform.touchSlot] = true;
platform.touchId[platform.touchSlot] = event.value; // Use Tracking ID for unique IDs
touchAction = 1; // TOUCH_ACTION_DOWN
}
else
{
// Touch has ended for this point
platform.touchActive[platform.touchSlot] = false;
platform.touchPosition[platform.touchSlot].x = -1;
platform.touchPosition[platform.touchSlot].y = -1;
platform.touchId[platform.touchSlot] = -1;
// Force UP action if we haven't already set a DOWN action
// (DOWN takes priority over UP if both happen in one frame, though rare)
if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP
}
}
}
// Handle ABS_MT_PRESSURE (0x3a) if available, as some devices use it for lift-off
#ifndef ABS_MT_PRESSURE
#define ABS_MT_PRESSURE 0x3a
#endif
if (event.code == ABS_MT_PRESSURE)
{
if (platform.touchSlot < MAX_TOUCH_POINTS)
{
if (event.value <= 0) // Pressure 0 means lift
{
platform.touchActive[platform.touchSlot] = false;
platform.touchPosition[platform.touchSlot].x = -1;
platform.touchPosition[platform.touchSlot].y = -1;
platform.touchId[platform.touchSlot] = -1;
if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP
}
} }
} }
@ -2319,16 +2456,15 @@ static void PollMouseEvents(void)
if (!event.value && previousMouseLeftButtonState) if (!event.value && previousMouseLeftButtonState)
{ {
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0; platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;
touchAction = 0; // TOUCH_ACTION_UP if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP
} }
if (event.value && !previousMouseLeftButtonState) if (event.value && !previousMouseLeftButtonState)
{ {
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1; platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;
touchAction = 1; // TOUCH_ACTION_DOWN touchAction = 1; // TOUCH_ACTION_DOWN
} }
} }
} }
// Button parsing // Button parsing
@ -2339,8 +2475,43 @@ static void PollMouseEvents(void)
{ {
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value; platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;
if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN if (event.value > 0)
else touchAction = 0; // TOUCH_ACTION_UP {
bool activateSlot0 = false;
if (event.code == BTN_LEFT) activateSlot0 = true; // Mouse click always activates
else if (event.code == BTN_TOUCH)
{
bool anyActive = false;
for (int i = 0; i < MAX_TOUCH_POINTS; i++)
{
if (platform.touchActive[i]) { anyActive = true; break; }
}
if (!anyActive) activateSlot0 = true;
}
if (activateSlot0)
{
platform.touchActive[0] = true;
platform.touchId[0] = 0;
}
touchAction = 1; // TOUCH_ACTION_DOWN
}
else
{
// Only clear touch 0 for actual mouse clicks (BTN_LEFT)
if (event.code == BTN_LEFT)
{
platform.touchActive[0] = false;
platform.touchPosition[0].x = -1;
platform.touchPosition[0].y = -1;
}
else if (event.code == BTN_TOUCH) platform.touchSlot = 0; // Reset slot index to 0
touchAction = 0; // TOUCH_ACTION_UP
}
} }
if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value; if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;
@ -2355,24 +2526,40 @@ static void PollMouseEvents(void)
if (!CORE.Input.Mouse.cursorLocked) if (!CORE.Input.Mouse.cursorLocked)
{ {
if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0; if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0;
if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x; if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x)
CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x;
if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0; if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0;
if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y)
CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y;
} }
// Update touch point count // Repack active touches into CORE.Input.Touch
CORE.Input.Touch.pointCount = 0; int k = 0;
for (int i = 0; i < MAX_TOUCH_POINTS; i++) for (int i = 0; i < MAX_TOUCH_POINTS; i++)
{ {
if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++; if (platform.touchActive[i])
{
CORE.Input.Touch.position[k] = platform.touchPosition[i];
CORE.Input.Touch.pointId[k] = platform.touchId[i];
k++;
}
}
CORE.Input.Touch.pointCount = k;
// Clear remaining slots
for (int i = k; i < MAX_TOUCH_POINTS; i++)
{
CORE.Input.Touch.position[i].x = -1;
CORE.Input.Touch.position[i].y = -1;
CORE.Input.Touch.pointId[i] = -1;
} }
#if defined(SUPPORT_GESTURES_SYSTEM) #if defined(SUPPORT_GESTURES_SYSTEM)
if (touchAction > -1) if (touchAction > -1)
{ {
GestureEvent gestureEvent = { 0 }; GestureEvent gestureEvent = { 0 };
gestureEvent.touchAction = touchAction; gestureEvent.touchAction = touchAction;
gestureEvent.pointCount = CORE.Input.Touch.pointCount; gestureEvent.pointCount = CORE.Input.Touch.pointCount;
@ -2383,7 +2570,6 @@ static void PollMouseEvents(void)
} }
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
touchAction = -1; touchAction = -1;
} }
#endif #endif
@ -2479,4 +2665,82 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
return nearestIndex; return nearestIndex;
} }
// EOF // Compute framebuffer size relative to screen size and display size
// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
static void SetupFramebuffer(int width, int height)
{
// Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var)
if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
// Downscaling to fit display with border-bars
float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width;
float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height;
if (widthRatio <= heightRatio)
{
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio);
CORE.Window.render.height = CORE.Window.display.height;
CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width);
CORE.Window.renderOffset.y = 0;
}
// Screen scaling required
float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width;
CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f);
// NOTE: We render to full display resolution!
// We just need to calculate above parameters for downscale matrix and offsets
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = CORE.Window.display.height;
TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height);
}
else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height))
{
// Required screen size is smaller than display size
TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{
CORE.Window.screen.width = CORE.Window.display.width;
CORE.Window.screen.height = CORE.Window.display.height;
}
// Upscaling to fit display with border-bars
float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height;
float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height;
if (displayRatio <= screenRatio)
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio);
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width);
CORE.Window.renderOffset.y = 0;
}
}
else
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = 0;
}
}
// EOF

View File

@ -13,9 +13,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -27,7 +24,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2025-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -428,7 +425,7 @@ void SetMouseCursor(int cursor)
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
} }
// Get physical key name. // Get physical key name
const char *GetKeyName(int key) const char *GetKeyName(int key)
{ {
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
@ -472,7 +469,7 @@ void PollInputEvents(void)
} }
// TODO: Poll input events for current platform // TODO: Poll input events for current platform
// Check for key pressed to exit // Check for key pressed to exit
if (kbhit()) if (kbhit())
{ {
@ -502,7 +499,7 @@ int InitPlatform(void)
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// If everything work as expected, we can continue // If everything worked as expected, continue
CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height; CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.width = CORE.Window.render.width;
@ -513,7 +510,7 @@ int InitPlatform(void)
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
CORE.Window.ready = true; CORE.Window.ready = true;
// TODO: Load OpenGL extensions // TODO: Load OpenGL extensions

View File

@ -27,7 +27,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -54,11 +54,6 @@
typedef struct { typedef struct {
// TODO: Define the platform specific variables required // TODO: Define the platform specific variables required
// Display data
EGLDisplay device; // Native display device (physical screen connection)
EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
EGLContext context; // Graphic context, mode in which drawing can be done
EGLConfig config; // Graphic config
} PlatformData; } PlatformData;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -346,10 +341,10 @@ void SwapScreenBuffer(void)
double GetTime(void) double GetTime(void)
{ {
double time = 0.0; double time = 0.0;
struct timespec ts = { 0 }; struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
return time; return time;
@ -366,7 +361,7 @@ void OpenURL(const char *url)
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
else else
{ {
// TODO: // TODO: Load url using default browser
} }
} }
@ -459,89 +454,20 @@ int InitPlatform(void)
// raylib uses OpenGL so, platform should create that kind of connection // raylib uses OpenGL so, platform should create that kind of connection
// Below example illustrates that process using EGL library // Below example illustrates that process using EGL library
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
EGLint samples = 0;
EGLint sampleBuffer = 0;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT))
{ {
samples = 4; // TODO: Enable MSAA
sampleBuffer = 1;
TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4"); TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4");
} }
const EGLint framebufferAttribs[] = // TODO: Init display and graphic device
{
EGL_RENDERABLE_TYPE, (rlGetVersion() == RL_OPENGL_ES_30)? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT, // Type of context support
EGL_RED_SIZE, 8, // RED color bit depth (alternative: 5)
EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6)
EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5)
//EGL_TRANSPARENT_TYPE, EGL_NONE, // Request transparent framebuffer (EGL_TRANSPARENT_RGB does not work on RPI)
EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!)
//EGL_STENCIL_SIZE, 8, // Stencil buffer size
EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA
EGL_SAMPLES, samples, // 4x Antialiasing if activated (Free on MALI GPUs)
EGL_NONE
};
const EGLint contextAttribs[] = // TODO: Check display, device and context activation
{ bool result = true;
EGL_CONTEXT_CLIENT_VERSION, 2, if (result)
EGL_NONE
};
EGLint numConfigs = 0;
// Get an EGL device connection
platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (platform.device == EGL_NO_DISPLAY)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
// Initialize the EGL device connection
if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)
{
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
// Get an appropriate EGL framebuffer configuration
eglChooseConfig(platform.device, framebufferAttribs, &platform.config, 1, &numConfigs);
// Set rendering API
eglBindAPI(EGL_OPENGL_ES_API);
// Create an EGL rendering context
platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs);
if (platform.context == EGL_NO_CONTEXT)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
return -1;
}
// Create an EGL window surface
EGLint displayFormat = 0;
// EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry()
// As soon as we picked a EGLConfig, we can safely reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID
eglGetConfigAttrib(platform.device, platform.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
// Android specific call
ANativeWindow_setBuffersGeometry(platform.app->window, 0, 0, displayFormat); // Force use of native display size
platform.surface = eglCreateWindowSurface(platform.device, platform.config, platform.app->window, NULL);
// There must be at least one frame displayed before the buffers are swapped
eglSwapInterval(platform.device, 1);
EGLBoolean result = eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context);
// Check surface and context activation
if (result != EGL_FALSE)
{ {
CORE.Window.ready = true; CORE.Window.ready = true;

View File

@ -12,9 +12,6 @@
* POSSIBLE IMPROVEMENTS: * POSSIBLE IMPROVEMENTS:
* - Replace glfw3 dependency by direct browser API calls (same as library_glfw3.js) * - Replace glfw3 dependency by direct browser API calls (same as library_glfw3.js)
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -26,7 +23,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -76,8 +73,13 @@ typedef struct {
bool ourFullscreen; // Internal var to filter our handling of fullscreen vs the user handling of fullscreen bool ourFullscreen; // Internal var to filter our handling of fullscreen vs the user handling of fullscreen
int unmaximizedWidth; // Internal var to store the unmaximized window (canvas) width int unmaximizedWidth; // Internal var to store the unmaximized window (canvas) width
int unmaximizedHeight; // Internal var to store the unmaximized window (canvas) height int unmaximizedHeight; // Internal var to store the unmaximized window (canvas) height
char canvasId[64]; // Keep current canvas id where wasm app is running char canvasId[64]; // Keep current canvas id where wasm app is running
// NOTE: Useful when trying to run multiple wasms in different canvases in same webpage
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
unsigned int *pixels; // Pointer to pixel data buffer (RGBA 32bit format)
#endif
} PlatformData; } PlatformData;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -199,7 +201,6 @@ void ToggleFullscreen(void)
EM_ASM(document.exitFullscreen();); EM_ASM(document.exitFullscreen(););
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
} }
@ -208,14 +209,12 @@ void ToggleFullscreen(void)
if (enterFullscreen) if (enterFullscreen)
{ {
// NOTE: The setTimeouts handle the browser mode change delay // NOTE: The setTimeouts handle the browser mode change delay
EM_ASM EM_ASM(
( setTimeout(function(){
setTimeout(function()
{
Module.requestFullscreen(false, false); Module.requestFullscreen(false, false);
}, 100); }, 100);
); );
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
@ -233,7 +232,7 @@ void ToggleFullscreen(void)
*/ */
// EM_ASM(Module.requestFullscreen(false, false);); // EM_ASM(Module.requestFullscreen(false, false););
/* /*
if (!CORE.Window.fullscreen) if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// Option 1: Request fullscreen for the canvas element // Option 1: Request fullscreen for the canvas element
// This option does not seem to work at all: // This option does not seem to work at all:
@ -264,11 +263,11 @@ void ToggleFullscreen(void)
}; };
emscripten_enter_soft_fullscreen(platform.canvasId, &strategy); emscripten_enter_soft_fullscreen(platform.canvasId, &strategy);
int width, height; int width = 0;
int height = 0;
emscripten_get_canvas_element_size(platform.canvasId, &width, &height); emscripten_get_canvas_element_size(platform.canvasId, &width, &height);
TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height); TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height);
CORE.Window.fullscreen = true; // Toggle fullscreen flag
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
else else
@ -280,7 +279,6 @@ void ToggleFullscreen(void)
emscripten_get_canvas_element_size(platform.canvasId, &width, &height); emscripten_get_canvas_element_size(platform.canvasId, &width, &height);
TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height); TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height);
CORE.Window.fullscreen = false; // Toggle fullscreen flag
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
*/ */
@ -307,7 +305,6 @@ void ToggleBorderlessWindowed(void)
EM_ASM(document.exitFullscreen();); EM_ASM(document.exitFullscreen(););
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
} }
@ -319,15 +316,16 @@ void ToggleBorderlessWindowed(void)
// 2. The style unset handles the possibility of a width="value%" like on the default shell.html file // 2. The style unset handles the possibility of a width="value%" like on the default shell.html file
EM_ASM EM_ASM
( (
const canvasId = UTF8ToString($0);
setTimeout(function() setTimeout(function()
{ {
Module.requestFullscreen(false, true); Module.requestFullscreen(false, true);
setTimeout(function() setTimeout(function()
{ {
canvas.style.width="unset"; document.querySelector(canvasId).style.width="unset";
}, 100); }, 100);
}, 100); }, 100);
); , platform.canvasId);
FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
} }
} }
@ -539,7 +537,6 @@ void ClearWindowState(unsigned int flags)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen();); if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen(););
} }
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
@ -883,7 +880,32 @@ void DisableCursor(void)
// Swap back buffer with front buffer (screen drawing) // Swap back buffer with front buffer (screen drawing)
void SwapScreenBuffer(void) void SwapScreenBuffer(void)
{ {
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
// Update framebuffer
rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, platform.pixels);
// Copy framebuffer data into canvas
EM_ASM({
const width = $0;
const height = $1;
const ptr = $2;
// Get canvas and 2d context created
const canvas = Module.canvas;
const ctx = canvas.getContext('2d');
if (!Module.__img || (Module.__img.width !== width) || (Module.__img.height !== height)) {
Module.__img = ctx.createImageData(width, height);
}
const src = HEAPU8.subarray(ptr, ptr + width*height*4); // RGBA (4 bytes)
Module.__img.data.set(src);
ctx.putImageData(Module.__img, 0, 0);
}, CORE.Window.screen.width, CORE.Window.screen.height, platform.pixels);
#else
glfwSwapBuffers(platform.handle); glfwSwapBuffers(platform.handle);
#endif
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -932,8 +954,8 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d
if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME; if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME;
duration *= 1000.0f; // Convert duration to ms duration *= 1000.0f; // Convert duration to ms
// Note: At the moment (2024.10.21) Chrome, Edge, Opera, Safari, Android Chrome, Android Webview only support the vibrationActuator API, // NOTE: At the moment (2024.10.21) Chrome, Edge, Opera, Safari, Android Chrome, Android Webview only support the vibrationActuator API,
// and Firefox only supports the hapticActuators API // and Firefox only supports the hapticActuators API
EM_ASM({ EM_ASM({
try try
{ {
@ -974,7 +996,7 @@ void SetMouseCursor(int cursor)
} }
} }
// Get physical key name. // Get physical key name
const char *GetKeyName(int key) const char *GetKeyName(int key)
{ {
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
@ -1080,7 +1102,7 @@ void PollInputEvents(void)
else CORE.Input.Gamepad.currentButtonState[i][button] = 0; else CORE.Input.Gamepad.currentButtonState[i][button] = 0;
} }
//TRACELOGD("INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); //TRACELOG(LOG_DEBUG, "INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]);
} }
// Register axis data for every connected gamepad // Register axis data for every connected gamepad
@ -1104,7 +1126,7 @@ void PollInputEvents(void)
int InitPlatform(void) int InitPlatform(void)
{ {
SetCanvasIdJs(platform.canvasId, 64); // Get the current canvas id SetCanvasIdJs(platform.canvasId, 64); // Get the current canvas id
glfwSetErrorCallback(ErrorCallback); glfwSetErrorCallback(ErrorCallback);
// Initialize GLFW internal global state // Initialize GLFW internal global state
@ -1124,8 +1146,6 @@ int InitPlatform(void)
// glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers // glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
// Check window creation flags // Check window creation flags
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window
else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden
@ -1178,8 +1198,8 @@ int InitPlatform(void)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
// Profiles Hint, only OpenGL 3.3 and above // Profiles Hint, only OpenGL 3.3 and above
// Possible values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE // Possible values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); // Forward Compatibility Hint: Only 3.3 and above! glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); // Forward Compatibility Hint: Only 3.3 and above!
// glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context // glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context
} }
@ -1215,7 +1235,21 @@ int InitPlatform(void)
// Init fullscreen toggle required var: // Init fullscreen toggle required var:
platform.ourFullscreen = false; platform.ourFullscreen = false;
if (CORE.Window.fullscreen) #if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
// Avoid creating a WebGL canvas, avoid calling glfwCreateWindow()
emscripten_set_canvas_element_size(platform.canvasId, CORE.Window.screen.width, CORE.Window.screen.height);
EM_ASM({
const canvas = document.querySelector(UTF8ToString($0));
Module.canvas = canvas;
}, platform.canvasId);
// Load memory framebuffer with desired screen size
// NOTE: Despite using a software framebuffer for blitting, GLFW still creates a WebGL canvas,
// but it is not being used, on SwapScreenBuffer() the pure software renderer is used
// TODO: Consider requesting another type of canvas, not a WebGL one --> Replace GLFW-web by Emscripten?
platform.pixels = (unsigned int *)RL_CALLOC(CORE.Window.screen.width*CORE.Window.screen.height, sizeof(unsigned int));
#else
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// remember center for switchinging from fullscreen to window // remember center for switchinging from fullscreen to window
if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width)) if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width))
@ -1254,18 +1288,6 @@ int InitPlatform(void)
TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height); TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
// framebuffer is rendered correctly but once displayed on a 16:9 monitor, it gets stretched
// by the sides to fit all monitor space...
// Try to setup the most appropriate fullscreen framebuffer for the requested screenWidth/screenHeight
// It considers device display resolution mode and setups a framebuffer with black bars if required (render size/offset)
// Modified global variables: CORE.Window.screen.width/CORE.Window.screen.height - CORE.Window.render.width/CORE.Window.render.height - CORE.Window.renderOffset.x/CORE.Window.renderOffset.y - CORE.Window.screenScale
// TODO: It is a quite cumbersome solution to display size vs requested size, it should be reviewed or removed...
// HighDPI monitors are properly considered in a following similar function: SetupViewport()
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL); platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL);
// NOTE: Full-screen change, not working properly... // NOTE: Full-screen change, not working properly...
@ -1289,6 +1311,7 @@ int InitPlatform(void)
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window"); TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
return -1; return -1;
} }
#endif
// WARNING: glfwCreateWindow() title doesn't work with emscripten // WARNING: glfwCreateWindow() title doesn't work with emscripten
emscripten_set_window_title((CORE.Window.title != 0)? CORE.Window.title : " "); emscripten_set_window_title((CORE.Window.title != 0)? CORE.Window.title : " ");
@ -1485,7 +1508,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{ {
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strcpy(CORE.Window.dropFilepaths[i], paths[i]); strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
} }
} }
} }
@ -1670,12 +1693,12 @@ static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPoin
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
{ {
/* /*
TRACELOGD("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", TRACELOG(LOG_DEBUG, "%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"",
eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state", eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state",
gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping);
for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOGD("Axis %d: %g", i, gamepadEvent->axis[i]); for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOG(LOG_DEBUG, "Axis %d: %g", i, gamepadEvent->axis[i]);
for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOG(LOG_DEBUG, "Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
*/ */
if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS)) if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS))
@ -1776,15 +1799,14 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
// Emscripten: Called on fullscreen change events // Emscripten: Called on fullscreen change events
static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData) static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData)
{ {
// NOTE: 1. Reset the fullscreen flags if the user left fullscreen manually by pressing the Escape key // NOTE 1: Reset the fullscreen flags if the user left fullscreen manually by pressing the Escape key
// 2. Which is a necessary safeguard because that case will bypass the toggles CORE.Window.flags resets // NOTE 2: Which is a necessary safeguard because that case will bypass the toggles CORE.Window.flags resets
if (platform.ourFullscreen) platform.ourFullscreen = false; if (platform.ourFullscreen) platform.ourFullscreen = false;
else else
{ {
const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0);
if (!wasFullscreen) if (!wasFullscreen)
{ {
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
} }

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -74,11 +74,7 @@
#else #else
#include "raylib.h" // Declares module functions #include "raylib.h" // Declares module functions
// Check if config flags have been externally provided on compilation line #include "config.h" // Defines module configuration flags
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags
#endif
#include "utils.h" // Required for: fopen() Android mapping
#endif #endif
#if defined(SUPPORT_MODULE_RAUDIO) || defined(RAUDIO_STANDALONE) #if defined(SUPPORT_MODULE_RAUDIO) || defined(RAUDIO_STANDALONE)
@ -1134,7 +1130,7 @@ bool ExportWaveAsCode(Wave wave, const char *fileName)
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n"); byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n");
@ -1249,7 +1245,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate); frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate);
if (frameCount == 0) if (frameCount == 0)
{ {
RL_FREE(wave->data); RL_FREE(data);
TRACELOG(LOG_WARNING, "WAVE: Failed format conversion"); TRACELOG(LOG_WARNING, "WAVE: Failed format conversion");
return; return;
} }
@ -2422,7 +2418,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead)%audioBuffer->sizeInFrames; audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead)%audioBuffer->sizeInFrames;
framesRead += framesToRead; framesRead += framesToRead;
// If we've read to the end of the buffer, mark it as processed // If the end of the buffer is read, mark it as processed
if (framesToRead == framesRemainingInOutputBuffer) if (framesToRead == framesRemainingInOutputBuffer)
{ {
audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true; audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true;
@ -2430,7 +2426,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
currentSubBufferIndex = (currentSubBufferIndex + 1)%2; currentSubBufferIndex = (currentSubBufferIndex + 1)%2;
// We need to break from this loop if we're not looping // Break from this loop if looping not enabled
if (!audioBuffer->looping) if (!audioBuffer->looping)
{ {
StopAudioBufferInLockedState(audioBuffer); StopAudioBufferInLockedState(audioBuffer);
@ -2457,10 +2453,12 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
// Reads audio data from an AudioBuffer object in device format, returned data will be in a format appropriate for mixing // Reads audio data from an AudioBuffer object in device format, returned data will be in a format appropriate for mixing
static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount) static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount)
{ {
// What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which // NOTE: Continuously converting data from the AudioBuffer's internal format to the mixing format,
// should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important // which should be defined by the output format of the data converter.
// detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output // This is done until frameCount frames have been output.
// frames. This can be achieved with ma_data_converter_get_required_input_frame_count() // The important detail to remember is that more data than required should neeveer be read,
// for the specified number of output frames.
// This can be achieved with ma_data_converter_get_required_input_frame_count()
ma_uint8 inputBuffer[4096] = { 0 }; ma_uint8 inputBuffer[4096] = { 0 };
ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn); ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
@ -2577,8 +2575,8 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
} }
} }
// If for some reason we weren't able to read every frame we'll need to break from the loop // If for some reason is not possible to read every frame, the loop needs to be broken
// Not doing this could theoretically put us into an infinite loop // Not doing this could theoretically eend up into an infinite loop
if (framesToRead > 0) break; if (framesToRead > 0) break;
} }
} }
@ -2743,9 +2741,9 @@ static const char *GetFileExtension(const char *fileName)
static const char *strprbrk(const char *text, const char *charset) static const char *strprbrk(const char *text, const char *charset)
{ {
const char *latestMatch = NULL; const char *latestMatch = NULL;
for (; (text != NULL) && (text = strpbrk(text, charset)); latestMatch = text++) { } for (; (text != NULL) && (text = strpbrk(text, charset)); latestMatch = text++) { }
return latestMatch; return latestMatch;
} }

Some files were not shown because too many files have changed in this diff Show More