REVIEWED: Formatting, follow raylib coding conventions

This commit is contained in:
Ray 2024-06-30 11:07:38 +02:00
parent a805f46f55
commit 17cbc75aa7
12 changed files with 221 additions and 228 deletions

27
examples/examples.rc Normal file
View file

@ -0,0 +1,27 @@
GLFW_ICON ICON "raylib.ico"
1 VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
//BLOCK "080904E4" // English UK
BLOCK "040904E4" // English US
BEGIN
VALUE "CompanyName", "raylib technologies"
VALUE "FileDescription", "raylib example"
VALUE "FileVersion", "1.0"
VALUE "InternalName", "raylib-example"
VALUE "LegalCopyright", "(c) 2024 raylib technologies (@raylibtech)"
//VALUE "OriginalFilename", "raylib_app.exe"
VALUE "ProductName", "raylib-example"
VALUE "ProductVersion", "1.0"
END
END
BLOCK "VarFileInfo"
BEGIN
//VALUE "Translation", 0x809, 1252 // English UK
VALUE "Translation", 0x409, 1252 // English US
END
END

BIN
examples/raylib.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View file

@ -104,9 +104,7 @@ __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage,
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
typedef struct { typedef struct {
// TODO: Define the platform specific variables required RGFW_window *window; // Native display device (physical screen connection)
RGFW_window* window; // Native display device (physical screen connection)
} PlatformData; } PlatformData;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -116,7 +114,7 @@ extern CoreData CORE; // Global CORE state context
static PlatformData platform = { NULL }; // Platform specific static PlatformData platform = { NULL }; // Platform specific
static const unsigned short RGFWKeyToRayKey[] = { static const unsigned short keyMappingRGFW[] = {
[RGFW_KEY_NULL] = KEY_NULL, [RGFW_KEY_NULL] = KEY_NULL,
[RGFW_Quote] = KEY_APOSTROPHE, [RGFW_Quote] = KEY_APOSTROPHE,
[RGFW_Comma] = KEY_COMMA, [RGFW_Comma] = KEY_COMMA,
@ -432,31 +430,32 @@ void SetWindowIcon(Image image)
{ {
i32 channels = 4; i32 channels = 4;
switch (image.format) { switch (image.format)
{
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE:
case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float) case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float)
case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float) case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float)
{
channels = 1; channels = 1;
break; } break;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels) case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels)
case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha) case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha) case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp
{
channels = 2; channels = 2;
break; } break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float) case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float) case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha) case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha)
case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp
{
channels = 3; channels = 3;
break; } break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float) case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half 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_DXT1_RGBA: // 4 bpp (1 bit alpha)
@ -466,9 +465,9 @@ void SetWindowIcon(Image image)
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp
{
channels = 4; channels = 4;
break; } break;
default: break; default: break;
} }
@ -537,46 +536,52 @@ void SetWindowFocused(void)
// Get native window handle // Get native window handle
void *GetWindowHandle(void) void *GetWindowHandle(void)
{ {
#ifndef RGFW_WINDOWS #ifndef RGFW_WINDOWS
return (void*)platform.window->src.window; return (void *)platform.window->src.window;
#else #else
return platform.window->src.hwnd; return platform.window->src.hwnd;
#endif #endif
} }
// Get number of monitors // Get number of monitors
int GetMonitorCount(void) int GetMonitorCount(void)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); #define MAX_MONITORS_SUPPORTED 6
size_t i;
for (i = 0; i < 6; i++) { int count = MAX_MONITORS_SUPPORTED;
RGFW_monitor *mons = RGFW_getMonitors();
for (int i = 0; i < 6; i++)
{
if (!mons[i].rect.x && !mons[i].rect.y && !mons[i].rect.w && mons[i].rect.h) if (!mons[i].rect.x && !mons[i].rect.y && !mons[i].rect.w && mons[i].rect.h)
return i; {
count = i;
break;
}
} }
return 6; return count;
} }
// Get number of monitors // Get number of monitors
int GetCurrentMonitor(void) int GetCurrentMonitor(void)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); int current = 0;
RGFW_monitor *mons = RGFW_getMonitors();
RGFW_monitor mon = RGFW_window_getMonitor(platform.window); RGFW_monitor mon = RGFW_window_getMonitor(platform.window);
size_t i; for (int i = 0; i < 6; i++)
for (i = 0; i < 6; i++) { {
if (mons[i].rect.x == mon.rect.x && if ((mons[i].rect.x == mon.rect.x) && (mons[i].rect.y == mon.rect.y)) current = i;
mons[i].rect.y == mon.rect.y)
return i;
} }
return 0; return current;
} }
// Get selected monitor position // Get selected monitor position
Vector2 GetMonitorPosition(int monitor) Vector2 GetMonitorPosition(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return (Vector2){mons[monitor].rect.x, mons[monitor].rect.y}; return (Vector2){mons[monitor].rect.x, mons[monitor].rect.y};
} }
@ -584,7 +589,7 @@ Vector2 GetMonitorPosition(int monitor)
// Get selected monitor width (currently used by monitor) // Get selected monitor width (currently used by monitor)
int GetMonitorWidth(int monitor) int GetMonitorWidth(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].rect.w; return mons[monitor].rect.w;
} }
@ -592,10 +597,9 @@ int GetMonitorWidth(int monitor)
// Get selected monitor height (currently used by monitor) // Get selected monitor height (currently used by monitor)
int GetMonitorHeight(int monitor) int GetMonitorHeight(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].rect.h; return mons[monitor].rect.h;
return 0;
} }
// Get selected monitor physical width in millimetres // Get selected monitor physical width in millimetres
@ -609,7 +613,7 @@ int GetMonitorPhysicalWidth(int monitor)
// Get selected monitor physical height in millimetres // Get selected monitor physical height in millimetres
int GetMonitorPhysicalHeight(int monitor) int GetMonitorPhysicalHeight(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].physH; return mons[monitor].physH;
} }
@ -624,7 +628,7 @@ int GetMonitorRefreshRate(int monitor)
// Get the human-readable, UTF-8 encoded name of the selected monitor // Get the human-readable, UTF-8 encoded name of the selected monitor
const char *GetMonitorName(int monitor) const char *GetMonitorName(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].name; return mons[monitor].name;
} }
@ -640,7 +644,7 @@ Vector2 GetWindowScaleDPI(void)
{ {
RGFW_monitor monitor = RGFW_window_getMonitor(platform.window); RGFW_monitor monitor = RGFW_window_getMonitor(platform.window);
return (Vector2){((u32)monitor.scaleX) * platform.window->r.w, ((u32) monitor.scaleX) * platform.window->r.h}; return (Vector2){((u32)monitor.scaleX)*platform.window->r.w, ((u32) monitor.scaleX)*platform.window->r.h};
} }
// Set clipboard text content // Set clipboard text content
@ -831,7 +835,8 @@ void PollInputEvents(void)
while (RGFW_window_checkEvent(platform.window)) while (RGFW_window_checkEvent(platform.window))
{ {
if (platform.window->event.type >= RGFW_jsButtonPressed && platform.window->event.type <= RGFW_jsAxisMove) { if ((platform.window->event.type >= RGFW_jsButtonPressed) && (platform.window->event.type <= RGFW_jsAxisMove))
{
if (!CORE.Input.Gamepad.ready[platform.window->event.joystick]) if (!CORE.Input.Gamepad.ready[platform.window->event.joystick])
{ {
CORE.Input.Gamepad.ready[platform.window->event.joystick] = true; CORE.Input.Gamepad.ready[platform.window->event.joystick] = true;
@ -848,11 +853,10 @@ void PollInputEvents(void)
switch (event->type) switch (event->type)
{ {
case RGFW_quit: CORE.Window.shouldClose = true; break; case RGFW_quit: CORE.Window.shouldClose = true; break;
case RGFW_dnd: // Dropped file case RGFW_dnd: // Dropped file
{ {
size_t i; for (int i = 0; i < event->droppedFilesCount; i++)
for (i = 0; i < event->droppedFilesCount; i++) { {
if (CORE.Window.dropFileCount == 0) if (CORE.Window.dropFileCount == 0)
{ {
// When a new file is dropped, we reserve a fixed number of slots for all possible dropped files // When a new file is dropped, we reserve a fixed number of slots for all possible dropped files
@ -897,7 +901,8 @@ void PollInputEvents(void)
{ {
KeyboardKey key = ConvertScancodeToKey(event->keyCode); KeyboardKey key = ConvertScancodeToKey(event->keyCode);
if (key != KEY_NULL) { if (key != KEY_NULL)
{
// If key was up, add it to the key pressed queue // If key was up, add it to the key pressed queue
if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE))
{ {
@ -923,7 +928,6 @@ void PollInputEvents(void)
CORE.Input.Keyboard.charPressedQueueCount++; CORE.Input.Keyboard.charPressedQueueCount++;
} }
} break; } break;
case RGFW_keyReleased: case RGFW_keyReleased:
{ {
KeyboardKey key = ConvertScancodeToKey(event->keyCode); KeyboardKey key = ConvertScancodeToKey(event->keyCode);
@ -933,7 +937,8 @@ void PollInputEvents(void)
// Check mouse events // Check mouse events
case RGFW_mouseButtonPressed: case RGFW_mouseButtonPressed:
{ {
if (event->button == RGFW_mouseScrollUp || event->button == RGFW_mouseScrollDown) { if ((event->button == RGFW_mouseScrollUp) || (event->button == RGFW_mouseScrollDown))
{
CORE.Input.Mouse.currentWheelMove.y = event->scroll; CORE.Input.Mouse.currentWheelMove.y = event->scroll;
break; break;
} }
@ -951,7 +956,8 @@ void PollInputEvents(void)
case RGFW_mouseButtonReleased: case RGFW_mouseButtonReleased:
{ {
if (event->button == RGFW_mouseScrollUp || event->button == RGFW_mouseScrollDown) { if ((event->button == RGFW_mouseScrollUp) || (event->button == RGFW_mouseScrollDown))
{
CORE.Input.Mouse.currentWheelMove.y = event->scroll; CORE.Input.Mouse.currentWheelMove.y = event->scroll;
break; break;
} }
@ -968,19 +974,20 @@ void PollInputEvents(void)
} break; } break;
case RGFW_mousePosChanged: case RGFW_mousePosChanged:
{ {
if (platform.window->src.winArgs & RGFW_HOLD_MOUSE) { if (platform.window->src.winArgs & RGFW_HOLD_MOUSE)
{
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
if ((event->point.x - (platform.window->r.w / 2)) * 2) if ((event->point.x - (platform.window->r.w/2))*2)
CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x; CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x;
if ((event->point.y - (platform.window->r.h / 2)) * 2) if ((event->point.y - (platform.window->r.h/2))*2)
CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y; CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y;
CORE.Input.Mouse.currentPosition.x = (event->point.x - (platform.window->r.w / 2)) * 2; CORE.Input.Mouse.currentPosition.x = (event->point.x - (platform.window->r.w/2))*2;
CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h / 2)) * 2; CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h/2))*2;
} }
else { else
{
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
CORE.Input.Mouse.currentPosition.x = (float)event->point.x; CORE.Input.Mouse.currentPosition.x = (float)event->point.x;
CORE.Input.Mouse.currentPosition.y = (float)event->point.y; CORE.Input.Mouse.currentPosition.y = (float)event->point.y;
@ -989,7 +996,6 @@ void PollInputEvents(void)
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
touchAction = 2; touchAction = 2;
} break; } break;
case RGFW_jsButtonPressed: case RGFW_jsButtonPressed:
{ {
int button = -1; int button = -1;
@ -1061,25 +1067,30 @@ void PollInputEvents(void)
case RGFW_jsAxisMove: case RGFW_jsAxisMove:
{ {
int axis = -1; int axis = -1;
for (int i = 0; i < event->axisesCount; i++)
size_t i; {
for (i = 0; i < event->axisesCount; i++) switch(i)
{ {
switch(i) {
case 0: case 0:
if (abs(event->axis[i].x) > abs(event->axis[i].y)) { {
if (abs(event->axis[i].x) > abs(event->axis[i].y))
{
axis = GAMEPAD_AXIS_LEFT_X; axis = GAMEPAD_AXIS_LEFT_X;
break; break;
} }
axis = GAMEPAD_AXIS_LEFT_Y; axis = GAMEPAD_AXIS_LEFT_Y;
break; } break;
case 1: case 1:
if (abs(event->axis[i].x) > abs(event->axis[i].y)) { {
axis = GAMEPAD_AXIS_RIGHT_X; break; if (abs(event->axis[i].x) > abs(event->axis[i].y))
{
axis = GAMEPAD_AXIS_RIGHT_X;
break;
} }
axis = GAMEPAD_AXIS_RIGHT_Y; break; axis = GAMEPAD_AXIS_RIGHT_Y;
} break;
case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break; case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break;
case 3: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break; case 3: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break;
default: break; default: break;
@ -1137,9 +1148,7 @@ void PollInputEvents(void)
#endif #endif
} }
if (RGFW_disableCursor && platform.window->event.inFocus) if (RGFW_disableCursor && platform.window->event.inFocus) RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
} }
@ -1151,15 +1160,7 @@ void PollInputEvents(void)
// Initialize platform: graphics, inputs and more // Initialize platform: graphics, inputs and more
int InitPlatform(void) int InitPlatform(void)
{ {
// TODO: Initialize graphic device: display/window
// It usually requires setting up the platform display system configuration
// and connexion with the GPU through some system graphic API
// raylib uses OpenGL so, platform should create that kind of connection
// Below example illustrates that process using EGL library
//----------------------------------------------------------------------------
// Initialize RGFW internal global state, only required systems // Initialize RGFW internal global state, only required systems
// Initialize graphic device: display/window and graphic context
//----------------------------------------------------------------------------
unsigned int flags = RGFW_CENTER | RGFW_ALLOW_DND; unsigned int flags = RGFW_CENTER | RGFW_ALLOW_DND;
// Check window creation flags // Check window creation flags
@ -1241,7 +1242,7 @@ int InitPlatform(void)
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
// TODO: Load OpenGL extensions // Load OpenGL extensions
// NOTE: GL procedures address loader is required to load extensions // NOTE: GL procedures address loader is required to load extensions
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
rlLoadExtensions((void*)RGFW_getProcAddress); rlLoadExtensions((void*)RGFW_getProcAddress);
@ -1255,12 +1256,12 @@ int InitPlatform(void)
// ... // ...
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// TODO: Initialize timing system // Initialize timing system
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
InitTimer(); InitTimer();
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// TODO: Initialize storage system // Initialize storage system
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
CORE.Storage.basePath = GetWorkingDirectory(); CORE.Storage.basePath = GetWorkingDirectory();
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1281,14 +1282,12 @@ int InitPlatform(void)
void ClosePlatform(void) void ClosePlatform(void)
{ {
RGFW_window_close(platform.window); RGFW_window_close(platform.window);
// TODO: De-initialize graphics, inputs and more
} }
// Keycode mapping
static KeyboardKey ConvertScancodeToKey(u32 keycode)
{
if (keycode > sizeof(keyMappingRGFW)/sizeof(unsigned short)) return 0;
static KeyboardKey ConvertScancodeToKey(u32 keycode) { return keyMappingRGFW[keycode];
if (keycode > sizeof(RGFWKeyToRayKey) / sizeof(unsigned short))
return 0;
return RGFWKeyToRayKey[keycode];
} }
// EOF

View file

@ -1132,7 +1132,8 @@ void PollInputEvents(void)
{ {
KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode); KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
if (key != KEY_NULL) { if (key != KEY_NULL)
{
// If key was up, add it to the key pressed queue // If key was up, add it to the key pressed queue
if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE))
{ {

View file

@ -1136,7 +1136,8 @@ void ClosePlatform(void)
// Close the evdev devices // Close the evdev devices
if (platform.mouseFd != -1) { if (platform.mouseFd != -1)
{
close(platform.mouseFd); close(platform.mouseFd);
platform.mouseFd = -1; platform.mouseFd = -1;
} }
@ -1924,9 +1925,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height); const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height);
const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps); const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps);
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) { if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) nearestIndex = i;
nearestIndex = i;
}
} }
return nearestIndex; return nearestIndex;

View file

@ -1332,9 +1332,9 @@ RLAPI Image GenImageText(int width, int height, const char *text);
// Image manipulation functions // Image manipulation functions
RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece
RLAPI Image ImageFromChannel(Image image, int selectedChannel); // Create an image from a selected channel of another image (GRAYSCALE/R16/R32)
RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font) RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font)
RLAPI Image ImageFromChannel(Image image, int selectedChannel); // Create an image from a selected channel of another image
RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
RLAPI void ImageToPOT(Image *image, Color fill); // Convert image to POT (power-of-two) RLAPI void ImageToPOT(Image *image, Color fill); // Convert image to POT (power-of-two)
RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle

View file

@ -2533,7 +2533,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
translation->y = mat.m13; translation->y = mat.m13;
translation->z = mat.m14; translation->z = mat.m14;
// Extract upper-left for determinant computation. // Extract upper-left for determinant computation
const float a = mat.m0; const float a = mat.m0;
const float b = mat.m4; const float b = mat.m4;
const float c = mat.m8; const float c = mat.m8;
@ -2543,28 +2543,29 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
const float g = mat.m2; const float g = mat.m2;
const float h = mat.m6; const float h = mat.m6;
const float i = mat.m10; const float i = mat.m10;
const float A = e * i - f * h; const float A = e*i - f*h;
const float B = f * g - d * i; const float B = f*g - d*i;
const float C = d * h - e * g; const float C = d*h - e*g;
// Extract scale. // Extract scale
const float det = a * A + b * B + c * C; const float det = a*A + b*B + c*C;
float scalex = Vector3Length((Vector3) {a, b, c}); float scalex = Vector3Length((Vector3){ a, b, c });
float scaley = Vector3Length((Vector3) {d, e, f}); float scaley = Vector3Length((Vector3){ d, e, f });
float scalez = Vector3Length((Vector3) {g, h, i}); float scalez = Vector3Length((Vector3){ g, h, i });
Vector3 s = {scalex, scaley, scalez}; Vector3 s = { scalex, scaley, scalez };
if (det < 0) s = Vector3Negate(s); if (det < 0) s = Vector3Negate(s);
*scale = s; *scale = s;
// Remove scale from the matrix if it is not close to zero. // Remove scale from the matrix if it is not close to zero
Matrix clone = mat; Matrix clone = mat;
if (!FloatEquals(det, 0)) if (!FloatEquals(det, 0))
{ {
clone.m0 /= s.x; clone.m0 /= s.x;
clone.m5 /= s.y; clone.m5 /= s.y;
clone.m10 /= s.z; clone.m10 /= s.z;
// Extract rotation // Extract rotation
*rotation = QuaternionFromMatrix(clone); *rotation = QuaternionFromMatrix(clone);
} }

View file

@ -1636,19 +1636,18 @@ Image ImageFromChannel(Image image, int selectedChannel)
Image result = { 0 }; Image result = { 0 };
// Security check to avoid program crash // Security check to avoid program crash
if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) return result;
return result;
// Check selected channel // Check selected channel is valid
if (selectedChannel < 0) if (selectedChannel < 0)
{ {
TRACELOG(LOG_WARNING, "Channel cannot be negative. Setting channel to 0."); TRACELOG(LOG_WARNING, "Channel cannot be negative. Setting channel to 0.");
selectedChannel = 0; selectedChannel = 0;
} }
if (image.format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE
|| image.format == PIXELFORMAT_UNCOMPRESSED_R32 if (image.format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE ||
|| image.format == PIXELFORMAT_UNCOMPRESSED_R16 image.format == PIXELFORMAT_UNCOMPRESSED_R32 ||
) image.format == PIXELFORMAT_UNCOMPRESSED_R16)
{ {
if (selectedChannel > 0) if (selectedChannel > 0)
{ {
@ -1664,11 +1663,10 @@ Image ImageFromChannel(Image image, int selectedChannel)
selectedChannel = 1; selectedChannel = 1;
} }
} }
else if (image.format == PIXELFORMAT_UNCOMPRESSED_R5G6B5 else if (image.format == PIXELFORMAT_UNCOMPRESSED_R5G6B5 ||
|| image.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8 image.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8 ||
|| image.format == PIXELFORMAT_UNCOMPRESSED_R32G32B32 image.format == PIXELFORMAT_UNCOMPRESSED_R32G32B32 ||
|| image.format == PIXELFORMAT_UNCOMPRESSED_R16G16B16 image.format == PIXELFORMAT_UNCOMPRESSED_R16G16B16)
)
{ {
if (selectedChannel > 2) if (selectedChannel > 2)
{ {
@ -1677,153 +1675,121 @@ Image ImageFromChannel(Image image, int selectedChannel)
} }
} }
// formats rgba // Check for RGBA formats
if (selectedChannel > 3) if (selectedChannel > 3)
{ {
TRACELOG(LOG_WARNING, "ImageFromChannel supports channels 0 to 3 (rgba). Setting channel to alpha."); TRACELOG(LOG_WARNING, "ImageFromChannel supports channels 0 to 3 (rgba). Setting channel to alpha.");
selectedChannel = 3; selectedChannel = 3;
} }
// TODO: Consider other one-channel formats: R16, R32
result.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; result.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
result.height = image.height; result.height = image.height;
result.width = image.width; result.width = image.width;
result.mipmaps = 1; result.mipmaps = 1;
unsigned char *pixels = (unsigned char *)RL_CALLOC(image.width * image.height, sizeof(unsigned char)); // values 0 to 255 unsigned char *pixels = (unsigned char *)RL_CALLOC(image.width*image.height, sizeof(unsigned char)); // Values from 0 to 255
if (image.format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "IMAGE: Pixel data retrieval not supported for compressed image formats"); if (image.format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "IMAGE: Pixel data retrieval not supported for compressed image formats");
else else
{ {
for (int i = 0, k = 0; i < image.width * image.height; ++i) for (int i = 0, k = 0; i < image.width*image.height; i++)
{ {
float imageValue = -1; float pixelValue = -1;
switch (image.format) switch (image.format)
{ {
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE:
{ {
imageValue = (float)((unsigned char *)image.data)[i + selectedChannel]/255.0f; pixelValue = (float)((unsigned char *)image.data)[i + selectedChannel]/255.0f;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
{ {
imageValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f; pixelValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f;
k += 2; k += 2;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
{ {
unsigned short pixel = ((unsigned short *)image.data)[i]; unsigned short pixel = ((unsigned short *)image.data)[i];
if (selectedChannel == 0) if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31);
{ else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000011111000000) >> 6)*(1.0f/31);
imageValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31); else if (selectedChannel == 2) pixelValue = (float)((pixel & 0b0000000000111110) >> 1)*(1.0f/31);
} else if (selectedChannel == 3) pixelValue = ((pixel & 0b0000000000000001) == 0)? 0.0f : 1.0f;
else if (selectedChannel == 1)
{
imageValue = (float)((pixel & 0b0000011111000000) >> 6)*(1.0f/31);
}
else if (selectedChannel == 2)
{
imageValue = (float)((pixel & 0b0000000000111110) >> 1)*(1.0f/31);
}
else if (selectedChannel == 3)
{
imageValue = ((pixel & 0b0000000000000001) == 0)? 0.0f : 1.0f;
}
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R5G6B5: case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
{ {
unsigned short pixel = ((unsigned short *)image.data)[i]; unsigned short pixel = ((unsigned short *)image.data)[i];
if (selectedChannel == 0) if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31);
{ else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000011111100000) >> 5)*(1.0f/63);
imageValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31); else if (selectedChannel == 2) pixelValue = (float)(pixel & 0b0000000000011111)*(1.0f/31);
}
else if (selectedChannel == 1)
{
imageValue = (float)((pixel & 0b0000011111100000) >> 5)*(1.0f/63);
}
else if (selectedChannel == 2)
{
imageValue = (float)(pixel & 0b0000000000011111)*(1.0f/31);
}
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4:
{ {
unsigned short pixel = ((unsigned short *)image.data)[i]; unsigned short pixel = ((unsigned short *)image.data)[i];
if (selectedChannel == 0) if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111000000000000) >> 12)*(1.0f/15);
{ else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000111100000000) >> 8)*(1.0f/15);
imageValue = (float)((pixel & 0b1111000000000000) >> 12)*(1.0f/15); else if (selectedChannel == 2) pixelValue = (float)((pixel & 0b0000000011110000) >> 4)*(1.0f/15);
} else if (selectedChannel == 3) pixelValue = (float)(pixel & 0b0000000000001111)*(1.0f/15);
else if (selectedChannel == 1)
{
imageValue = (float)((pixel & 0b0000111100000000) >> 8)*(1.0f/15);
}
else if (selectedChannel == 2)
{
imageValue = (float)((pixel & 0b0000000011110000) >> 4)*(1.0f/15);
}
else if (selectedChannel == 3)
{
imageValue = (float)(pixel & 0b0000000000001111)*(1.0f/15);
}
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8:
{ {
imageValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f; pixelValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f;
k += 4; k += 4;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: case PIXELFORMAT_UNCOMPRESSED_R8G8B8:
{ {
imageValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f; pixelValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f;
k += 3; k += 3;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R32: case PIXELFORMAT_UNCOMPRESSED_R32:
{ {
imageValue = ((float *)image.data)[k]; pixelValue = ((float *)image.data)[k];
k += 1; k += 1;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: case PIXELFORMAT_UNCOMPRESSED_R32G32B32:
{ {
imageValue = ((float *)image.data)[k + selectedChannel]; pixelValue = ((float *)image.data)[k + selectedChannel];
k += 3; k += 3;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32:
{ {
imageValue = ((float *)image.data)[k + selectedChannel]; pixelValue = ((float *)image.data)[k + selectedChannel];
k += 4; k += 4;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R16: case PIXELFORMAT_UNCOMPRESSED_R16:
{ {
imageValue = HalfToFloat(((unsigned short *)image.data)[k]); pixelValue = HalfToFloat(((unsigned short *)image.data)[k]);
k += 1; k += 1;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R16G16B16: case PIXELFORMAT_UNCOMPRESSED_R16G16B16:
{ {
imageValue = HalfToFloat(((unsigned short *)image.data)[k+selectedChannel]); pixelValue = HalfToFloat(((unsigned short *)image.data)[k+selectedChannel]);
k += 3; k += 3;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16:
{ {
imageValue = HalfToFloat(((unsigned short *)image.data)[k + selectedChannel]); pixelValue = HalfToFloat(((unsigned short *)image.data)[k + selectedChannel]);
k += 4; k += 4;
} break; } break;
default: break; default: break;
} }
pixels[i] = imageValue * 255; pixels[i] = (unsigned char)(pixelValue*255);
} }
} }