From 04678bc585b51bf218310387b048e846ca4a7718 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Wed, 2 Aug 2023 10:12:38 -0700 Subject: [PATCH 1/5] int math done with floats causes warnings. (#3218) --- src/rcore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 282fec17e..fc87e7354 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -1693,8 +1693,8 @@ void SetWindowMonitor(int monitor) if ((screenWidth >= monitorWorkareaWidth) || (screenHeight >= monitorWorkareaHeight)) glfwSetWindowPos(CORE.Window.handle, monitorWorkareaX, monitorWorkareaY); else { - const int x = monitorWorkareaX + (monitorWorkareaWidth*0.5f) - (screenWidth*0.5f); - const int y = monitorWorkareaY + (monitorWorkareaHeight*0.5f) - (screenHeight*0.5f); + const int x = monitorWorkareaX + (monitorWorkareaWidth/2) - (screenWidth/2); + const int y = monitorWorkareaY + (monitorWorkareaHeight/2) - (screenHeight/2); glfwSetWindowPos(CORE.Window.handle, x, y); } } From 464e714a2e256e7501239e0a5a12a2e9ee4e7f04 Mon Sep 17 00:00:00 2001 From: ubkp <118854183+ubkp@users.noreply.github.com> Date: Wed, 2 Aug 2023 14:16:35 -0300 Subject: [PATCH 2/5] Adds BORDERLESS_WINDOWED_MODE for PLATFORM_DESKTOP (#3216) --- src/raylib.h | 2 ++ src/rcore.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/src/raylib.h b/src/raylib.h index b3f17bd53..45a6120f5 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -526,6 +526,7 @@ typedef enum { FLAG_WINDOW_TRANSPARENT = 0x00000010, // Set to allow transparent framebuffer FLAG_WINDOW_HIGHDPI = 0x00002000, // Set to support HighDPI FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED + FLAG_BORDERLESS_WINDOWED_MODE = 0x00008000, // Set to run program in borderless windowed mode FLAG_MSAA_4X_HINT = 0x00000020, // Set to try enabling MSAA 4X FLAG_INTERLACED_HINT = 0x00010000 // Set to try enabling interlaced video format (for V3D) } ConfigFlags; @@ -947,6 +948,7 @@ RLAPI bool IsWindowState(unsigned int flag); // Check if on RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP) RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP) +RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP) RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP) RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP) RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) diff --git a/src/rcore.c b/src/rcore.c index fc87e7354..d5addad48 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -412,6 +412,8 @@ typedef struct CoreData { Size render; // Framebuffer width and height (render area, including black bars if required) Point renderOffset; // Offset from render area (must be divided by 2) Matrix screenScale; // Matrix to scale screen (framebuffer rendering) + Point previousPosition; // Previous screen position (required on borderless windowed toggle) + Size previousScreen; // Previous screen size (required on borderless windowed toggle) char **dropFilepaths; // Store dropped files paths pointers (provided by GLFW) unsigned int dropFileCount; // Count dropped files strings @@ -1324,6 +1326,82 @@ void ToggleFullscreen(void) #endif } +// Toggle borderless windowed mode (only PLATFORM_DESKTOP) +void ToggleBorderlessWindowed(void) +{ +#if defined(PLATFORM_DESKTOP) + // Leave fullscreen before attempting to set borderless windowed mode and get screen position from it + bool wasOnFullscreen = false; + if (CORE.Window.fullscreen) + { + CORE.Window.previousPosition = CORE.Window.position; + ToggleFullscreen(); + wasOnFullscreen = true; + } + + const int monitor = GetCurrentMonitor(); + int monitorCount; + GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); + if ((monitor >= 0) && (monitor < monitorCount)) + { + const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]); + if (mode) + { + if (!IsWindowState(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 + if (!wasOnFullscreen) glfwGetWindowPos(CORE.Window.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y); + CORE.Window.previousScreen = CORE.Window.screen; + + // Set undecorated and topmost modes and flags + glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_FALSE); + CORE.Window.flags |= FLAG_WINDOW_UNDECORATED; + glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_TRUE); + CORE.Window.flags |= FLAG_WINDOW_TOPMOST; + + // Get monitor position and size + int monitorPosX = 0; + int monitorPosY = 0; + glfwGetMonitorPos(monitors[monitor], &monitorPosX, &monitorPosY); + const int monitorWidth = mode->width; + const int monitorHeight = mode->height; + glfwSetWindowSize(CORE.Window.handle, monitorWidth, monitorHeight); + + // Set screen position and size + glfwSetWindowPos(CORE.Window.handle, monitorPosX, monitorPosY); + glfwSetWindowSize(CORE.Window.handle, monitorWidth, monitorHeight); + + // Refocus window + glfwFocusWindow(CORE.Window.handle); + + CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE; + } + else + { + // Remove topmost and undecorated modes and flags + glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_FALSE); + CORE.Window.flags &= ~FLAG_WINDOW_TOPMOST; + glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_TRUE); + CORE.Window.flags &= ~FLAG_WINDOW_UNDECORATED; + + // 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 + glfwSetWindowSize(CORE.Window.handle, CORE.Window.previousScreen.width, CORE.Window.previousScreen.height); + glfwSetWindowPos(CORE.Window.handle, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y); + + // Refocus window + glfwFocusWindow(CORE.Window.handle); + + CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; + } + } + else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor"); + } + else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor"); +#endif +} + // Set window state: maximized, if resizable (only PLATFORM_DESKTOP) void MaximizeWindow(void) { @@ -1373,6 +1451,13 @@ void SetWindowState(unsigned int flags) CORE.Window.flags |= FLAG_VSYNC_HINT; } + // State change: FLAG_BORDERLESS_WINDOWED_MODE + // NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running + 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 ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) != (flags & FLAG_FULLSCREEN_MODE)) { @@ -1483,6 +1568,13 @@ void ClearWindowState(unsigned int flags) CORE.Window.flags &= ~FLAG_VSYNC_HINT; } + // State change: FLAG_BORDERLESS_WINDOWED_MODE + // NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running + 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 (((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) && ((flags & FLAG_FULLSCREEN_MODE) > 0)) { From 5b4aaf4eb1b848d023b3bac0ce7a8e34faab9ba1 Mon Sep 17 00:00:00 2001 From: ubkp <118854183+ubkp@users.noreply.github.com> Date: Thu, 3 Aug 2023 05:29:45 -0300 Subject: [PATCH 3/5] Adds CMake option for SUPPORT_CUSTOM_FRAME_CONTROL (#3221) --- CMakeOptions.txt | 1 + cmake/CompileDefinitions.cmake | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeOptions.txt b/CMakeOptions.txt index c643427c6..cc57a851f 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -46,6 +46,7 @@ cmake_dependent_option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing syn cmake_dependent_option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_WINMM_HIGHRES_TIMER "Setting a higher resolution can improve the accuracy of time-out intervals in wait functions" OFF CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_COMPRESSION_API "Support for compression API" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_CUSTOM_FRAME_CONTROL "Enabling this flag allows manual control of the frame processes, use at your own risk" OFF CUSTOMIZE_BUILD OFF) # rshapes.c cmake_dependent_option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON CUSTOMIZE_BUILD ON) diff --git a/cmake/CompileDefinitions.cmake b/cmake/CompileDefinitions.cmake index 749222455..689f98ac4 100644 --- a/cmake/CompileDefinitions.cmake +++ b/cmake/CompileDefinitions.cmake @@ -28,6 +28,7 @@ if (${CUSTOMIZE_BUILD}) define_if("raylib" SUPPORT_EVENTS_WAITING) define_if("raylib" SUPPORT_WINMM_HIGHRES_TIMER) define_if("raylib" SUPPORT_COMPRESSION_API) + define_if("raylib" SUPPORT_CUSTOM_FRAME_CONTROL) define_if("raylib" SUPPORT_QUADS_DRAW_MODE) define_if("raylib" SUPPORT_IMAGE_EXPORT) define_if("raylib" SUPPORT_IMAGE_GENERATION) @@ -69,17 +70,17 @@ if (${CUSTOMIZE_BUILD}) else () target_compile_definitions("raylib" PUBLIC "MAX_FILEPATH_LENGTH=512") endif () - + target_compile_definitions("raylib" PUBLIC "MAX_GAMEPADS=4") target_compile_definitions("raylib" PUBLIC "MAX_GAMEPAD_AXIS=8") target_compile_definitions("raylib" PUBLIC "MAX_GAMEPAD_BUTTONS=32") target_compile_definitions("raylib" PUBLIC "MAX_TOUCH_POINTS=10") target_compile_definitions("raylib" PUBLIC "MAX_KEY_PRESSED_QUEUE=16") - + target_compile_definitions("raylib" PUBLIC "STORAGE_DATA_FILE=\"storage.data\"") target_compile_definitions("raylib" PUBLIC "MAX_CHAR_PRESSED_QUEUE=16") target_compile_definitions("raylib" PUBLIC "MAX_DECOMPRESSION_SIZE=64") - + if (${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_33" OR ${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_11") target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_BUFFER_ELEMENTS=8192") elseif (${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES2") From d3058fe58972b80684591237c6358104f9e28ba0 Mon Sep 17 00:00:00 2001 From: vitopigno <103512727+VitusVeit@users.noreply.github.com> Date: Fri, 4 Aug 2023 12:04:19 +0200 Subject: [PATCH 4/5] [CORE] Support for SetWindowTitle and InitWindow for web (#3222) * Update raylib.h Changed SetWindowTitle's description * Update rcore.c SetWindowTitle now works on web * Update rcore.c InitWindow title now works with web platform too. --- src/raylib.h | 2 +- src/rcore.c | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 45a6120f5..8b5a80700 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -954,7 +954,7 @@ RLAPI void MinimizeWindow(void); // Set window RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP) RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) -RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP) +RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB) RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) diff --git a/src/rcore.c b/src/rcore.c index d5addad48..344e851f3 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -1736,13 +1736,16 @@ void SetWindowIcons(Image *images, int count) #endif } -// Set title for window (only PLATFORM_DESKTOP) +// Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB) void SetWindowTitle(const char *title) { CORE.Window.title = title; #if defined(PLATFORM_DESKTOP) glfwSetWindowTitle(CORE.Window.handle, title); #endif +#if defined(PLATFORM_WEB) + emscripten_set_window_title(title); +#endif } // Set window position on screen (windowed mode) @@ -4433,6 +4436,11 @@ static bool InitGraphicsDevice(int width, int height) return false; } +// glfwCreateWindow title doesn't work with emscripten. +#if defined(PLATFORM_WEB) + emscripten_set_window_title((CORE.Window.title != 0)? CORE.Window.title : " "); +#endif + // Set window callback events glfwSetWindowSizeCallback(CORE.Window.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default! #if !defined(PLATFORM_WEB) From 601cadbae6a7561d2114de891f374a2d9f2f497e Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Fri, 4 Aug 2023 07:40:10 -0700 Subject: [PATCH 5/5] [AUDIO] Add a function to make an alias of a sound and share it's sample data (#3219) * Add a function to clone a sound and share data with another sound. * rename items based on feedback * PR Feedback, use custom unload for sound alias, not variant of normal sound unloading --- src/raudio.c | 37 +++++++++++++++++++++++++++++++++++++ src/raylib.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/src/raudio.c b/src/raudio.c index 5e2ccf996..5f84688d9 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -916,6 +916,32 @@ Sound LoadSoundFromWave(Wave wave) return sound; } +// Clone sound from existing sound data, clone does not own wave data +// Wave data must +// NOTE: Wave data must be unallocated manually and will be shared across all clones +Sound LoadSoundAlias(Sound source) +{ + Sound sound = { 0 }; + + if (source.stream.buffer->data != NULL) + { + AudioBuffer* audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, source.frameCount, AUDIO_BUFFER_USAGE_STATIC); + if (audioBuffer == NULL) + { + TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer"); + return sound; // early return to avoid dereferencing the audioBuffer null pointer + } + audioBuffer->data = source.stream.buffer->data; + sound.frameCount = source.frameCount; + sound.stream.sampleRate = AUDIO.System.device.sampleRate; + sound.stream.sampleSize = 32; + sound.stream.channels = AUDIO_DEVICE_CHANNELS; + sound.stream.buffer = audioBuffer; + } + + return sound; +} + // Checks if a sound is ready bool IsSoundReady(Sound sound) { @@ -940,6 +966,17 @@ void UnloadSound(Sound sound) //TRACELOG(LOG_INFO, "SOUND: Unloaded sound data from RAM"); } +void UnloadSoundAlias(Sound alias) +{ + // untrack and unload just the sound buffer, not the sample data, it is shared with the source for the alias + if (alias.stream.buffer != NULL) + { + ma_data_converter_uninit(&alias.stream.buffer->converter, NULL); + UntrackAudioBuffer(alias.stream.buffer); + RL_FREE(alias.stream.buffer); + } +} + // Update sound buffer with new data void UpdateSound(Sound sound, const void *data, int sampleCount) { diff --git a/src/raylib.h b/src/raylib.h index 8b5a80700..a49e19a57 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1533,10 +1533,12 @@ RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileDat RLAPI bool IsWaveReady(Wave wave); // Checks if wave data is ready RLAPI Sound LoadSound(const char *fileName); // Load sound from file RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data +RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound +RLAPI void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data) RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success RLAPI bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success