mirror of
https://github.com/raysan5/raylib.git
synced 2025-12-25 10:22:33 -05:00
Compare commits
34 Commits
8d246fdaff
...
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 | |||
| 7553e9d586 | |||
| 80ad96acc2 | |||
| 7a5e8aa3a5 | |||
| 1c94e94873 | |||
| 33adda1983 | |||
| f031b2f4f4 | |||
| 1c7240a01d | |||
| cf0d6fc664 | |||
| 615fc36eeb | |||
| cbe31759ab | |||
| d74556d35c |
4
.gitignore
vendored
4
.gitignore
vendored
@ -58,6 +58,10 @@ packages/
|
||||
*.h.pch
|
||||
./*.obj
|
||||
|
||||
# Ignore SDL libs for testing
|
||||
src/external/SDL2
|
||||
src/external/SDL3
|
||||
|
||||
# Emscripten
|
||||
emsdk
|
||||
|
||||
|
||||
@ -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-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) | **???** |
|
||||
| [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 |
|
||||
| [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 |
|
||||
|
||||
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._
|
||||
@ -106,9 +106,9 @@ const config_h_flags = outer: {
|
||||
if (std.mem.startsWith(u8, line, "//")) 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 = 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 = "-D" ++ flag; // Prepend with -D
|
||||
|
||||
@ -193,7 +193,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
|
||||
// No GLFW required on 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);
|
||||
@ -224,7 +224,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
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) {
|
||||
.windows => {
|
||||
switch (options.platform) {
|
||||
|
||||
@ -531,7 +531,7 @@ CORE = \
|
||||
core/core_delta_time \
|
||||
core/core_directory_files \
|
||||
core/core_drop_files \
|
||||
core/core_high_dpi \
|
||||
core/core_highdpi_demo \
|
||||
core/core_highdpi_testbed \
|
||||
core/core_input_actions \
|
||||
core/core_input_gamepad \
|
||||
|
||||
@ -519,7 +519,7 @@ CORE = \
|
||||
core/core_delta_time \
|
||||
core/core_directory_files \
|
||||
core/core_drop_files \
|
||||
core/core_high_dpi \
|
||||
core/core_highdpi_demo \
|
||||
core/core_highdpi_testbed \
|
||||
core/core_input_actions \
|
||||
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
|
||||
$(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)
|
||||
|
||||
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_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_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_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) |
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - high dpi
|
||||
* raylib [core] example - highdpi demo
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
@ -33,7 +33,7 @@ int main(void)
|
||||
const int screenHeight = 450;
|
||||
|
||||
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);
|
||||
|
||||
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 screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
|
||||
|
||||
Vector2 scaleDpi = GetWindowScaleDPI();
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
int currentMonitor = GetCurrentMonitor();
|
||||
|
||||
int gridSpacing = 40; // Grid spacing in pixels
|
||||
|
||||
SetTargetFPS(60);
|
||||
@ -40,7 +44,11 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update variables / Implement example logic at this point
|
||||
mousePos = GetMousePosition();
|
||||
currentMonitor = GetCurrentMonitor();
|
||||
scaleDpi = GetWindowScaleDPI();
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -50,11 +58,30 @@ int main(void)
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw grid
|
||||
for (int h = 0; h < 20; h++) DrawLine(0, h*gridSpacing, GetRenderWidth(), h*gridSpacing, LIGHTGRAY);
|
||||
for (int v = 0; v < 40; v++) DrawLine(v*gridSpacing, 0, v*gridSpacing, GetScreenHeight(), LIGHTGRAY);
|
||||
for (int h = 0; h < 20; h++)
|
||||
{
|
||||
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
|
||||
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();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -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_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_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_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||
|
||||
@ -316,7 +316,7 @@ void SliceTextParticle(TextParticle *tp, int particlePos, int sliceLength, TextP
|
||||
void SliceTextParticleByChar(TextParticle *tp, char charToSlice, TextParticle *tps, int *particleCount)
|
||||
{
|
||||
int tokenCount = 0;
|
||||
const char **tokens = TextSplit(tp->text, charToSlice, &tokenCount);
|
||||
char **tokens = TextSplit(tp->text, charToSlice, &tokenCount);
|
||||
|
||||
if (tokenCount > 1)
|
||||
{
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
|
||||
#include "raymath.h" // Required for: Lerp()
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum TextAlignment {
|
||||
TEXT_ALIGN_LEFT = 0,
|
||||
TEXT_ALIGN_TOP = 0,
|
||||
@ -58,7 +60,7 @@ int main(void)
|
||||
// And of course the font...
|
||||
Font font = GetFontDefault();
|
||||
|
||||
// Intialize the alignment variables
|
||||
// Initialize the alignment variables
|
||||
TextAlignment hAlign = TEXT_ALIGN_CENTRE;
|
||||
TextAlignment vAlign = TEXT_ALIGN_MIDDLE;
|
||||
|
||||
@ -72,8 +74,7 @@ int main(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_LEFT))
|
||||
{
|
||||
hAlign = hAlign - 1;
|
||||
if (hAlign < 0) hAlign = 0;
|
||||
if (hAlign > 0) hAlign = hAlign - 1;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_RIGHT))
|
||||
@ -84,8 +85,7 @@ int main(void)
|
||||
|
||||
if (IsKeyPressed(KEY_UP))
|
||||
{
|
||||
vAlign = vAlign - 1;
|
||||
if (vAlign < 0) vAlign = 0;
|
||||
if (vAlign > 0) vAlign = vAlign - 1;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_DOWN))
|
||||
@ -95,7 +95,8 @@ int main(void)
|
||||
}
|
||||
|
||||
// One word per second
|
||||
wordIndex = (int)GetTime()%wordCount;
|
||||
if (wordCount > 0) wordIndex = (int)GetTime()%wordCount;
|
||||
else wordIndex = 0;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -132,4 +133,4 @@ int main(void)
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_drop_files", "examples\core_drop_files.vcxproj", "{0199E349-0701-40BC-8A7F-06A54FFA3E7C}"
|
||||
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
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gamepad", "examples\core_input_gamepad.vcxproj", "{8F19E3DA-8929-4000-87B5-3CA6929636CC}"
|
||||
EndProject
|
||||
@ -5543,7 +5543,7 @@ Global
|
||||
{19CA0070-B4B2-4394-90B7-D0C259AA35BA} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
|
||||
{2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {278D8859-20B1-428F-8448-064F46E1F021}
|
||||
{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}
|
||||
{A4662163-83E7-4309-8CAA-B0BF13655FE6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
|
||||
{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}
|
||||
{AC215730-2B5F-4498-B7F5-5DB80AEFCA5F} = {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}
|
||||
{9DE2FC01-A839-4F89-8319-9071D4C54821} = {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;
|
||||
|
||||
// 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;
|
||||
((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;
|
||||
|
||||
// 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;
|
||||
((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);
|
||||
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)
|
||||
// DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA
|
||||
// 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];
|
||||
((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2];
|
||||
|
||||
@ -357,13 +357,17 @@ void RestoreWindow(void)
|
||||
// Set window configuration state using 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
|
||||
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
|
||||
@ -601,7 +605,7 @@ void DisableCursor(void)
|
||||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
eglSwapBuffers(platform.device, platform.surface);
|
||||
if (platform.surface != EGL_NO_SURFACE) eglSwapBuffers(platform.device, platform.surface);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -740,8 +744,8 @@ void PollInputEvents(void)
|
||||
int pollEvents = 0;
|
||||
|
||||
// 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)
|
||||
while ((pollResult = ALooper_pollOnce(platform.appEnabled? 0 : -1, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT))
|
||||
// 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 || FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN))? 0 : -1, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT))
|
||||
{
|
||||
// Process this event
|
||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||
|
||||
@ -134,12 +134,13 @@ static void ErrorCallback(int error, const char *description);
|
||||
|
||||
// Window callbacks events
|
||||
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 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 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
|
||||
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 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
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -205,7 +204,6 @@ void ToggleFullscreen(void)
|
||||
|
||||
glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -231,22 +229,22 @@ void ToggleBorderlessWindowed(void)
|
||||
bool wasOnFullscreen = false;
|
||||
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();
|
||||
wasOnFullscreen = true;
|
||||
}
|
||||
|
||||
const int monitor = GetCurrentMonitor();
|
||||
int monitorCount;
|
||||
int monitorCount = 0;
|
||||
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
|
||||
const int monitor = GetCurrentMonitor();
|
||||
|
||||
if ((monitor >= 0) && (monitor < monitorCount))
|
||||
{
|
||||
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
|
||||
// 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);
|
||||
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
|
||||
// NOTE: The order matters here, it must set size first, then set position, otherwise the screen will be positioned incorrectly
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -1016,8 +1024,8 @@ Vector2 GetWindowPosition(void)
|
||||
// Get window scale DPI factor for current monitor
|
||||
Vector2 GetWindowScaleDPI(void)
|
||||
{
|
||||
Vector2 scale = { 0 };
|
||||
glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y);
|
||||
Vector2 scale = { 1.0f, 1.0f };
|
||||
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y);
|
||||
return scale;
|
||||
}
|
||||
|
||||
@ -1329,7 +1337,8 @@ void PollInputEvents(void)
|
||||
|
||||
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)
|
||||
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
|
||||
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))
|
||||
{
|
||||
// since we skipped it before, now make sure to set this on macOS
|
||||
#if defined(__APPLE__)
|
||||
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
|
||||
#endif
|
||||
// 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
|
||||
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__)
|
||||
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
|
||||
#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
|
||||
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;
|
||||
if (CORE.Window.fullscreen)
|
||||
{
|
||||
// According to glfwCreateWindow(), if the user does not have a choice, fullscreen applications
|
||||
// should default to the primary monitor
|
||||
|
||||
// NOTE: Fullscreen applications default to the primary monitor
|
||||
monitor = glfwGetPrimaryMonitor();
|
||||
if (!monitor)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
|
||||
return -1;
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
|
||||
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
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -1639,6 +1659,7 @@ int InitPlatform(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// NOTE: Not considering scale factor now, considered below
|
||||
CORE.Window.render.width = CORE.Window.screen.width;
|
||||
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))
|
||||
{
|
||||
// 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);
|
||||
#if !defined(__APPLE__)
|
||||
// Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
|
||||
glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight);
|
||||
|
||||
// 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);
|
||||
|
||||
#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
|
||||
#endif
|
||||
}
|
||||
|
||||
CORE.Window.render.width = fbWidth;
|
||||
@ -1735,28 +1755,24 @@ int InitPlatform(void)
|
||||
// Initialize input events callbacks
|
||||
//----------------------------------------------------------------------------
|
||||
// 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);
|
||||
glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback);
|
||||
glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback);
|
||||
glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback);
|
||||
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
|
||||
glfwSetKeyCallback(platform.handle, KeyCallback);
|
||||
glfwSetCharCallback(platform.handle, CharCallback);
|
||||
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
|
||||
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
|
||||
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
|
||||
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
|
||||
glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback);
|
||||
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
|
||||
for (int i = 0; i < MAX_GAMEPADS; i++)
|
||||
@ -1814,79 +1830,116 @@ void ClosePlatform(void)
|
||||
#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)
|
||||
{
|
||||
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()
|
||||
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,
|
||||
// but we don't want to change internal screen values, it breaks things
|
||||
if ((width == 0) || (height == 0)) return;
|
||||
|
||||
// Reset viewport and projection matrix for new size
|
||||
// NOTE: Stores current render size: CORE.Window.render
|
||||
SetupViewport(width, height);
|
||||
|
||||
// Set render size
|
||||
CORE.Window.currentFbo.width = width;
|
||||
CORE.Window.currentFbo.height = height;
|
||||
CORE.Window.resizedLastFrame = true;
|
||||
|
||||
if (IsWindowFullscreen()) return;
|
||||
|
||||
// if we are doing automatic DPI scaling, then the "screen" size is divided by the window scale
|
||||
if (IsWindowState(FLAG_WINDOW_HIGHDPI))
|
||||
// Check if render size was actually scaled for high-dpi
|
||||
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
|
||||
{
|
||||
width = (int)(width/GetWindowScaleDPI().x);
|
||||
height = (int)(height/GetWindowScaleDPI().y);
|
||||
// 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);
|
||||
}
|
||||
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
|
||||
}
|
||||
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
|
||||
CORE.Window.position.x = x;
|
||||
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
CORE.Input.Mouse.currentPosition.x = (float)x;
|
||||
@ -2025,20 +2078,20 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (enter) CORE.Input.Mouse.cursorOnScreen = true;
|
||||
else CORE.Input.Mouse.cursorOnScreen = false;
|
||||
}
|
||||
|
||||
// GLFW3 Joystick Connected/Disconnected Callback
|
||||
// GLFW3: Joystick connected/disconnected callback
|
||||
static void JoystickCallback(int jid, int event)
|
||||
{
|
||||
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
|
||||
# define WIN32_CLIPBOARD_IMPLEMENTATION
|
||||
# include "../external/win32_clipboard.h"
|
||||
|
||||
@ -48,11 +48,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)
|
||||
#define RGFW_NO_GL_HEADER
|
||||
#endif
|
||||
@ -527,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
|
||||
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
|
||||
@ -583,12 +547,17 @@ void SetWindowIcons(Image *images, int count)
|
||||
|
||||
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 ((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 (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), RGFW_formatToChannels(bigIcon->format), RGFW_iconTaskbar);
|
||||
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), 4, RGFW_iconTaskbar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@
|
||||
// SDL base library (window/rendered, input, timing... functionality)
|
||||
#ifdef USING_SDL3_PROJECT
|
||||
#include "SDL3/SDL.h"
|
||||
#elif USING_SDL2_PROJECT
|
||||
#elif defined(USING_SDL2_PROJECT)
|
||||
#include "SDL2/SDL.h"
|
||||
#else
|
||||
#include "SDL.h"
|
||||
@ -71,7 +71,7 @@
|
||||
// SDL OpenGL functionality (if required, instead of internal renderer)
|
||||
#ifdef USING_SDL3_PROJECT
|
||||
#include "SDL3/SDL_opengl.h"
|
||||
#elif USING_SDL2_PROJECT
|
||||
#elif defined(USING_SDL2_PROJECT)
|
||||
#include "SDL2/SDL_opengl.h"
|
||||
#else
|
||||
#include "SDL_opengl.h"
|
||||
@ -679,6 +679,7 @@ void ClearWindowState(unsigned int flags)
|
||||
{
|
||||
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
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_SDL");
|
||||
@ -1041,7 +1042,7 @@ int GetMonitorPhysicalWidth(int monitor)
|
||||
SDL_DisplayMode mode;
|
||||
SDL_GetCurrentDisplayMode(monitor, &mode);
|
||||
// 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");
|
||||
|
||||
@ -1065,7 +1066,7 @@ int GetMonitorPhysicalHeight(int monitor)
|
||||
SDL_DisplayMode mode;
|
||||
SDL_GetCurrentDisplayMode(monitor, &mode);
|
||||
// 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");
|
||||
|
||||
@ -1127,14 +1128,15 @@ Vector2 GetWindowScaleDPI(void)
|
||||
{
|
||||
Vector2 scale = { 1.0f, 1.0f };
|
||||
|
||||
#ifndef USING_VERSION_SDL3
|
||||
// NOTE: SDL_GetWindowDisplayScale was only added on SDL3
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
// NOTE: SDL_GetWindowDisplayScale added on SDL3
|
||||
// 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.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
|
||||
|
||||
return scale;
|
||||
@ -1195,7 +1197,7 @@ Image GetClipboardImage(void)
|
||||
|
||||
if (fileData)
|
||||
{
|
||||
image = LoadImageFromMemory(imageExtensions[i], fileData, dataSize);
|
||||
image = LoadImageFromMemory(imageExtensions[i], fileData, (int)dataSize);
|
||||
if (IsImageValid(image))
|
||||
{
|
||||
TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]);
|
||||
@ -1429,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,
|
||||
// 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
|
||||
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
|
||||
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);
|
||||
#endif
|
||||
|
||||
@ -1442,9 +1444,9 @@ void PollInputEvents(void)
|
||||
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
|
||||
|
||||
#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
|
||||
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);
|
||||
#endif
|
||||
|
||||
@ -1454,7 +1456,7 @@ void PollInputEvents(void)
|
||||
|
||||
} break;
|
||||
|
||||
// Window events are also polled (Minimized, maximized, close...)
|
||||
// Window events are also polled (minimized, maximized, close...)
|
||||
|
||||
#ifndef USING_VERSION_SDL3
|
||||
// SDL3 states:
|
||||
@ -1473,7 +1475,7 @@ void PollInputEvents(void)
|
||||
const int height = event.window.data2;
|
||||
SetupViewport(width, height);
|
||||
// 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.height = (int)(height/GetWindowScaleDPI().y);
|
||||
@ -1488,7 +1490,8 @@ void PollInputEvents(void)
|
||||
CORE.Window.resizedLastFrame = true;
|
||||
|
||||
#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))
|
||||
{
|
||||
int borderTop = 0;
|
||||
@ -1504,14 +1507,8 @@ void PollInputEvents(void)
|
||||
#endif
|
||||
} break;
|
||||
|
||||
case SDL_WINDOWEVENT_ENTER:
|
||||
{
|
||||
CORE.Input.Mouse.cursorOnScreen = true;
|
||||
} break;
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
{
|
||||
CORE.Input.Mouse.cursorOnScreen = false;
|
||||
} break;
|
||||
case SDL_WINDOWEVENT_ENTER: CORE.Input.Mouse.cursorOnScreen = true; break;
|
||||
case SDL_WINDOWEVENT_LEAVE: CORE.Input.Mouse.cursorOnScreen = false; break;
|
||||
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
{
|
||||
@ -1750,7 +1747,11 @@ void PollInputEvents(void)
|
||||
{
|
||||
int button = -1;
|
||||
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
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_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
|
||||
@ -1778,7 +1779,11 @@ void PollInputEvents(void)
|
||||
{
|
||||
for (int i = 0; i < MAX_GAMEPADS; i++)
|
||||
{
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
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.lastButtonPressed = button;
|
||||
@ -1791,7 +1796,11 @@ void PollInputEvents(void)
|
||||
{
|
||||
int button = -1;
|
||||
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
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_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
|
||||
@ -1819,7 +1828,11 @@ void PollInputEvents(void)
|
||||
{
|
||||
for (int i = 0; i < MAX_GAMEPADS; i++)
|
||||
{
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
if (platform.gamepadId[i] == event.gbutton.which)
|
||||
#else
|
||||
if (platform.gamepadId[i] == event.jbutton.which)
|
||||
#endif
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[i][button] = 0;
|
||||
if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
|
||||
@ -2054,28 +2067,23 @@ int InitPlatform(void)
|
||||
platform.gamepadId[i] = -1; // Set all gamepad initial instance ids as invalid to not conflict with instance id zero
|
||||
}
|
||||
|
||||
int numJoysticks = 0;
|
||||
SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks); // array of joystick IDs, they do not start from 0
|
||||
int numJoysticks = SDL_NumJoysticks();
|
||||
|
||||
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(joysticks[i]);
|
||||
platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i]));
|
||||
platform.gamepad[i] = SDL_GameControllerOpen(i);
|
||||
platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i]));
|
||||
|
||||
if (platform.gamepad[i])
|
||||
{
|
||||
CORE.Input.Gamepad.ready[i] = true;
|
||||
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_RIGHT_TRIGGER] = -1.0f;
|
||||
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';
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
|
||||
if (platform.gamepad[i])
|
||||
{
|
||||
CORE.Input.Gamepad.ready[i] = true;
|
||||
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_RIGHT_TRIGGER] = -1.0f;
|
||||
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';
|
||||
}
|
||||
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
|
||||
@ -2196,7 +2204,7 @@ static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
|
||||
for (int i = 0; i < CORE.Input.Touch.pointCount; 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].y = finger->y*CORE.Window.screen.height;
|
||||
CORE.Input.Touch.currentTouchState[i] = 1;
|
||||
|
||||
@ -54,11 +54,6 @@
|
||||
typedef struct {
|
||||
// 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;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -346,10 +341,10 @@ void SwapScreenBuffer(void)
|
||||
double GetTime(void)
|
||||
{
|
||||
double time = 0.0;
|
||||
|
||||
struct timespec ts = { 0 };
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
|
||||
|
||||
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
|
||||
|
||||
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");
|
||||
else
|
||||
{
|
||||
// TODO:
|
||||
// TODO: Load url using default browser
|
||||
}
|
||||
}
|
||||
|
||||
@ -462,86 +457,18 @@ int InitPlatform(void)
|
||||
CORE.Window.fullscreen = true;
|
||||
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))
|
||||
{
|
||||
samples = 4;
|
||||
sampleBuffer = 1;
|
||||
// TODO: Enable MSAA
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4");
|
||||
}
|
||||
|
||||
const EGLint framebufferAttribs[] =
|
||||
{
|
||||
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
|
||||
};
|
||||
// TODO: Init display and graphic device
|
||||
|
||||
const EGLint contextAttribs[] =
|
||||
{
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
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)
|
||||
// TODO: Check display, device and context activation
|
||||
bool result = true;
|
||||
if (result)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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_CLEAR(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
|
||||
@ -816,30 +816,22 @@ int GetScreenHeight(void)
|
||||
// Get current render width which is equal to screen width*dpi scale
|
||||
int GetRenderWidth(void)
|
||||
{
|
||||
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.width;
|
||||
|
||||
int width = 0;
|
||||
#if defined(__APPLE__)
|
||||
Vector2 scale = GetWindowScaleDPI();
|
||||
width = (int)((float)CORE.Window.render.width*scale.x);
|
||||
#else
|
||||
width = CORE.Window.render.width;
|
||||
#endif
|
||||
|
||||
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.width;
|
||||
else width = CORE.Window.render.width;
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
// Get current screen height which is equal to screen height*dpi scale
|
||||
int GetRenderHeight(void)
|
||||
{
|
||||
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.height;
|
||||
|
||||
int height = 0;
|
||||
#if defined(__APPLE__)
|
||||
Vector2 scale = GetWindowScaleDPI();
|
||||
height = (int)((float)CORE.Window.render.height*scale.y);
|
||||
#else
|
||||
height = CORE.Window.render.height;
|
||||
#endif
|
||||
|
||||
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.height;
|
||||
else height = CORE.Window.render.height;
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
@ -1833,7 +1825,7 @@ void TakeScreenshot(const char *fileName)
|
||||
|
||||
// Apply a scale if we are doing HIGHDPI auto-scaling
|
||||
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));
|
||||
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;
|
||||
|
||||
// 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);
|
||||
#endif
|
||||
|
||||
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||
rlLoadIdentity(); // Reset current matrix (projection)
|
||||
|
||||
54
src/rlgl.h
54
src/rlgl.h
@ -1762,11 +1762,6 @@ void rlTextureParameters(unsigned int id, int param, int value)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11)
|
||||
// Reset anisotropy filter, in case it was set
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
#endif
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case RL_TEXTURE_WRAP_S:
|
||||
@ -1786,6 +1781,9 @@ void rlTextureParameters(unsigned int id, int param, int value)
|
||||
case RL_TEXTURE_FILTER_ANISOTROPIC:
|
||||
{
|
||||
#if !defined(GRAPHICS_API_OPENGL_11)
|
||||
// Reset anisotropy filter, in case it was set
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
|
||||
if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
|
||||
else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f)
|
||||
{
|
||||
@ -3355,8 +3353,8 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
|
||||
|
||||
mipWidth /= 2;
|
||||
mipHeight /= 2;
|
||||
mipOffset += mipSize; // Increment offset position to next mipmap
|
||||
if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap
|
||||
mipOffset += mipSize; // Increment offset position to next mipmap
|
||||
if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap
|
||||
|
||||
// Security check for NPOT textures
|
||||
if (mipWidth < 1) mipWidth = 1;
|
||||
@ -3394,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_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);
|
||||
|
||||
// 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
|
||||
|
||||
@ -5220,24 +5224,36 @@ static int rlGetPixelDataSize(int width, int height, int format)
|
||||
case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB:
|
||||
case RL_PIXELFORMAT_COMPRESSED_ETC2_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_DXT5_RGBA:
|
||||
case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
|
||||
case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
|
||||
case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
|
||||
case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 16 bytes per each 4x4 block
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
double bytesPerPixel = (double)bpp/8.0;
|
||||
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
|
||||
|
||||
// Most compressed formats works on 4x4 blocks,
|
||||
// if texture is smaller, minimum dataSize is 8 or 16
|
||||
if ((width < 4) && (height < 4))
|
||||
// Compute dataSize for uncompressed texture data (no blocks)
|
||||
if ((format >= RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) &&
|
||||
(format <= RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16))
|
||||
{
|
||||
if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8;
|
||||
else if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16;
|
||||
double bytesPerPixel = (double)bpp/8.0;
|
||||
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
|
||||
}
|
||||
|
||||
return dataSize;
|
||||
|
||||
@ -127,10 +127,13 @@
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#ifndef MAX_MATERIAL_MAPS
|
||||
#define MAX_MATERIAL_MAPS 12 // Maximum number of maps supported
|
||||
#define MAX_MATERIAL_MAPS 12 // Maximum number of maps supported
|
||||
#endif
|
||||
#ifndef MAX_MESH_VERTEX_BUFFERS
|
||||
#define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh
|
||||
#define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh
|
||||
#endif
|
||||
#ifndef MAX_FILEPATH_LENGTH
|
||||
#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
25
src/rtext.c
25
src/rtext.c
@ -700,7 +700,11 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
||||
switch (type)
|
||||
{
|
||||
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:
|
||||
{
|
||||
if (cp != 32)
|
||||
@ -1593,14 +1597,13 @@ float TextToFloat(const char *text)
|
||||
|
||||
#if defined(SUPPORT_TEXT_MANIPULATION)
|
||||
// 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 bytes = 0;
|
||||
|
||||
if ((src != NULL) && (dst != NULL))
|
||||
{
|
||||
// NOTE: Alternative: use strcpy(dst, src)
|
||||
|
||||
while (*src != '\0')
|
||||
{
|
||||
*dst = *src;
|
||||
@ -1713,11 +1716,13 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
|
||||
{
|
||||
char *insertPoint = NULL; // Next insert point
|
||||
char *temp = NULL; // Temp pointer
|
||||
int textLen = 0; // Text string length
|
||||
int searchLen = 0; // Search string length of (the string to remove)
|
||||
int replaceLen = 0; // Replacement length (the string to replace by)
|
||||
int lastReplacePos = 0; // Distance between next search and end of last replace
|
||||
int count = 0; // Number of replacements
|
||||
|
||||
textLen = TextLength(text);
|
||||
searchLen = TextLength(search);
|
||||
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;
|
||||
|
||||
// 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
|
||||
|
||||
@ -1740,13 +1746,16 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
|
||||
{
|
||||
insertPoint = (char *)strstr(text, search);
|
||||
lastReplacePos = (int)(insertPoint - text);
|
||||
temp = strncpy(temp, text, lastReplacePos) + lastReplacePos;
|
||||
temp = strcpy(temp, replacement) + replaceLen;
|
||||
temp = strncpy(temp, text, tempLen - 1) + lastReplacePos;
|
||||
tempLen -= lastReplacePos;
|
||||
temp = strncpy(temp, replacement, tempLen - 1) + replaceLen;
|
||||
tempLen -= replaceLen;
|
||||
|
||||
text += lastReplacePos + searchLen; // Move to next "end of replace"
|
||||
}
|
||||
|
||||
// Copy remaind text part after replacement to result (pointed by moving temp)
|
||||
strcpy(temp, text);
|
||||
strncpy(temp, text, tempLen - 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2086,7 +2095,7 @@ int *LoadCodepoints(const char *text, int *count)
|
||||
int textLength = TextLength(text);
|
||||
|
||||
// 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;
|
||||
for (int i = 0; i < textLength; codepointCount++)
|
||||
|
||||
Reference in New Issue
Block a user