mirror of
https://github.com/raysan5/raylib.git
synced 2025-12-25 10:22:33 -05:00
Compare commits
23 Commits
7553e9d586
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 101502103a | |||
| 20dd4641c8 | |||
| fc843dc557 | |||
| 9103f6e055 | |||
| ced84333a9 | |||
| 05f42aa119 | |||
| a1e84caa8c | |||
| ddb827fb6f | |||
| 0a4583ca54 | |||
| 6a701b2679 | |||
| aa2884bd78 | |||
| f27f2d097f | |||
| e4baf682ab | |||
| 8516750975 | |||
| 3212becc91 | |||
| b9446863d7 | |||
| 13f9112d8c | |||
| f16fb065ea | |||
| 66392fe0ae | |||
| 720dd22491 | |||
| ca578b8b08 | |||
| 4b760091da | |||
| 6d562e5e87 |
@ -76,6 +76,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 |
|
||||||
|
|||||||
18
SECURITY.md
Normal file
18
SECURITY.md
Normal 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._
|
||||||
@ -531,7 +531,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 \
|
||||||
|
|||||||
@ -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 \
|
||||||
@ -783,7 +783,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
|
||||||
|
|||||||
@ -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) |
|
||||||
|
|||||||
@ -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;
|
||||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@ -27,9 +27,13 @@ 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();
|
||||||
|
|
||||||
int gridSpacing = 40; // Grid spacing in pixels
|
int gridSpacing = 40; // Grid spacing in pixels
|
||||||
|
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
@ -40,7 +44,11 @@ int main(void)
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// TODO: Update variables / Implement example logic at this point
|
mousePos = GetMousePosition();
|
||||||
|
currentMonitor = GetCurrentMonitor();
|
||||||
|
scaleDpi = GetWindowScaleDPI();
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -50,11 +58,30 @@ 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 < 20; 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 < 40; 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("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 90, 20, DARKGRAY);
|
||||||
|
DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 130, 20, DARKGRAY);
|
||||||
|
DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 170, 20, GRAY);
|
||||||
|
|
||||||
|
// 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();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -43,7 +43,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
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||||
@ -5543,7 +5543,7 @@ Global
|
|||||||
{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} = {278D8859-20B1-428F-8448-064F46E1F021}
|
||||||
{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 +5559,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}
|
||||||
|
|||||||
8
src/external/rl_gputex.h
vendored
8
src/external/rl_gputex.h
vendored
@ -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];
|
||||||
|
|||||||
@ -360,7 +360,7 @@ void SetWindowState(unsigned int flags)
|
|||||||
if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead");
|
if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead");
|
||||||
|
|
||||||
// State change: FLAG_WINDOW_ALWAYS_RUN
|
// State change: FLAG_WINDOW_ALWAYS_RUN
|
||||||
if (!FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) FLAG_SET(CORE.Window.flags, 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
|
||||||
|
|||||||
@ -134,12 +134,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 +156,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
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -205,7 +204,6 @@ void ToggleFullscreen(void)
|
|||||||
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
@ -231,22 +229,22 @@ void ToggleBorderlessWindowed(void)
|
|||||||
bool wasOnFullscreen = false;
|
bool wasOnFullscreen = false;
|
||||||
if (CORE.Window.fullscreen)
|
if (CORE.Window.fullscreen)
|
||||||
{
|
{
|
||||||
// fullscreen already saves the previous position so it does not need to be set here again
|
// Fullscreen already saves the previous position so it does not need to be set here again
|
||||||
ToggleFullscreen();
|
ToggleFullscreen();
|
||||||
wasOnFullscreen = true;
|
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
|
||||||
@ -286,6 +284,16 @@ void ToggleBorderlessWindowed(void)
|
|||||||
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);
|
||||||
|
|
||||||
|
#if !defined(__APPLE__)
|
||||||
|
// Make sure to restore size to HighDPI
|
||||||
|
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
|
||||||
|
{
|
||||||
|
Vector2 scaleDpi = GetWindowScaleDPI();
|
||||||
|
CORE.Window.previousScreen.width *= scaleDpi.x;
|
||||||
|
CORE.Window.previousScreen.height *= scaleDpi.y;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Return previous screen size and position
|
// Return previous screen size and position
|
||||||
// NOTE: The order matters here, it must set size first, then set position, otherwise the screen will be positioned incorrectly
|
// NOTE: The order matters here, it must set size first, then set position, otherwise the screen will be positioned incorrectly
|
||||||
glfwSetWindowMonitor(
|
glfwSetWindowMonitor(
|
||||||
@ -475,13 +483,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
|
||||||
@ -1016,8 +1024,8 @@ Vector2 GetWindowPosition(void)
|
|||||||
// 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)) glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y);
|
||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1329,7 +1337,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();
|
||||||
@ -1434,31 +1443,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);
|
||||||
@ -1528,17 +1533,24 @@ int InitPlatform(void)
|
|||||||
GLFWmonitor *monitor = NULL;
|
GLFWmonitor *monitor = NULL;
|
||||||
if (CORE.Window.fullscreen)
|
if (CORE.Window.fullscreen)
|
||||||
{
|
{
|
||||||
// According to glfwCreateWindow(), if the user does not have a choice, fullscreen applications
|
// NOTE: Fullscreen applications default to the primary monitor
|
||||||
// should default to the primary monitor
|
|
||||||
|
|
||||||
monitor = glfwGetPrimaryMonitor();
|
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);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
// Remember center for switching from fullscreen to window
|
// Remember center for switching 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))
|
||||||
@ -1627,7 +1639,15 @@ int InitPlatform(void)
|
|||||||
if (monitorIndex < monitorCount)
|
if (monitorIndex < monitorCount)
|
||||||
{
|
{
|
||||||
monitor = monitors[monitorIndex];
|
monitor = monitors[monitorIndex];
|
||||||
SetDimensionsFromMonitor(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;
|
||||||
|
|
||||||
if (requestWindowedFullscreen) glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
|
if (requestWindowedFullscreen) glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
|
||||||
}
|
}
|
||||||
@ -1639,6 +1659,7 @@ 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;
|
||||||
}
|
}
|
||||||
@ -1669,16 +1690,15 @@ 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__)
|
|
||||||
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;
|
||||||
@ -1735,28 +1755,24 @@ 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++)
|
||||||
@ -1814,79 +1830,116 @@ 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)
|
||||||
{
|
{
|
||||||
|
// Nothing to do for now on window resize...
|
||||||
|
//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,
|
// WARNING: On window minimization, callback is called,
|
||||||
// but we don't want to change internal screen values, it breaks things
|
// but we don't want to change internal screen values, 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;
|
// Check if render size was actually scaled for high-dpi
|
||||||
|
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
|
||||||
// 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);
|
// Set screen size to logical pixel size, considering content scaling
|
||||||
height = (int)(height/GetWindowScaleDPI().y);
|
Vector2 scaleDpi = GetWindowScaleDPI();
|
||||||
|
CORE.Window.screen.width = (int)((float)width/scaleDpi.x);
|
||||||
|
CORE.Window.screen.height = (int)((float)height/scaleDpi.y);
|
||||||
|
}
|
||||||
|
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((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CORE.Window.render.width = (int)fbWidth;
|
||||||
|
CORE.Window.render.height = (int)fbHeight;
|
||||||
|
CORE.Window.currentFbo.width = (int)fbWidth;
|
||||||
|
CORE.Window.currentFbo.height = (int)fbHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
@ -1909,12 +1962,12 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@ -1941,7 +1994,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
|
||||||
@ -1958,7 +2011,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,
|
||||||
@ -1994,7 +2047,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;
|
||||||
@ -2025,20 +2078,20 @@ 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)
|
||||||
@ -2054,20 +2107,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"
|
||||||
|
|||||||
@ -522,46 +522,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
|
||||||
@ -578,12 +547,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -679,6 +679,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");
|
||||||
@ -1430,9 +1431,9 @@ void PollInputEvents(void)
|
|||||||
// 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
|
||||||
|
|
||||||
@ -1443,9 +1444,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
|
||||||
|
|
||||||
@ -1474,7 +1475,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);
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,86 +457,18 @@ int InitPlatform(void)
|
|||||||
CORE.Window.fullscreen = true;
|
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;
|
||||||
|
|
||||||
|
|||||||
@ -1531,7 +1531,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1701
src/platforms/rcore_web_emscripten.c
Normal file
1701
src/platforms/rcore_web_emscripten.c
Normal file
File diff suppressed because it is too large
Load Diff
35
src/rcore.c
35
src/rcore.c
@ -273,7 +273,7 @@
|
|||||||
#define FLAG_SET(n, f) ((n) |= (f))
|
#define FLAG_SET(n, f) ((n) |= (f))
|
||||||
#define FLAG_CLEAR(n, f) ((n) &= ~(f))
|
#define FLAG_CLEAR(n, f) ((n) &= ~(f))
|
||||||
#define FLAG_TOGGLE(n, f) ((n) ^= (f))
|
#define FLAG_TOGGLE(n, f) ((n) ^= (f))
|
||||||
#define FLAG_IS_SET(n, f) (((n) & (f)) > 0)
|
#define FLAG_IS_SET(n, f) (((n) & (f)) == (f))
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
@ -816,30 +816,22 @@ int GetScreenHeight(void)
|
|||||||
// Get current render width which is equal to screen width*dpi scale
|
// Get current render width which is equal to screen width*dpi scale
|
||||||
int GetRenderWidth(void)
|
int GetRenderWidth(void)
|
||||||
{
|
{
|
||||||
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.width;
|
|
||||||
|
|
||||||
int width = 0;
|
int width = 0;
|
||||||
#if defined(__APPLE__)
|
|
||||||
Vector2 scale = GetWindowScaleDPI();
|
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.width;
|
||||||
width = (int)((float)CORE.Window.render.width*scale.x);
|
else width = CORE.Window.render.width;
|
||||||
#else
|
|
||||||
width = CORE.Window.render.width;
|
|
||||||
#endif
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current screen height which is equal to screen height*dpi scale
|
// Get current screen height which is equal to screen height*dpi scale
|
||||||
int GetRenderHeight(void)
|
int GetRenderHeight(void)
|
||||||
{
|
{
|
||||||
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.height;
|
|
||||||
|
|
||||||
int height = 0;
|
int height = 0;
|
||||||
#if defined(__APPLE__)
|
|
||||||
Vector2 scale = GetWindowScaleDPI();
|
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.height;
|
||||||
height = (int)((float)CORE.Window.render.height*scale.y);
|
else height = CORE.Window.render.height;
|
||||||
#else
|
|
||||||
height = CORE.Window.render.height;
|
|
||||||
#endif
|
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1833,7 +1825,7 @@ void TakeScreenshot(const char *fileName)
|
|||||||
|
|
||||||
// Apply a scale if we are doing HIGHDPI auto-scaling
|
// Apply a scale if we are doing HIGHDPI auto-scaling
|
||||||
Vector2 scale = { 1.0f, 1.0f };
|
Vector2 scale = { 1.0f, 1.0f };
|
||||||
if (IsWindowState(FLAG_WINDOW_HIGHDPI)) scale = GetWindowScaleDPI();
|
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) scale = GetWindowScaleDPI();
|
||||||
|
|
||||||
unsigned char *imgData = rlReadScreenPixels((int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y));
|
unsigned char *imgData = rlReadScreenPixels((int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y));
|
||||||
Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
||||||
@ -3823,14 +3815,7 @@ void SetupViewport(int width, int height)
|
|||||||
CORE.Window.render.height = height;
|
CORE.Window.render.height = height;
|
||||||
|
|
||||||
// Set viewport width and height
|
// Set viewport width and height
|
||||||
// NOTE: We consider render size (scaled) and offset in case black bars are required and
|
|
||||||
// render area does not match full display area (this situation is only applicable on fullscreen mode)
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
Vector2 scale = GetWindowScaleDPI();
|
|
||||||
rlViewport(CORE.Window.renderOffset.x/2*scale.x, CORE.Window.renderOffset.y/2*scale.y, (CORE.Window.render.width)*scale.x, (CORE.Window.render.height)*scale.y);
|
|
||||||
#else
|
|
||||||
rlViewport(CORE.Window.renderOffset.x/2, CORE.Window.renderOffset.y/2, CORE.Window.render.width, CORE.Window.render.height);
|
rlViewport(CORE.Window.renderOffset.x/2, CORE.Window.renderOffset.y/2, CORE.Window.render.width, CORE.Window.render.height);
|
||||||
#endif
|
|
||||||
|
|
||||||
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||||
rlLoadIdentity(); // Reset current matrix (projection)
|
rlLoadIdentity(); // Reset current matrix (projection)
|
||||||
|
|||||||
46
src/rlgl.h
46
src/rlgl.h
@ -3353,8 +3353,8 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
|
|||||||
|
|
||||||
mipWidth /= 2;
|
mipWidth /= 2;
|
||||||
mipHeight /= 2;
|
mipHeight /= 2;
|
||||||
mipOffset += mipSize; // Increment offset position to next mipmap
|
mipOffset += mipSize; // Increment offset position to next mipmap
|
||||||
if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap
|
if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap
|
||||||
|
|
||||||
// Security check for NPOT textures
|
// Security check for NPOT textures
|
||||||
if (mipWidth < 1) mipWidth = 1;
|
if (mipWidth < 1) mipWidth = 1;
|
||||||
@ -3392,8 +3392,14 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
|
||||||
// Define thee maximum number of mipmap levels to be used, 0 is default texture size
|
// Define the maximum number of mipmap levels to be used, 0 is base texture size
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapCount - 1);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapCount - 1);
|
||||||
|
|
||||||
|
// Check if the loaded texture with mipmaps is complete,
|
||||||
|
// uncomplete textures will draw in black if mipmap filtering is required
|
||||||
|
//GLint complete = 0;
|
||||||
|
//glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_FORMAT, &complete);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -5218,24 +5224,36 @@ static int rlGetPixelDataSize(int width, int height, int format)
|
|||||||
case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB:
|
case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB:
|
||||||
case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB:
|
case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB:
|
||||||
case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB:
|
case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB:
|
||||||
case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
|
case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 8 bytes per each 4x4 block
|
||||||
|
{
|
||||||
|
int blockWidth = (width + 3)/4;
|
||||||
|
int blockHeight = (height + 3)/4;
|
||||||
|
dataSize = blockWidth*blockHeight*8;
|
||||||
|
} break;
|
||||||
case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA:
|
case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA:
|
||||||
case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA:
|
case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA:
|
||||||
case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
|
case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
|
||||||
case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
|
case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 16 bytes per each 4x4 block
|
||||||
case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
|
{
|
||||||
|
int blockWidth = (width + 3)/4;
|
||||||
|
int blockHeight = (height + 3)/4;
|
||||||
|
dataSize = blockWidth*blockHeight*16;
|
||||||
|
} break;
|
||||||
|
case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 4 bytes per each 4x4 block
|
||||||
|
{
|
||||||
|
int blockWidth = (width + 3)/4;
|
||||||
|
int blockHeight = (height + 3)/4;
|
||||||
|
dataSize = blockWidth*blockHeight*4;
|
||||||
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
double bytesPerPixel = (double)bpp/8.0;
|
// Compute dataSize for uncompressed texture data (no blocks)
|
||||||
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
|
if ((format >= RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) &&
|
||||||
|
(format <= RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16))
|
||||||
// Most compressed formats works on 4x4 blocks,
|
|
||||||
// if texture is smaller, minimum dataSize is 8 or 16
|
|
||||||
if ((width < 4) && (height < 4))
|
|
||||||
{
|
{
|
||||||
if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8;
|
double bytesPerPixel = (double)bpp/8.0;
|
||||||
else if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16;
|
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataSize;
|
return dataSize;
|
||||||
|
|||||||
25
src/rtext.c
25
src/rtext.c
@ -700,7 +700,11 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case FONT_DEFAULT:
|
case FONT_DEFAULT:
|
||||||
case FONT_BITMAP: glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp, &cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY); break;
|
case FONT_BITMAP:
|
||||||
|
{
|
||||||
|
glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp,
|
||||||
|
&cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY);
|
||||||
|
} break;
|
||||||
case FONT_SDF:
|
case FONT_SDF:
|
||||||
{
|
{
|
||||||
if (cp != 32)
|
if (cp != 32)
|
||||||
@ -1593,14 +1597,13 @@ float TextToFloat(const char *text)
|
|||||||
|
|
||||||
#if defined(SUPPORT_TEXT_MANIPULATION)
|
#if defined(SUPPORT_TEXT_MANIPULATION)
|
||||||
// Copy one string to another, returns bytes copied
|
// Copy one string to another, returns bytes copied
|
||||||
|
// NOTE: Alternative implementation to strcpy(dst, src) from C standard library
|
||||||
int TextCopy(char *dst, const char *src)
|
int TextCopy(char *dst, const char *src)
|
||||||
{
|
{
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
|
|
||||||
if ((src != NULL) && (dst != NULL))
|
if ((src != NULL) && (dst != NULL))
|
||||||
{
|
{
|
||||||
// NOTE: Alternative: use strcpy(dst, src)
|
|
||||||
|
|
||||||
while (*src != '\0')
|
while (*src != '\0')
|
||||||
{
|
{
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
@ -1713,11 +1716,13 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
|
|||||||
{
|
{
|
||||||
char *insertPoint = NULL; // Next insert point
|
char *insertPoint = NULL; // Next insert point
|
||||||
char *temp = NULL; // Temp pointer
|
char *temp = NULL; // Temp pointer
|
||||||
|
int textLen = 0; // Text string length
|
||||||
int searchLen = 0; // Search string length of (the string to remove)
|
int searchLen = 0; // Search string length of (the string to remove)
|
||||||
int replaceLen = 0; // Replacement length (the string to replace by)
|
int replaceLen = 0; // Replacement length (the string to replace by)
|
||||||
int lastReplacePos = 0; // Distance between next search and end of last replace
|
int lastReplacePos = 0; // Distance between next search and end of last replace
|
||||||
int count = 0; // Number of replacements
|
int count = 0; // Number of replacements
|
||||||
|
|
||||||
|
textLen = TextLength(text);
|
||||||
searchLen = TextLength(search);
|
searchLen = TextLength(search);
|
||||||
if (searchLen == 0) return NULL; // Empty search causes infinite loop during count
|
if (searchLen == 0) return NULL; // Empty search causes infinite loop during count
|
||||||
|
|
||||||
@ -1728,7 +1733,8 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
|
|||||||
for (count = 0; (temp = strstr(insertPoint, search)); count++) insertPoint = temp + searchLen;
|
for (count = 0; (temp = strstr(insertPoint, search)); count++) insertPoint = temp + searchLen;
|
||||||
|
|
||||||
// Allocate returning string and point temp to it
|
// Allocate returning string and point temp to it
|
||||||
temp = result = (char *)RL_MALLOC(TextLength(text) + (replaceLen - searchLen)*count + 1);
|
int tempLen = textLen + (replaceLen - searchLen)*count + 1;
|
||||||
|
temp = result = (char *)RL_MALLOC(tempLen);
|
||||||
|
|
||||||
if (!result) return NULL; // Memory could not be allocated
|
if (!result) return NULL; // Memory could not be allocated
|
||||||
|
|
||||||
@ -1740,13 +1746,16 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
|
|||||||
{
|
{
|
||||||
insertPoint = (char *)strstr(text, search);
|
insertPoint = (char *)strstr(text, search);
|
||||||
lastReplacePos = (int)(insertPoint - text);
|
lastReplacePos = (int)(insertPoint - text);
|
||||||
temp = strncpy(temp, text, lastReplacePos) + lastReplacePos;
|
temp = strncpy(temp, text, tempLen - 1) + lastReplacePos;
|
||||||
temp = strcpy(temp, replacement) + replaceLen;
|
tempLen -= lastReplacePos;
|
||||||
|
temp = strncpy(temp, replacement, tempLen - 1) + replaceLen;
|
||||||
|
tempLen -= replaceLen;
|
||||||
|
|
||||||
text += lastReplacePos + searchLen; // Move to next "end of replace"
|
text += lastReplacePos + searchLen; // Move to next "end of replace"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy remaind text part after replacement to result (pointed by moving temp)
|
// Copy remaind text part after replacement to result (pointed by moving temp)
|
||||||
strcpy(temp, text);
|
strncpy(temp, text, tempLen - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -2086,7 +2095,7 @@ int *LoadCodepoints(const char *text, int *count)
|
|||||||
int textLength = TextLength(text);
|
int textLength = TextLength(text);
|
||||||
|
|
||||||
// Allocate a big enough buffer to store as many codepoints as text bytes
|
// Allocate a big enough buffer to store as many codepoints as text bytes
|
||||||
int *codepoints = (int *)RL_CALLOC(textLength, sizeof(int));
|
codepoints = (int *)RL_CALLOC(textLength, sizeof(int));
|
||||||
|
|
||||||
int codepointSize = 0;
|
int codepointSize = 0;
|
||||||
for (int i = 0; i < textLength; codepointCount++)
|
for (int i = 0; i < textLength; codepointCount++)
|
||||||
|
|||||||
Reference in New Issue
Block a user