diff --git a/examples/audio/audio_raw_stream.c b/examples/audio/audio_raw_stream.c index 6befa765a..b3173ab97 100644 --- a/examples/audio/audio_raw_stream.c +++ b/examples/audio/audio_raw_stream.c @@ -38,8 +38,7 @@ float sineIdx = 0.0f; void AudioInputCallback(void *buffer, unsigned int frames) { audioFrequency = frequency + (audioFrequency - frequency)*0.95f; - audioFrequency += 1.0f; - audioFrequency -= 1.0f; + float incr = audioFrequency/44100.0f; short *d = (short *)buffer; diff --git a/projects/CMake/CMakeLists.txt b/projects/CMake/CMakeLists.txt index cc606a4a2..ee258d604 100644 --- a/projects/CMake/CMakeLists.txt +++ b/projects/CMake/CMakeLists.txt @@ -5,7 +5,7 @@ project(example) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Dependencies -set(RAYLIB_VERSION 4.5.0) +set(RAYLIB_VERSION 5.0) find_package(raylib ${RAYLIB_VERSION} QUIET) # QUIET or REQUIRED if (NOT raylib_FOUND) # If there's none, fetch and build raylib include(FetchContent) @@ -40,4 +40,4 @@ if (APPLE) target_link_libraries(${PROJECT_NAME} "-framework IOKit") target_link_libraries(${PROJECT_NAME} "-framework Cocoa") target_link_libraries(${PROJECT_NAME} "-framework OpenGL") -endif() \ No newline at end of file +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4335bda5c..919efeb4d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ # Setup the project and settings project(raylib C) -set(PROJECT_VERSION 4.5.0) -set(API_VERSION 450) +set(PROJECT_VERSION 5.0.0) +set(API_VERSION 500) include(GNUInstallDirs) include(JoinPaths) diff --git a/src/external/rprand.h b/src/external/rprand.h index c9b460cd6..7e27d980f 100644 --- a/src/external/rprand.h +++ b/src/external/rprand.h @@ -200,8 +200,7 @@ int *rprand_load_sequence(unsigned int count, int min, int max) for (unsigned int i = 0; i < count;) { - value = ((int)rprand_xoshiro()%(abs(max - min) + 1)) + min; - value_is_dup = false; + value = ((unsigned int)rprand_xoshiro()%(abs(max - min) + 1)) + min; for (int j = 0; j < i; j++) { @@ -217,6 +216,8 @@ int *rprand_load_sequence(unsigned int count, int min, int max) sequence[i] = value; i++; } + + value_is_dup = false; } return sequence; diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 8cb0c1be8..e1e6e4c9a 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -996,7 +996,7 @@ void PollInputEvents(void) CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE - bool gestureUpdate = false; // Flag to note gestures require to update + bool realTouch = false; // Flag to differentiate real touch gestures from mouse ones // Register previous keys states // NOTE: Android supports up to 260 keys @@ -1141,7 +1141,6 @@ void PollInputEvents(void) CORE.Input.Touch.currentTouchState[btn] = 1; touchAction = 1; - gestureUpdate = true; } break; case SDL_MOUSEBUTTONUP: { @@ -1155,7 +1154,6 @@ void PollInputEvents(void) CORE.Input.Touch.currentTouchState[btn] = 0; touchAction = 0; - gestureUpdate = true; } break; case SDL_MOUSEWHEEL: { @@ -1178,32 +1176,38 @@ void PollInputEvents(void) CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; touchAction = 2; - gestureUpdate = true; } break; // Check touch events // NOTE: These cases need to be reviewed on a real touch screen case SDL_FINGERDOWN: { - CORE.Input.Touch.currentTouchState[event.tfinger.fingerId] = 1; + const int touchId = (int)event.tfinger.fingerId; + CORE.Input.Touch.currentTouchState[touchId] = 1; + CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width; + CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height; touchAction = 1; - gestureUpdate = true; + realTouch = true; } break; case SDL_FINGERUP: { - CORE.Input.Touch.currentTouchState[event.tfinger.fingerId] = 0; + const int touchId = (int)event.tfinger.fingerId; + CORE.Input.Touch.currentTouchState[touchId] = 0; + CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width; + CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height; touchAction = 0; - gestureUpdate = true; + realTouch = true; } break; case SDL_FINGERMOTION: { - CORE.Input.Touch.position[event.tfinger.fingerId].x = (float)event.motion.x; - CORE.Input.Touch.position[event.tfinger.fingerId].y = (float)event.motion.y; + const int touchId = (int)event.tfinger.fingerId; + CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width; + CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height; touchAction = 2; - gestureUpdate = true; + realTouch = true; } break; // Check gamepad events @@ -1228,7 +1232,7 @@ void PollInputEvents(void) } #if defined(SUPPORT_GESTURES_SYSTEM) - if (gestureUpdate) + if (touchAction > -1) { // Process mouse events as touches to be able to use mouse-gestures GestureEvent gestureEvent = { 0 }; @@ -1243,7 +1247,7 @@ void PollInputEvents(void) gestureEvent.pointCount = 1; // Register touch points position, only one point registered - if (touchAction == 2) gestureEvent.position[0] = CORE.Input.Touch.position[0]; + if (touchAction == 2 || realTouch) gestureEvent.position[0] = CORE.Input.Touch.position[0]; else gestureEvent.position[0] = GetMousePosition(); // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height @@ -1252,6 +1256,8 @@ void PollInputEvents(void) // Gesture data is sent to gestures-system for processing ProcessGestureEvent(gestureEvent); + + touchAction = -1; } #endif } @@ -1404,6 +1410,11 @@ int InitPlatform(void) //if (platform.gamepadgamepad == NULL) TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); } + // Disable mouse events being interpreted as touch events + // NOTE: This is wanted because there are SDL_FINGER* events available which provide unique data + // Due to the way PollInputEvents() and rgestures.h are currently implemented, setting this won't break SUPPORT_MOUSE_GESTURES + SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); + SDL_EventState(SDL_DROPFILE, SDL_ENABLE); //---------------------------------------------------------------------------- diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index e9493d721..2fec53f58 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -612,7 +612,6 @@ void PollInputEvents(void) struct input_event event = { 0 }; int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE - bool gestureUpdate = false; // Flag to note gestures require to update // Try to read data from the mouse/touch/gesture and only continue if successful while (read(fd, &event, sizeof(event)) == (int)sizeof(event)) @@ -631,7 +630,6 @@ void PollInputEvents(void) CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x; touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; } if (event.code == REL_Y) @@ -645,7 +643,6 @@ void PollInputEvents(void) CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y; touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; } if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value; @@ -661,7 +658,6 @@ void PollInputEvents(void) CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; } if (event.code == ABS_Y) @@ -670,7 +666,6 @@ void PollInputEvents(void) CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; } // Multitouch movement @@ -706,7 +701,6 @@ void PollInputEvents(void) platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0; touchAction = 0; // TOUCH_ACTION_UP - gestureUpdate = true; } if (event.value && !previousMouseLeftButtonState) @@ -714,7 +708,6 @@ void PollInputEvents(void) platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1; touchAction = 1; // TOUCH_ACTION_DOWN - gestureUpdate = true; } } @@ -730,7 +723,6 @@ void PollInputEvents(void) if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN else touchAction = 0; // TOUCH_ACTION_UP - gestureUpdate = true; } if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value; @@ -759,7 +751,7 @@ void PollInputEvents(void) } #if defined(SUPPORT_GESTURES_SYSTEM) - if (gestureUpdate) + if (touchAction > -1) { GestureEvent gestureEvent = { 0 }; @@ -774,7 +766,7 @@ void PollInputEvents(void) ProcessGestureEvent(gestureEvent); - gestureUpdate = false; + touchAction = -1; } #endif } diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index ae210853b..8ffceafdc 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -211,7 +211,33 @@ void ToggleFullscreen(void) // Toggle borderless windowed mode void ToggleBorderlessWindowed(void) { - TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform"); + const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); + if (wasFullscreen) + { + EM_ASM(document.exitFullscreen();); + + CORE.Window.fullscreen = false; + CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; + } + + if (!IsWindowState(FLAG_BORDERLESS_WINDOWED_MODE)) + { + // NOTE: 1. The setTimeouts handle the browser mode change delay + // 2. The style unset handles the possibility of a width="100%" like on the default shell.html file + EM_ASM( + setTimeout(function() + { + Module.requestFullscreen(true, true); + setTimeout(function() + { + canvas.style.width="unset"; + }, 100); + }, 100); + ); + + CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE; + } + else CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; } // Set window state: maximized, if resizable @@ -235,13 +261,215 @@ void RestoreWindow(void) // Set window configuration state using flags void SetWindowState(unsigned int flags) { - TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform"); + // Check previous state and requested state to apply required changes + // NOTE: In most cases the functions already change the flags internally + + // State change: FLAG_VSYNC_HINT + if ((flags & FLAG_VSYNC_HINT) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_VSYNC_HINT) not available on target platform"); + } + + // State change: FLAG_BORDERLESS_WINDOWED_MODE + if (((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) != (flags & FLAG_BORDERLESS_WINDOWED_MODE)) && ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0)) + { + ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function + } + + // State change: FLAG_FULLSCREEN_MODE + if ((flags & FLAG_FULLSCREEN_MODE) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_FULLSCREEN_MODE) not available yet on target platform"); + } + + // State change: FLAG_WINDOW_RESIZABLE + if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != (flags & FLAG_WINDOW_RESIZABLE)) && ((flags & FLAG_WINDOW_RESIZABLE) > 0)) + { + glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_TRUE); + CORE.Window.flags |= FLAG_WINDOW_RESIZABLE; + } + + // State change: FLAG_WINDOW_UNDECORATED + if ((flags & FLAG_WINDOW_UNDECORATED) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_UNDECORATED) not available on target platform"); + } + + // State change: FLAG_WINDOW_HIDDEN + if ((flags & FLAG_WINDOW_HIDDEN) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_HIDDEN) not available on target platform"); + } + + // State change: FLAG_WINDOW_MINIMIZED + if ((flags & FLAG_WINDOW_MINIMIZED) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MINIMIZED) not available on target platform"); + } + + // State change: FLAG_WINDOW_MAXIMIZED + if ((flags & FLAG_WINDOW_MAXIMIZED) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MAXIMIZED) not available on target platform"); + } + + // State change: FLAG_WINDOW_UNFOCUSED + if ((flags & FLAG_WINDOW_UNFOCUSED) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_UNFOCUSED) not available on target platform"); + } + + // State change: FLAG_WINDOW_TOPMOST + if ((flags & FLAG_WINDOW_TOPMOST) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_TOPMOST) not available on target platform"); + } + + // State change: FLAG_WINDOW_ALWAYS_RUN + if ((flags & FLAG_WINDOW_ALWAYS_RUN) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_ALWAYS_RUN) not available on target platform"); + } + + // The following states can not be changed after window creation + // NOTE: Review for PLATFORM_WEB + + // State change: FLAG_WINDOW_TRANSPARENT + if ((flags & FLAG_WINDOW_TRANSPARENT) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_TRANSPARENT) not available on target platform"); + } + + // State change: FLAG_WINDOW_HIGHDPI + if ((flags & FLAG_WINDOW_HIGHDPI) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_HIGHDPI) not available on target platform"); + } + + // State change: FLAG_WINDOW_MOUSE_PASSTHROUGH + if ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH) not available on target platform"); + } + + // State change: FLAG_MSAA_4X_HINT + if ((flags & FLAG_MSAA_4X_HINT) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_MSAA_4X_HINT) not available on target platform"); + } + + // State change: FLAG_INTERLACED_HINT + if ((flags & FLAG_INTERLACED_HINT) > 0) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_INTERLACED_HINT) not available on target platform"); + } } // Clear window configuration state flags void ClearWindowState(unsigned int flags) { - TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform"); + // Check previous state and requested state to apply required changes + // NOTE: In most cases the functions already change the flags internally + + // State change: FLAG_VSYNC_HINT + if ((flags & FLAG_VSYNC_HINT) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_VSYNC_HINT) not available on target platform"); + } + + // State change: FLAG_BORDERLESS_WINDOWED_MODE + if (((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) && ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0)) + { + ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function + } + + // State change: FLAG_FULLSCREEN_MODE + if ((flags & FLAG_FULLSCREEN_MODE) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_FULLSCREEN_MODE) not available yet on target platform"); + } + + // State change: FLAG_WINDOW_RESIZABLE + if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) && ((flags & FLAG_WINDOW_RESIZABLE) > 0)) + { + glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_FALSE); + CORE.Window.flags &= ~FLAG_WINDOW_RESIZABLE; + } + + // State change: FLAG_WINDOW_HIDDEN + if ((flags & FLAG_WINDOW_HIDDEN) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_HIDDEN) not available on target platform"); + } + + // State change: FLAG_WINDOW_MINIMIZED + if ((flags & FLAG_WINDOW_MINIMIZED) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MINIMIZED) not available on target platform"); + } + + // State change: FLAG_WINDOW_MAXIMIZED + if ((flags & FLAG_WINDOW_MAXIMIZED) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MAXIMIZED) not available on target platform"); + } + + // State change: FLAG_WINDOW_UNDECORATED + if ((flags & FLAG_WINDOW_UNDECORATED) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_UNDECORATED) not available on target platform"); + } + + // State change: FLAG_WINDOW_UNFOCUSED + if ((flags & FLAG_WINDOW_UNFOCUSED) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_UNFOCUSED) not available on target platform"); + } + + // State change: FLAG_WINDOW_TOPMOST + if ((flags & FLAG_WINDOW_TOPMOST) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_TOPMOST) not available on target platform"); + } + + // State change: FLAG_WINDOW_ALWAYS_RUN + if ((flags & FLAG_WINDOW_ALWAYS_RUN) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_ALWAYS_RUN) not available on target platform"); + } + + // The following states can not be changed after window creation + // NOTE: Review for PLATFORM_WEB + + // State change: FLAG_WINDOW_TRANSPARENT + if ((flags & FLAG_WINDOW_TRANSPARENT) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_TRANSPARENT) not available on target platform"); + } + + // State change: FLAG_WINDOW_HIGHDPI + if ((flags & FLAG_WINDOW_HIGHDPI) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_HIGHDPI) not available on target platform"); + } + + // State change: FLAG_WINDOW_MOUSE_PASSTHROUGH + if ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH) not available on target platform"); + } + + // State change: FLAG_MSAA_4X_HINT + if ((flags & FLAG_MSAA_4X_HINT) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_MSAA_4X_HINT) not available on target platform"); + } + + // State change: FLAG_INTERLACED_HINT + if ((flags & FLAG_INTERLACED_HINT) > 0) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_INTERLACED_HINT) not available on target platform"); + } } // Set icon for window diff --git a/src/rtextures.c b/src/rtextures.c index 8742b0c9c..c78b0ebf4 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3706,7 +3706,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color // Draw text (default font) within an image (destination) void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color) { -#if defined(SUPPORT_MODULE_RTEXT) +#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) // Make sure default font is loaded to be used on image text drawing if (GetFontDefault().texture.id == 0) LoadFontDefault();