Skip to content

Commit f5170f1

Browse files
authored
Merge branch 'master' into feature/playlist-preset-callback-946
2 parents 219ad1d + 85b8c08 commit f5170f1

67 files changed

Lines changed: 881 additions & 4925 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build_linux.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ jobs:
6464
-DCMAKE_VERBOSE_MAKEFILE=YES \
6565
-DBUILD_SHARED_LIBS="${shared_libs}" \
6666
-DENABLE_BOOST_FILESYSTEM="${use_boost}" \
67+
-DENABLE_CXX_INTERFACE=YES \
6768
-DBUILD_TESTING=YES
6869
6970
- name: Build Debug
@@ -80,6 +81,16 @@ jobs:
8081
cmake --build "${{ github.workspace }}/cmake-build" --config "Debug" --target install
8182
cmake --build "${{ github.workspace }}/cmake-build" --config "Release" --target install
8283
84+
- name: Test C++ Interface
85+
run: |
86+
cmake -G "Ninja Multi-Config" \
87+
-S "${{ github.workspace }}/tests/cxx-interface" \
88+
-B "${{ github.workspace }}/cmake-build-cxx-api" \
89+
-DCMAKE_PREFIX_PATH="${{ github.workspace }}/install"
90+
91+
cmake --build "${{ github.workspace }}/cmake-build-cxx-api" --config "Debug"
92+
cmake --build "${{ github.workspace }}/cmake-build-cxx-api" --config "Release"
93+
8394
- name: Upload Artifact
8495
uses: actions/upload-artifact@v4
8596
with:

.github/workflows/build_osx.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ jobs:
6565
-DBUILD_SHARED_LIBS="${shared_libs}" \
6666
-DENABLE_BOOST_FILESYSTEM="${use_boost}" \
6767
-DCMAKE_OSX_ARCHITECTURES="${{ matrix.arch }}" \
68+
-DENABLE_CXX_INTERFACE=YES \
6869
-DBUILD_TESTING=YES
6970
7071
- name: Build Debug
@@ -81,6 +82,17 @@ jobs:
8182
cmake --build "${{ github.workspace }}/cmake-build" --config "Debug" --target install
8283
cmake --build "${{ github.workspace }}/cmake-build" --config "Release" --target install
8384
85+
- name: Test C++ Interface
86+
run: |
87+
cmake -G "Ninja Multi-Config" \
88+
-S "${{ github.workspace }}/tests/cxx-interface" \
89+
-B "${{ github.workspace }}/cmake-build-cxx-api" \
90+
-DCMAKE_OSX_ARCHITECTURES="${{ matrix.arch }}" \
91+
-DCMAKE_PREFIX_PATH="${{ github.workspace }}/install"
92+
93+
cmake --build "${{ github.workspace }}/cmake-build-cxx-api" --config "Debug"
94+
cmake --build "${{ github.workspace }}/cmake-build-cxx-api" --config "Release"
95+
8496
- name: Upload Artifact
8597
uses: actions/upload-artifact@v4
8698
with:

.github/workflows/build_windows.yml

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ jobs:
9696
-DCMAKE_VERBOSE_MAKEFILE=YES `
9797
-DBUILD_SHARED_LIBS="$($shared_libs)" `
9898
-DENABLE_BOOST_FILESYSTEM="$($use_boost)" `
99-
-DBUILD_TESTING=YES
99+
-DENABLE_CXX_INTERFACE=YES `
100+
-DBUILD_TESTING=YES `
101+
-DCMAKE_VERBOSE_MAKEFILE=ON
100102
101103
- name: Build Debug
102104
run: cmake --build "${{ github.workspace }}/cmake-build" --config "Debug" --parallel
@@ -112,6 +114,39 @@ jobs:
112114
cmake --build "${{ github.workspace }}/cmake-build" --config "Debug" --target INSTALL
113115
cmake --build "${{ github.workspace }}/cmake-build" --config "Release" --target INSTALL
114116
117+
- name: Test C++ Interface
118+
run: |
119+
if("${{ matrix.fslib }}" -eq "boost") {
120+
$use_boost = "ON"
121+
} else {
122+
$use_boost = "OFF"
123+
}
124+
if("${{ matrix.arch }}" -eq "X64") {
125+
$triplet = "x64-windows"
126+
} else {
127+
$triplet = "x86-windows"
128+
}
129+
if("${{ matrix.libs }}" -eq "shared") {
130+
$runtime = "DLL"
131+
} else {
132+
$runtime = ""
133+
$triplet = $triplet + "-static"
134+
}
135+
136+
cmake -G "Visual Studio 17 2022" `
137+
-A "${{ matrix.arch }}" `
138+
-S "${{ github.workspace }}/tests/cxx-interface" `
139+
-B "${{ github.workspace }}/cmake-build-cxx-api" `
140+
-DCMAKE_PREFIX_PATH="${{ github.workspace }}/install" `
141+
-DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>$($runtime)" `
142+
-DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" `
143+
-DVCPKG_TARGET_TRIPLET="$($triplet)" `
144+
-DENABLE_BOOST_FILESYSTEM="$($use_boost)" `
145+
-DCMAKE_VERBOSE_MAKEFILE=ON
146+
147+
cmake --build "${{ github.workspace }}/cmake-build-cxx-api" --config "Debug"
148+
cmake --build "${{ github.workspace }}/cmake-build-cxx-api" --config "Release"
149+
115150
- name: Upload Artifact
116151
uses: actions/upload-artifact@v4
117152
with:

CMakeLists.txt

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ endif()
9797
cmake_dependent_option(BUILD_SHARED_LIBS "Build and install libprojectM as a shared libraries. If OFF, builds as static libraries." ON "NOT ENABLE_EMSCRIPTEN" OFF)
9898
cmake_dependent_option(ENABLE_GLES "Enable OpenGL ES support" OFF "NOT ENABLE_EMSCRIPTEN AND NOT CMAKE_SYSTEM_NAME STREQUAL Android" ON)
9999
cmake_dependent_option(ENABLE_INSTALL "Enable installing projectM libraries and headers." OFF "NOT PROJECT_IS_TOP_LEVEL" ON)
100+
cmake_dependent_option(ENABLE_MACOS_FRAMEWORK "Build as macOS Framework bundles instead of plain shared libraries." OFF "CMAKE_SYSTEM_NAME STREQUAL Darwin AND BUILD_SHARED_LIBS" OFF)
100101

101102
# Experimental/unsupported features
102103
option(ENABLE_CXX_INTERFACE "Enable exporting C++ symbols for ProjectM and PCM classes, not only the C API. Warning: This is not very portable." OFF)
@@ -199,16 +200,6 @@ else()
199200
endif()
200201
endif()
201202

202-
if(ENABLE_CXX_INTERFACE)
203-
set(CMAKE_C_VISIBILITY_PRESET default)
204-
set(CMAKE_CXX_VISIBILITY_PRESET default)
205-
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
206-
else()
207-
set(CMAKE_C_VISIBILITY_PRESET hidden)
208-
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
209-
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
210-
endif()
211-
212203
# Disable trace/debug logging in release builds unless explicitly requested
213204
add_compile_definitions(
214205
$<$<OR:$<CONFIG:Debug>,$<BOOL:${ENABLE_VERBOSE_LOGGING}>>:ENABLE_DEBUG_LOGGING>
@@ -278,6 +269,7 @@ if(ENABLE_SDL_UI)
278269
message(STATUS " SDL2 version: ${SDL2_VERSION}")
279270
endif()
280271
message(STATUS " OpenGL ES: ${ENABLE_GLES}")
272+
message(STATUS " macOS Framework: ${ENABLE_MACOS_FRAMEWORK}")
281273
message(STATUS " Emscripten: ${ENABLE_EMSCRIPTEN}")
282274
if(CMAKE_SYSTEM_NAME STREQUAL Emscripten)
283275
message(STATUS " - PThreads: ${USE_PTHREADS}")

src/api/CMakeLists.txt

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,35 @@ generate_export_header(projectM_api
1111
EXPORT_FILE_NAME "${PROJECTM_EXPORT_HEADER}"
1212
)
1313

14+
# Always generate the header, but we only install it if the C++ interface is actually enabled.
15+
set(PROJECTM_CXX_EXPORT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/include/projectM-4/projectM_cxx_export.h")
16+
17+
generate_export_header(projectM_api
18+
BASE_NAME projectM_CXX
19+
EXPORT_FILE_NAME "${PROJECTM_CXX_EXPORT_HEADER}"
20+
)
21+
1422
set(PROJECTM_PUBLIC_HEADERS
1523
"${PROJECTM_EXPORT_HEADER}"
1624
"${CMAKE_CURRENT_BINARY_DIR}/include/projectM-4/version.h"
17-
include/projectM-4/audio.h
18-
include/projectM-4/callbacks.h
19-
include/projectM-4/core.h
20-
include/projectM-4/debug.h
21-
include/projectM-4/logging.h
22-
include/projectM-4/memory.h
23-
include/projectM-4/parameters.h
24-
include/projectM-4/projectM.h
25-
include/projectM-4/render_opengl.h
26-
include/projectM-4/touch.h
27-
include/projectM-4/types.h
28-
include/projectM-4/user_sprites.h
25+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/audio.h"
26+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/callbacks.h"
27+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/core.h"
28+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/debug.h"
29+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/logging.h"
30+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/memory.h"
31+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/parameters.h"
32+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/projectM.h"
33+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/render_opengl.h"
34+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/touch.h"
35+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/types.h"
36+
"${CMAKE_CURRENT_SOURCE_DIR}/include/projectM-4/user_sprites.h"
2937
)
3038

39+
if(ENABLE_CXX_INTERFACE)
40+
list(APPEND PROJECTM_PUBLIC_HEADERS ${PROJECTM_CXX_EXPORT_HEADER})
41+
endif()
42+
3143
target_sources(projectM_api
3244
PRIVATE
3345
${PROJECTM_PUBLIC_HEADERS}
@@ -46,6 +58,14 @@ target_include_directories(projectM_api
4658
"$<INSTALL_INTERFACE:${PROJECTM_INCLUDE_DIR}>"
4759
)
4860

61+
if(NOT BUILD_SHARED_LIBS)
62+
target_compile_definitions(projectM_api
63+
INTERFACE
64+
PROJECTM_STATIC_DEFINE
65+
PROJECTM_CXX_STATIC_DEFINE
66+
)
67+
endif()
68+
4969
add_library(libprojectM::API ALIAS projectM_api)
5070

5171

src/api/include/projectM-4/callbacks.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,79 @@ PROJECTM_EXPORT void projectm_set_preset_switch_failed_event_callback(projectm_h
8888
projectm_preset_switch_failed_event callback,
8989
void* user_data);
9090

91+
/**
92+
* @brief Structure containing texture data returned by the texture load callback.
93+
*
94+
* Applications can provide texture data in one of two ways:
95+
* 1. Raw pixel data: Set data to a valid pointer, width/height to the dimensions,
96+
* and channels to the number of color channels (3 for RGB, 4 for RGBA).
97+
* 2. Existing OpenGL texture: Set texture_id to a valid OpenGL texture ID.
98+
*
99+
* If both are provided, the texture_id takes precedence.
100+
* If neither is provided (data is NULL and texture_id is 0), projectM will
101+
* attempt to load the texture from the filesystem.
102+
*
103+
* @warning When providing a texture_id, projectM takes ownership of the OpenGL texture
104+
* and will delete it (via glDeleteTextures) when it is no longer needed. Do not
105+
* delete the texture yourself or reuse the texture ID after passing it here.
106+
*
107+
* @since 4.2.0
108+
*/
109+
typedef struct projectm_texture_load_data {
110+
const unsigned char* data; /**< Pointer to raw pixel data in standard OpenGL format (first row is bottom of image). Can be NULL. */
111+
unsigned int width; /**< Width of the texture in pixels. Must be > 0 when providing data or texture_id. */
112+
unsigned int height; /**< Height of the texture in pixels. Must be > 0 when providing data or texture_id. */
113+
unsigned int channels; /**< Number of color channels (3 for RGB, 4 for RGBA). */
114+
unsigned int texture_id; /**< An existing OpenGL texture ID to use. Set to 0 if not used. */
115+
} projectm_texture_load_data;
116+
117+
/**
118+
* @brief Callback function that is executed when projectM needs to load a texture.
119+
*
120+
* This callback allows applications to provide textures from sources other than
121+
* the filesystem, such as:
122+
* - Loading textures from archives (e.g., ZIP files)
123+
* - Loading textures over the network
124+
* - Generating textures procedurally
125+
* - Providing pre-loaded textures or video frames
126+
*
127+
* When called, the application should populate the provided data structure with
128+
* either raw pixel data or an OpenGL texture ID. If the application cannot provide
129+
* the requested texture, it should leave the structure unchanged (data = NULL,
130+
* texture_id = 0) and projectM will fall back to loading from the filesystem.
131+
*
132+
* @note The texture_name pointer is only valid inside the callback. Make a copy if
133+
* it needs to be retained for later use.
134+
* @note If providing raw pixel data, the data pointer must remain valid until
135+
* projectM has finished processing it (i.e., until the callback returns).
136+
* @note This callback is always invoked from the same thread that calls projectM
137+
* rendering functions. No additional synchronization is required.
138+
*
139+
* @param texture_name The name of the texture being requested, as used in the preset.
140+
* @param[out] data Pointer to a structure where the application should place texture data.
141+
* @param user_data A user-defined data pointer that was provided when registering the callback.
142+
* @since 4.2.0
143+
*/
144+
typedef void (*projectm_texture_load_event)(const char* texture_name,
145+
projectm_texture_load_data* data,
146+
void* user_data);
147+
148+
/**
149+
* @brief Sets a callback function that will be called when projectM needs to load a texture.
150+
*
151+
* This allows applications to provide textures from non-filesystem sources.
152+
* Only one callback can be registered per projectM instance. To remove the callback, use NULL.
153+
*
154+
* @param instance The projectM instance handle.
155+
* @param callback A pointer to the callback function.
156+
* @param user_data A pointer to any data that will be sent back in the callback, e.g. context
157+
* information.
158+
* @since 4.2.0
159+
*/
160+
PROJECTM_EXPORT void projectm_set_texture_load_event_callback(projectm_handle instance,
161+
projectm_texture_load_event callback,
162+
void* user_data);
163+
91164
#ifdef __cplusplus
92165
} // extern "C"
93166
#endif

src/libprojectM/Audio/CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,18 @@ target_include_directories(Audio
2020
target_link_libraries(Audio
2121
PUBLIC
2222
libprojectM::API
23-
)
23+
)
24+
25+
if(BUILD_SHARED_LIBS)
26+
if(ENABLE_CXX_INTERFACE)
27+
target_compile_definitions(Audio
28+
PRIVATE
29+
projectM_api_EXPORTS
30+
)
31+
else()
32+
target_compile_definitions(Audio
33+
PRIVATE
34+
PROJECTM_CXX_STATIC_DEFINE
35+
)
36+
endif()
37+
endif()

src/libprojectM/Audio/FrameAudioData.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88

99
#include "Audio/AudioConstants.hpp"
1010

11-
#include <projectM-4/projectM_export.h>
11+
#include <projectM-4/projectM_cxx_export.h>
1212

1313
#include <array>
1414

1515
namespace libprojectM {
1616
namespace Audio {
1717

18-
class PROJECTM_EXPORT FrameAudioData
18+
class PROJECTM_CXX_EXPORT FrameAudioData
1919
{
2020
public:
2121
float bass{0.f};

src/libprojectM/Audio/Loudness.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#include "Audio/AudioConstants.hpp"
99

10+
#include <projectM-4/projectM_cxx_export.h>
11+
1012
#include <array>
1113
#include <cstdint>
1214

@@ -16,14 +18,14 @@ namespace Audio {
1618
/**
1719
* @brief Calculates beat-detection loudness relative to the previous frame(s).
1820
*/
19-
class Loudness
21+
class PROJECTM_CXX_EXPORT Loudness
2022
{
2123
public:
2224
/**
2325
* @brief Frequency bands.
2426
* Only the first half of the spectrum is used for these bands, each using one third of this half.
2527
*/
26-
enum class Band : int
28+
enum class Band : std::uint8_t
2729
{
2830
Bass = 0, //!< Bass band (first sixth of the spectrum)
2931
Middles = 1, //!< Middles band (second sixth of the spectrum)
@@ -76,7 +78,7 @@ class Loudness
7678
void UpdateBandAverage(double secondsSinceLastFrame, uint32_t frame);
7779

7880
/**
79-
* @brief Adjusts the dampening rate according the the current FPS.
81+
* @brief Adjusts the dampening rate according to the current FPS.
8082
* @param rate The rate to be dampened.
8183
* @param secondsSinceLastFrame (Fractional) seconds passed since the last frame.
8284
* @return The dampened rate value.

src/libprojectM/Audio/MilkdropFFT.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2929

3030
#pragma once
3131

32+
#include <projectM-4/projectM_cxx_export.h>
33+
3234
#include <complex>
35+
#include <cstddef>
3336
#include <vector>
3437

3538
namespace libprojectM {
@@ -40,7 +43,7 @@ namespace Audio {
4043
* Also applies an equalizer pattern with an envelope curve to the resulting data to smooth out
4144
* certain artifacts.
4245
*/
43-
class MilkdropFFT
46+
class PROJECTM_CXX_EXPORT MilkdropFFT
4447
{
4548
public:
4649
/**

0 commit comments

Comments
 (0)