diff --git a/examples/examples.rc b/examples/examples.rc new file mode 100644 index 000000000000..4767ad480f3e --- /dev/null +++ b/examples/examples.rc @@ -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 diff --git a/examples/raylib.ico b/examples/raylib.ico new file mode 100644 index 000000000000..0cedcc55cee7 Binary files /dev/null and b/examples/raylib.ico differ diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index d8568d929687..dc8724d8f61c 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -660,7 +660,7 @@ void PollInputEvents(void) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; } } - + // Register previous touch states for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index e85f7a0ebd01..dbbbe10cc6c2 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -104,9 +104,7 @@ __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, // Types and Structures Definition //---------------------------------------------------------------------------------- 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; //---------------------------------------------------------------------------------- @@ -114,9 +112,9 @@ typedef struct { //---------------------------------------------------------------------------------- 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_Quote] = KEY_APOSTROPHE, [RGFW_Comma] = KEY_COMMA, @@ -157,7 +155,7 @@ static const unsigned short RGFWKeyToRayKey[] = { [RGFW_SuperL] = KEY_LEFT_SUPER, #ifndef RGFW_MACOS [RGFW_ShiftR] = KEY_RIGHT_SHIFT, - + [RGFW_AltR] = KEY_RIGHT_ALT, #endif [RGFW_Space] = KEY_SPACE, @@ -237,7 +235,7 @@ bool InitGraphicsDevice(void); // Initialize graphics device // Check if application should close bool WindowShouldClose(void) -{ +{ if (CORE.Window.shouldClose == false) CORE.Window.shouldClose = RGFW_window_shouldClose(platform.window); if (CORE.Window.ready) return CORE.Window.shouldClose; @@ -246,7 +244,7 @@ bool WindowShouldClose(void) // Toggle fullscreen mode void ToggleFullscreen(void) -{ +{ RGFW_window_maximize(platform.window); ToggleBorderlessWindowed(); } @@ -255,7 +253,7 @@ void ToggleFullscreen(void) void ToggleBorderlessWindowed(void) { CORE.Window.flags & FLAG_WINDOW_UNDECORATED; - + if (platform.window != NULL) TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() after window creation not available on target platform"); } @@ -430,33 +428,34 @@ void ClearWindowState(unsigned int flags) // Set icon for window void SetWindowIcon(Image image) { - i32 channels = 4; + i32 channels = 4; - switch (image.format) { + switch (image.format) + { case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float) case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float) + { channels = 1; - break; - + } break; 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 + { channels = 2; - break; - + } break; 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 + { channels = 3; - break; - + } break; 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) @@ -465,10 +464,10 @@ void SetWindowIcon(Image image) 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 + case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp + { channels = 4; - break; - + } break; default: break; } @@ -537,65 +536,70 @@ void SetWindowFocused(void) // Get native window handle void *GetWindowHandle(void) { - #ifndef RGFW_WINDOWS - return (void*)platform.window->src.window; - #else +#ifndef RGFW_WINDOWS + return (void *)platform.window->src.window; +#else return platform.window->src.hwnd; - #endif +#endif } // Get number of monitors int GetMonitorCount(void) { - RGFW_monitor* mons = RGFW_getMonitors(); - size_t i; - for (i = 0; i < 6; i++) { + #define MAX_MONITORS_SUPPORTED 6 + + 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) - return i; + { + count = i; + break; + } } - return 6; + return count; } // Get number of monitors int GetCurrentMonitor(void) { - RGFW_monitor* mons = RGFW_getMonitors(); + int current = 0; + RGFW_monitor *mons = RGFW_getMonitors(); RGFW_monitor mon = RGFW_window_getMonitor(platform.window); - size_t i; - for (i = 0; i < 6; i++) { - if (mons[i].rect.x == mon.rect.x && - mons[i].rect.y == mon.rect.y) - return i; + for (int i = 0; i < 6; i++) + { + if ((mons[i].rect.x == mon.rect.x) && (mons[i].rect.y == mon.rect.y)) current = i; } - return 0; + return current; } // Get selected monitor position 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}; } // Get selected monitor width (currently used by 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; } // Get selected monitor height (currently used by monitor) int GetMonitorHeight(int monitor) { - RGFW_monitor* mons = RGFW_getMonitors(); + RGFW_monitor *mons = RGFW_getMonitors(); - return mons[monitor].rect.h; - return 0; + return mons[monitor].rect.h; } // Get selected monitor physical width in millimetres @@ -603,15 +607,15 @@ int GetMonitorPhysicalWidth(int monitor) { RGFW_monitor* mons = RGFW_getMonitors(); - return mons[monitor].physW; + return mons[monitor].physW; } // Get selected monitor physical height in millimetres int GetMonitorPhysicalHeight(int monitor) { - RGFW_monitor* mons = RGFW_getMonitors(); + RGFW_monitor *mons = RGFW_getMonitors(); - return mons[monitor].physH; + return mons[monitor].physH; } // Get selected monitor refresh rate @@ -624,7 +628,7 @@ int GetMonitorRefreshRate(int monitor) // Get the human-readable, UTF-8 encoded name of the selected monitor const char *GetMonitorName(int monitor) { - RGFW_monitor* mons = RGFW_getMonitors(); + RGFW_monitor *mons = RGFW_getMonitors(); return mons[monitor].name; } @@ -640,7 +644,7 @@ Vector2 GetWindowScaleDPI(void) { 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 @@ -757,7 +761,7 @@ void SetMouseCursor(int cursor) static KeyboardKey ConvertScancodeToKey(u32 keycode); // Register all input events -void PollInputEvents(void) +void PollInputEvents(void) { #if defined(SUPPORT_GESTURES_SYSTEM) // NOTE: Gestures update must be called every frame to reset gestures correctly @@ -774,7 +778,7 @@ void PollInputEvents(void) CORE.Input.Mouse.currentWheelMove.y = 0; // Register previous mouse position - + // Reset last gamepad button/axis registered state for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++) @@ -808,7 +812,7 @@ void PollInputEvents(void) } // Register previous mouse states - for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) + for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i]; // Poll input events for current platform @@ -818,7 +822,7 @@ void PollInputEvents(void) #define RGFW_HOLD_MOUSE (1L<<2) #if defined(RGFW_X11) //|| defined(RGFW_MACOS) - 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.currentPosition = (Vector2){ 0.0f, 0.0f }; @@ -831,7 +835,8 @@ void PollInputEvents(void) 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]) { CORE.Input.Gamepad.ready[platform.window->event.joystick] = true; @@ -848,11 +853,10 @@ void PollInputEvents(void) switch (event->type) { case RGFW_quit: CORE.Window.shouldClose = true; break; - case RGFW_dnd: // Dropped file { - size_t i; - for (i = 0; i < event->droppedFilesCount; i++) { + for (int i = 0; i < event->droppedFilesCount; i++) + { if (CORE.Window.dropFileCount == 0) { // When a new file is dropped, we reserve a fixed number of slots for all possible dropped files @@ -862,7 +866,7 @@ void PollInputEvents(void) CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]); - + CORE.Window.dropFileCount++; } else if (CORE.Window.dropFileCount < 1024) @@ -896,8 +900,9 @@ void PollInputEvents(void) case RGFW_keyPressed: { 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 ((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++; } } break; - case RGFW_keyReleased: { KeyboardKey key = ConvertScancodeToKey(event->keyCode); @@ -933,7 +937,8 @@ void PollInputEvents(void) // Check mouse events 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; break; } @@ -951,11 +956,12 @@ void PollInputEvents(void) 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; break; } - + int btn = event->button; if (btn == RGFW_mouseLeft) btn = 1; else if (btn == RGFW_mouseRight) btn = 2; @@ -968,20 +974,21 @@ void PollInputEvents(void) } break; 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 }; - - if ((event->point.x - (platform.window->r.w / 2)) * 2) - CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x; - if ((event->point.y - (platform.window->r.h / 2)) * 2) + + if ((event->point.x - (platform.window->r.w/2))*2) + CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x; + if ((event->point.y - (platform.window->r.h/2))*2) 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.y = (event->point.y - (platform.window->r.h / 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; } - else { - CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; + else + { + CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; CORE.Input.Mouse.currentPosition.x = (float)event->point.x; 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; touchAction = 2; } break; - case RGFW_jsButtonPressed: { int button = -1; @@ -1061,25 +1067,30 @@ void PollInputEvents(void) case RGFW_jsAxisMove: { int axis = -1; - - size_t i; - for (i = 0; i < event->axisesCount; i++) + for (int i = 0; i < event->axisesCount; i++) { - switch(i) { - case 0: - if (abs(event->axis[i].x) > abs(event->axis[i].y)) { - axis = GAMEPAD_AXIS_LEFT_X; + switch(i) + { + case 0: + { + if (abs(event->axis[i].x) > abs(event->axis[i].y)) + { + axis = GAMEPAD_AXIS_LEFT_X; break; } - + axis = GAMEPAD_AXIS_LEFT_Y; - break; - case 1: - if (abs(event->axis[i].x) > abs(event->axis[i].y)) { - axis = GAMEPAD_AXIS_RIGHT_X; break; + } break; + case 1: + { + 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 3: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break; default: break; @@ -1137,9 +1148,7 @@ void PollInputEvents(void) #endif } - if (RGFW_disableCursor && platform.window->event.inFocus) - RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0)); - + if (RGFW_disableCursor && platform.window->event.inFocus) RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0)); //----------------------------------------------------------------------------- } @@ -1151,15 +1160,7 @@ void PollInputEvents(void) // Initialize platform: graphics, inputs and more 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 graphic device: display/window and graphic context - //---------------------------------------------------------------------------- unsigned int flags = RGFW_CENTER | RGFW_ALLOW_DND; // Check window creation flags @@ -1201,14 +1202,14 @@ int InitPlatform(void) if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1); - + RGFW_window_makeCurrent(platform.window); // Check surface and context activation if (platform.window != NULL) { CORE.Window.ready = true; - + CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.height = CORE.Window.screen.height; CORE.Window.currentFbo.width = CORE.Window.render.width; @@ -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, " > 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 //---------------------------------------------------------------------------- rlLoadExtensions((void*)RGFW_getProcAddress); @@ -1255,12 +1256,12 @@ int InitPlatform(void) // ... //---------------------------------------------------------------------------- - // TODO: Initialize timing system + // Initialize timing system //---------------------------------------------------------------------------- InitTimer(); //---------------------------------------------------------------------------- - // TODO: Initialize storage system + // Initialize storage system //---------------------------------------------------------------------------- CORE.Storage.basePath = GetWorkingDirectory(); //---------------------------------------------------------------------------- @@ -1281,14 +1282,12 @@ int InitPlatform(void) void ClosePlatform(void) { 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) { - if (keycode > sizeof(RGFWKeyToRayKey) / sizeof(unsigned short)) - return 0; - - return RGFWKeyToRayKey[keycode]; + return keyMappingRGFW[keycode]; } -// EOF \ No newline at end of file diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index c22150efbff0..8a0fea81a33b 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1132,7 +1132,8 @@ void PollInputEvents(void) { 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 ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) { diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index ba6071460154..17a8e4d005e8 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -398,7 +398,7 @@ int GetMonitorWidth(int monitor) { width = platform.connector->modes[platform.modeIndex].hdisplay; } - + return width; } @@ -415,7 +415,7 @@ int GetMonitorHeight(int monitor) { height = platform.connector->modes[platform.modeIndex].vdisplay; } - + return height; } @@ -479,7 +479,7 @@ const char *GetMonitorName(int monitor) { name = platform.connector->modes[platform.modeIndex].name; } - + return name; } @@ -1136,7 +1136,8 @@ void ClosePlatform(void) // Close the evdev devices - if (platform.mouseFd != -1) { + if (platform.mouseFd != -1) + { close(platform.mouseFd); 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 nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps); - if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) { - nearestIndex = i; - } + if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) nearestIndex = i; } return nearestIndex; diff --git a/src/raudio.c b/src/raudio.c index 623984e1dc26..e33712978939 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -1464,7 +1464,7 @@ Music LoadMusicStream(const char *fileName) jar_xm_reset(ctxXm); // Make sure we start at the beginning of the song musicLoaded = true; } - else + else { jar_xm_free_context(ctxXm); } @@ -1566,7 +1566,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, music.looping = true; // Looping enabled by default musicLoaded = true; } - else + else { stb_vorbis_close(ctxOgg); } diff --git a/src/raylib.h b/src/raylib.h index 26cf03e85a46..3f6b61f8a733 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1332,9 +1332,9 @@ RLAPI Image GenImageText(int width, int height, const char *text); // Image manipulation functions 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 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 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 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 diff --git a/src/raymath.h b/src/raymath.h index 63947ee8d74a..0a0b05803b83 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -2221,9 +2221,9 @@ RMAPI Quaternion QuaternionCubicHermiteSpline(Quaternion q1, Quaternion outTange float t2 = t * t; float t3 = t2 * t; float h00 = 2 * t3 - 3 * t2 + 1; - float h10 = t3 - 2 * t2 + t; - float h01 = -2 * t3 + 3 * t2; - float h11 = t3 - t2; + float h10 = t3 - 2 * t2 + t; + float h01 = -2 * t3 + 3 * t2; + float h11 = t3 - t2; Quaternion p0 = QuaternionScale(q1, h00); Quaternion m0 = QuaternionScale(outTangent1, h10); @@ -2533,7 +2533,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio translation->y = mat.m13; translation->z = mat.m14; - // Extract upper-left for determinant computation. + // Extract upper-left for determinant computation const float a = mat.m0; const float b = mat.m4; 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 h = mat.m6; const float i = mat.m10; - const float A = e * i - f * h; - const float B = f * g - d * i; - const float C = d * h - e * g; + const float A = e*i - f*h; + const float B = f*g - d*i; + const float C = d*h - e*g; - // Extract scale. - const float det = a * A + b * B + c * C; - float scalex = Vector3Length((Vector3) {a, b, c}); - float scaley = Vector3Length((Vector3) {d, e, f}); - float scalez = Vector3Length((Vector3) {g, h, i}); - Vector3 s = {scalex, scaley, scalez}; + // Extract scale + const float det = a*A + b*B + c*C; + float scalex = Vector3Length((Vector3){ a, b, c }); + float scaley = Vector3Length((Vector3){ d, e, f }); + float scalez = Vector3Length((Vector3){ g, h, i }); + Vector3 s = { scalex, scaley, scalez }; if (det < 0) s = Vector3Negate(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; if (!FloatEquals(det, 0)) { clone.m0 /= s.x; clone.m5 /= s.y; clone.m10 /= s.z; + // Extract rotation *rotation = QuaternionFromMatrix(clone); } diff --git a/src/rmodels.c b/src/rmodels.c index 5f061e2dd96d..432413cd0fd9 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -4327,7 +4327,7 @@ static Model LoadIQM(const char *fileName) model.materials[i].maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture(TextFormat("%s/%s", basePath, material)); model.meshMaterial[i] = i; - + TRACELOG(LOG_DEBUG, "MODEL: [%s] mesh name (%s), material (%s)", fileName, name, material); model.meshes[i].vertexCount = imesh[i].num_vertexes; @@ -4636,7 +4636,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou animations[a].boneCount = iqmHeader->num_poses; animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo)); animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *)); - memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here + memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here TraceLog(LOG_INFO, "IQM Anim %s", animations[a].name); // animations[a].framerate = anim.framerate; // TODO: Use animation framerate data? @@ -4913,7 +4913,7 @@ static Model LoadGLTF(const char *fileName) PBR specular/glossiness flow and extended texture flows not supported - Supports multiple meshes per model (every primitives is loaded as a separate mesh) - Supports basic animations - - Transforms, including parent-child relations, are applied on the mesh data, but the + - Transforms, including parent-child relations, are applied on the mesh data, but the hierarchy is not kept (as it can't be represented). - Mesh instances in the glTF file (i.e. same mesh linked from multiple nodes) are turned into separate raylib Meshes. @@ -5101,7 +5101,7 @@ static Model LoadGLTF(const char *fileName) // Each primitive within a glTF node becomes a Raylib Mesh. // The local-to-world transform of each node is used to transform the // points/normals/tangents of the created Mesh(es). - // Any glTF mesh linked from more than one Node (i.e. instancing) + // Any glTF mesh linked from more than one Node (i.e. instancing) // is turned into multiple Mesh's, as each Node will have its own // transform applied. // Note: the code below disregards the scenes defined in the file, all nodes are used. @@ -5262,7 +5262,7 @@ static Model LoadGLTF(const char *fileName) else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported", fileName); } else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName); - + int index = mesh->primitives[p].attributes[j].index; if (index == 0) model.meshes[meshIndex].texcoords = texcoordPtr; else if (index == 1) model.meshes[meshIndex].texcoords2 = texcoordPtr; diff --git a/src/rshapes.c b/src/rshapes.c index b119f50ec1b8..fd6ff7d23533 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -1834,7 +1834,7 @@ void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thic if (pointCount >= 3) { for (int i = 0; i < pointCount - 2; i += 2) DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color); - + // Cap circle drawing at the end of every segment //for (int i = 2; i < pointCount - 2; i += 2) DrawCircleV(points[i], thick/2.0f, color); } @@ -1846,7 +1846,7 @@ void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, C if (pointCount >= 4) { for (int i = 0; i < pointCount - 3; i += 3) DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color); - + // Cap circle drawing at the end of every segment //for (int i = 3; i < pointCount - 3; i += 3) DrawCircleV(points[i], thick/2.0f, color); } diff --git a/src/rtextures.c b/src/rtextures.c index 9d547cd0be21..b6d331385134 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -1636,19 +1636,18 @@ Image ImageFromChannel(Image image, int selectedChannel) Image result = { 0 }; // Security check to avoid program crash - if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) - return result; + if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) return result; - // Check selected channel + // Check selected channel is valid if (selectedChannel < 0) { TRACELOG(LOG_WARNING, "Channel cannot be negative. Setting channel to 0."); selectedChannel = 0; } - if (image.format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE - || image.format == PIXELFORMAT_UNCOMPRESSED_R32 - || image.format == PIXELFORMAT_UNCOMPRESSED_R16 - ) + + if (image.format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE || + image.format == PIXELFORMAT_UNCOMPRESSED_R32 || + image.format == PIXELFORMAT_UNCOMPRESSED_R16) { if (selectedChannel > 0) { @@ -1664,11 +1663,10 @@ Image ImageFromChannel(Image image, int selectedChannel) selectedChannel = 1; } } - else if (image.format == PIXELFORMAT_UNCOMPRESSED_R5G6B5 - || image.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8 - || image.format == PIXELFORMAT_UNCOMPRESSED_R32G32B32 - || image.format == PIXELFORMAT_UNCOMPRESSED_R16G16B16 - ) + else if (image.format == PIXELFORMAT_UNCOMPRESSED_R5G6B5 || + image.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8 || + image.format == PIXELFORMAT_UNCOMPRESSED_R32G32B32 || + image.format == PIXELFORMAT_UNCOMPRESSED_R16G16B16) { if (selectedChannel > 2) { @@ -1677,153 +1675,121 @@ Image ImageFromChannel(Image image, int selectedChannel) } } - // formats rgba + // Check for RGBA formats if (selectedChannel > 3) { TRACELOG(LOG_WARNING, "ImageFromChannel supports channels 0 to 3 (rgba). Setting channel to alpha."); selectedChannel = 3; } + // TODO: Consider other one-channel formats: R16, R32 result.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; result.height = image.height; result.width = image.width; 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"); 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) { 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; 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; + } break; case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: { unsigned short pixel = ((unsigned short *)image.data)[i]; - if (selectedChannel == 0) - { - imageValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31); - } - 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; - } + if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31); + else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000011111000000) >> 6)*(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; } break; case PIXELFORMAT_UNCOMPRESSED_R5G6B5: { unsigned short pixel = ((unsigned short *)image.data)[i]; - if (selectedChannel == 0) - { - imageValue = (float)((pixel & 0b1111100000000000) >> 11)*(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); - } + if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31); + else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000011111100000) >> 5)*(1.0f/63); + else if (selectedChannel == 2) pixelValue = (float)(pixel & 0b0000000000011111)*(1.0f/31); } break; case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: { unsigned short pixel = ((unsigned short *)image.data)[i]; - if (selectedChannel == 0) - { - imageValue = (float)((pixel & 0b1111000000000000) >> 12)*(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); - } + if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111000000000000) >> 12)*(1.0f/15); + else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000111100000000) >> 8)*(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); } break; 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; + } break; 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; + } break; case PIXELFORMAT_UNCOMPRESSED_R32: { - imageValue = ((float *)image.data)[k]; - + pixelValue = ((float *)image.data)[k]; k += 1; + } break; case PIXELFORMAT_UNCOMPRESSED_R32G32B32: { - imageValue = ((float *)image.data)[k + selectedChannel]; - + pixelValue = ((float *)image.data)[k + selectedChannel]; k += 3; + } break; case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: { - imageValue = ((float *)image.data)[k + selectedChannel]; - + pixelValue = ((float *)image.data)[k + selectedChannel]; k += 4; + } break; case PIXELFORMAT_UNCOMPRESSED_R16: { - imageValue = HalfToFloat(((unsigned short *)image.data)[k]); - + pixelValue = HalfToFloat(((unsigned short *)image.data)[k]); k += 1; + } break; case PIXELFORMAT_UNCOMPRESSED_R16G16B16: { - imageValue = HalfToFloat(((unsigned short *)image.data)[k+selectedChannel]); - + pixelValue = HalfToFloat(((unsigned short *)image.data)[k+selectedChannel]); k += 3; + } break; case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: { - imageValue = HalfToFloat(((unsigned short *)image.data)[k + selectedChannel]); - + pixelValue = HalfToFloat(((unsigned short *)image.data)[k + selectedChannel]); k += 4; + } break; default: break; } - pixels[i] = imageValue * 255; + pixels[i] = (unsigned char)(pixelValue*255); } } @@ -4911,12 +4877,12 @@ Color Fade(Color color, float alpha) int ColorToInt(Color color) { int result = 0; - - result = (int)(((unsigned int)color.r << 24) | - ((unsigned int)color.g << 16) | - ((unsigned int)color.b << 8) | + + result = (int)(((unsigned int)color.r << 24) | + ((unsigned int)color.g << 16) | + ((unsigned int)color.b << 8) | (unsigned int)color.a); - + return result; }