Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
834ba36
Enable blank issues and clear contact links
riley-1995 Feb 10, 2026
68cf7f4
Add integration test infrastructure and vcpkg manifest feature handling
akleinecke Feb 18, 2026
137e5c8
Fix SDL2 include path handling and simplify test linkage
riley-1995 Feb 18, 2026
62b5d7b
CI: fix vcpkg nuget invocation in Windows workflow
riley-1995 Feb 18, 2026
19e68be
Modified to adjust to review suggestions.
akleinecke Feb 19, 2026
528e5a0
Merge pull request #11 from riley-1995/p1/issue-10-enable-googletest-…
riley-1995 Feb 19, 2026
c08fad5
Implement audio devices override v1
riley-1995 Feb 18, 2026
46f5161
Update tests/CMakeLists.txt to specify windows vs non windows audio c…
riley-1995 Feb 23, 2026
5a59ae8
Update List Audio Devices test to be more robust in checking listDevi…
riley-1995 Feb 24, 2026
c423370
Fixed error in ListAudioDevicesTest for redeclaring cfg by renaming v…
riley-1995 Feb 24, 2026
5ba7875
Merge pull request #9 from riley-1995/p1/issue-8-audio-devices-override
akleinecke Feb 24, 2026
94bf667
Update build check workflow to optimize for windows on forks via cach…
riley-1995 Feb 24, 2026
0079a94
Add integration render smoke test using glReadPixels.
akleinecke Feb 24, 2026
4e253d0
Update buildcheck windows: add file-based vcpkg binary cache for fork…
riley-1995 Feb 24, 2026
de9e4d1
Prepare vcpkg cache dir before attempting cache restore for forks
riley-1995 Feb 24, 2026
0380555
Merge pull request #14 from riley-1995/p1/issue-12-improve-windows-bu…
akleinecke Feb 24, 2026
ce05ff1
Adhere to peer review
akleinecke Feb 24, 2026
6634d1d
Merge pull request #13 from riley-1995/p1/issue-6-render-smoke-test
riley-1995 Feb 24, 2026
80e97e0
Update render test OpenGL import for Apple, silence depreciation warn…
riley-1995 Feb 24, 2026
95c8586
Merge pull request #15 from riley-1995/p1/issue-6-render-smoke-test
akleinecke Feb 24, 2026
13f2c42
Add integration test for CLI --help exit behavior
riley-1995 Feb 25, 2026
f96e156
Added support for windows specific help option
akleinecke Feb 25, 2026
e5f0936
Merge pull request #16 from riley-1995/p1/issue-3-cli-help-option-exits
akleinecke Feb 25, 2026
d728cf3
Added unit test for issue 2; Modified CMAKE files for issue 2
akleinecke Feb 25, 2026
7532a65
Merge pull request #19 from riley-1995/p1/issue-2-main-render-exits
riley-1995 Feb 26, 2026
375dc0b
Add Esc Overlay Toggle Test
riley-1995 Feb 26, 2026
ed58755
cmake: fix macOS link by adding OpenGL to projectMSDL
riley-1995 Feb 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
blank_issues_enabled: false
contact_links:
- name: Create new issue
url: https://github.com/projectM-visualizer/projectm/issues/new/choose
about: Please open new issues in the main projectM repository. We will then move the issue into the correct repository for you.
blank_issues_enabled: true
contact_links: []
93 changes: 78 additions & 15 deletions .github/workflows/buildcheck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ jobs:
USERNAME: projectM-visualizer
VCPKG_EXE: ${{ github.workspace }}/vcpkg/vcpkg
FEED_URL: https://nuget.pkg.github.com/projectM-visualizer/index.json
VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/projectM-visualizer/index.json,readwrite"


steps:
- name: Checkout vcpkg
Expand All @@ -108,24 +106,95 @@ jobs:
path: vcpkg
submodules: recursive

- name: Bootstrap vcpkg
# Capture the exact vcpkg repository commit being used.
# This ensures our cache key changes automatically if vcpkg itself is updated.
- name: Get vcpkg commit
id: vcpkg_rev
shell: pwsh
run: ${{ github.workspace }}/vcpkg/bootstrap-vcpkg.bat
run: |
$rev = (git -C "${{ github.workspace }}/vcpkg" rev-parse HEAD).Trim()
"rev=$rev" | Out-File -FilePath $env:GITHUB_OUTPUT -Append

# Checkout this repo before hashFiles() / manifest is referenced
- name: Checkout projectMSDL Sources
uses: actions/checkout@v4
with:
path: frontend-sdl2
submodules: recursive

- name: Prepare vcpkg binary cache dir (forks)
if: github.repository != 'projectM-visualizer/frontend-sdl-cpp'
shell: pwsh
run: |
$cacheDir = Join-Path $env:GITHUB_WORKSPACE "vcpkg-binary-cache"
New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null
Write-Host "Cache dir: $cacheDir"

# Restore fork cache (file-based binary cache persisted by actions/cache)
- name: Cache vcpkg binary cache (forks)
if: github.repository != 'projectM-visualizer/frontend-sdl-cpp'
uses: actions/cache@v4
with:
path: ${{ github.workspace }}\vcpkg-binary-cache
key: vcpkg-bincache-${{ runner.os }}-${{ steps.vcpkg_rev.outputs.rev }}-${{ hashFiles('frontend-sdl2/vcpkg.json', 'frontend-sdl2/vcpkg-configuration.json') }}
restore-keys: |
vcpkg-bincache-${{ runner.os }}-${{ steps.vcpkg_rev.outputs.rev }}-
vcpkg-bincache-${{ runner.os }}-

- name: Show if binary cache has contents (forks)
if: github.repository != 'projectM-visualizer/frontend-sdl-cpp'
shell: pwsh
run: |
$cacheDir = Join-Path $env:GITHUB_WORKSPACE "vcpkg-binary-cache"
if (Test-Path $cacheDir) {
Get-ChildItem -Recurse $cacheDir | Select-Object -First 30 FullName
} else {
Write-Host "Binary cache directory does not exist."
}

# Configure vcpkg binary cache behavior
- name: Configure vcpkg binary cache (upstream)
if: github.repository == 'projectM-visualizer/frontend-sdl-cpp'
shell: pwsh
run: |
Write-Host "Using NuGet binary cache (readwrite) for upstream repo"
"VCPKG_BINARY_SOURCES=clear;nuget,${{ env.FEED_URL }},readwrite" | Out-File -FilePath $env:GITHUB_ENV -Append

- name: Configure vcpkg binary cache (forks)
if: github.repository != 'projectM-visualizer/frontend-sdl-cpp'
shell: pwsh
run: |
Write-Host "Using local file-based binary cache (readwrite) for fork/PR"
$cacheDir = Join-Path $env:GITHUB_WORKSPACE "vcpkg-binary-cache"
"VCPKG_DEFAULT_BINARY_CACHE=$cacheDir" | Out-File -FilePath $env:GITHUB_ENV -Append
"VCPKG_BINARY_SOURCES=clear;files,$cacheDir,readwrite" | Out-File -FilePath $env:GITHUB_ENV -Append

# Upstream-only: authenticate to GitHub Packages NuGet feed
- name: Add NuGet sources
if: github.repository == 'projectM-visualizer/frontend-sdl-cpp'
env:
VCPKG_PACKAGES_TOKEN: ${{ secrets.VCPKG_PACKAGES_TOKEN }}
shell: pwsh
run: |
.$(${{ env.VCPKG_EXE }} fetch nuget) `
sources add `
if (-not $env:VCPKG_PACKAGES_TOKEN) {
Write-Host "VCPKG_PACKAGES_TOKEN not set; skipping NuGet auth."
exit 0
}

$nuget = (& "${{ env.VCPKG_EXE }}" fetch nuget | Select-Object -Last 1).Trim()
& $nuget sources add `
-Source "${{ env.FEED_URL }}" `
-StorePasswordInClearText `
-Name GitHubPackages `
-UserName "${{ env.USERNAME }}" `
-Password "${{ secrets.VCPKG_PACKAGES_TOKEN }}"
.$(${{ env.VCPKG_EXE }} fetch nuget) `
setapikey "${{ secrets.VCPKG_PACKAGES_TOKEN }}" `
-Password "$env:VCPKG_PACKAGES_TOKEN"
& $nuget setapikey "$env:VCPKG_PACKAGES_TOKEN" `
-Source "${{ env.FEED_URL }}"

- name: Bootstrap vcpkg
shell: pwsh
run: ${{ github.workspace }}/vcpkg/bootstrap-vcpkg.bat

- name: Checkout libprojectM Sources
uses: actions/checkout@v4
with:
Expand All @@ -140,12 +209,6 @@ jobs:
cmake --build "${{ github.workspace }}/cmake-build-libprojectm" --config Release --parallel
cmake --install "${{ github.workspace }}/cmake-build-libprojectm" --config Release

- name: Checkout projectMSDL Sources
uses: actions/checkout@v4
with:
path: frontend-sdl2
submodules: recursive

- name: Build projectMSDL
run: |
mkdir cmake-build-frontend-sdl2
Expand Down
28 changes: 21 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@ set(CMAKE_POSITION_INDEPENDENT_CODE YES)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

project(projectMSDL
LANGUAGES C CXX
VERSION 2.0.0
)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

option(ENABLE_FLAT_PACKAGE "Creates a \"flat\" install layout with the executable, configuration file(s) and preset/texture dirs directly in the install prefix." OFF)
option(ENABLE_INSTALL_BDEPS "Installs all shared libraries projectMSDL requires to run. On some platforms, CMake 3.31 or higher is required for this to work!" OFF)

# Added option display to cmake build to allow testing
option(BUILD_TESTING "Build the frontend-sdl2 ctests" OFF)

# Enable vcpkg manifest features according to build options (just like the projectm backend)
if(BUILD_TESTING)
list(APPEND VCPKG_MANIFEST_FEATURES test)
endif()

# Moved below options to allow using options
project(projectMSDL
LANGUAGES C CXX
VERSION 2.0.0
)

set(PROJECTMSDL_PROPERTIES_FILENAME "projectMSDL.properties")

if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT ENABLE_FLAT_PACKAGE)
Expand Down Expand Up @@ -114,8 +123,10 @@ include(ImGui.cmake)

add_subdirectory(src)

if(ENABLE_TESTING)
add_subdirectory(test)
# Adjusted testing build from existing code
if(BUILD_TESTING)
enable_testing()
add_subdirectory(tests)
endif()

include(install.cmake)
Expand All @@ -135,3 +146,6 @@ message(STATUS "The projectMSDL binary will look for the following hard-coded pa
message(STATUS " Configuration file: ${DEFAULT_CONFIG_PATH}")
message(STATUS " Presets: ${DEFAULT_PRESETS_PATH}")
message(STATUS " Textures: ${DEFAULT_TEXTURES_PATH}")
# Added testing message
message(STATUS "=============================================")
message(STATUS " Tests: ${BUILD_TESTING}")
34 changes: 22 additions & 12 deletions cmake/SDL2Target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,30 @@ if(NOT TARGET SDL2::SDL2)
endif()

# Temporary fix to deal with wrong include dir set by SDL2's CMake configuration.
get_target_property(_SDL2_INCLUDE_DIR SDL2::SDL2 INTERFACE_INCLUDE_DIRECTORIES)
if(_SDL2_INCLUDE_DIR MATCHES "(.+)/SDL2\$" AND _SDL2_TARGET_TYPE STREQUAL STATIC_LIBRARY)
# Check if SDL2::SDL2 is aliased to SDL2::SDL2-static (will be the case for static-only builds)
get_target_property(_SDL2_ALIASED_TARGET SDL2::SDL2 ALIASED_TARGET)
if(_SDL2_ALIASED_TARGET)
set(_sdl2_target ${_SDL2_ALIASED_TARGET})
else()
set(_sdl2_target SDL2::SDL2)
endif()
# Some SDL2 configs incorrectly report .../include/SDL2 instead of .../include.
get_target_property(_SDL2_INCLUDE_DIRS SDL2::SDL2 INTERFACE_INCLUDE_DIRECTORIES)

if(_SDL2_INCLUDE_DIRS)
# The property can be a list, so handle each entry.
foreach(_dir IN LISTS _SDL2_INCLUDE_DIRS)
if(_dir MATCHES "(.+)/SDL2$")
set(_fixed_parent "${CMAKE_MATCH_1}")

# If SDL2::SDL2 is an alias, patch the real target.
get_target_property(_SDL2_ALIASED_TARGET SDL2::SDL2 ALIASED_TARGET)
if(_SDL2_ALIASED_TARGET)
set(_sdl2_target "${_SDL2_ALIASED_TARGET}")
else()
set(_sdl2_target SDL2::SDL2)
endif()

message(STATUS "SDL2 include dir contains \"SDL2\" subdir (SDL bug #4004) - fixing to \"${CMAKE_MATCH_1}\".")
set_target_properties(${_sdl2_target} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_MATCH_1}"
message(STATUS "SDL2 include dir contains \"SDL2\" subdir - fixing to \"${_fixed_parent}\".")
set_target_properties(${_sdl2_target} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_fixed_parent}"
)
break()
endif()
endforeach()
endif()

if(SDL2_VERSION AND SDL2_VERSION VERSION_LESS "2.0.5")
Expand Down
10 changes: 10 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ set(PROJECTM_CONFIGURATION_FILE "${CMAKE_CURRENT_BINARY_DIR}/projectMSDL.propert
set(PROJECTM_CONFIGURATION_FILE "${PROJECTM_CONFIGURATION_FILE}" PARENT_SCOPE)
configure_file(resources/projectMSDL.properties.in "${PROJECTM_CONFIGURATION_FILE}" @ONLY)

find_package(OpenGL REQUIRED)

add_executable(projectMSDL WIN32 MACOSX_BUNDLE
AudioCapture.cpp
AudioCapture.h
Expand Down Expand Up @@ -82,6 +84,14 @@ target_link_libraries(projectMSDL
SDL2::SDL2main
)

if (TARGET OpenGL::GL)
target_link_libraries(projectMSDL PRIVATE OpenGL::GL)
elseif (TARGET OpenGL::OpenGL)
target_link_libraries(projectMSDL PRIVATE OpenGL::OpenGL)
else()
message(FATAL_ERROR "No OpenGL CMake target found.")
endif()

if (MSVC)
set_target_properties(projectMSDL
PROPERTIES
Expand Down
Empty file removed test/CMakeLists.txt
Empty file.
132 changes: 132 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# ======
# Test-only core library
# (Eventually this should be moved into src/CMakeLists.txt to avoid
# duplicating source lists and dependancies.)
# ======

# Build a core library from production sources to test on
add_library(projectMSDL_testcorelib
# Add .cpp files as needed for testing
# Examples:
# ${PROJECT_SOURCE_DIR}/src/SDLRenderingWindow.cpp
# ${PROJECT_SOURCE_DIR}/src/RenderLoop.cpp
# ${PROJECT_SOURCE_DIR}/src/ProjectMWrapper.cpp
# For now, we'll include a simple file just so this thing works. It can be removed if unneeded later.
${PROJECT_SOURCE_DIR}/src/FPSLimiter.cpp
${PROJECT_SOURCE_DIR}/src/ProjectMSDLApplication.cpp
${PROJECT_SOURCE_DIR}/src/RenderLoop.cpp
${PROJECT_SOURCE_DIR}/src/ProjectMWrapper.cpp
${PROJECT_SOURCE_DIR}/src/SDLRenderingWindow.cpp
${PROJECT_SOURCE_DIR}/src/AudioCapture.cpp
)

if (WIN32)
target_sources(projectMSDL_testcorelib PRIVATE
${PROJECT_SOURCE_DIR}/src/AudioCaptureImpl_WASAPI.cpp
)
target_compile_definitions(projectMSDL_testcorelib PRIVATE
AUDIO_IMPL_HEADER="AudioCaptureImpl_WASAPI.h"
USE_GLEW
)
else()
target_sources(projectMSDL_testcorelib PRIVATE
${PROJECT_SOURCE_DIR}/src/AudioCaptureImpl_SDL.cpp
)
target_compile_definitions(projectMSDL_testcorelib PRIVATE
AUDIO_IMPL_HEADER="AudioCaptureImpl_SDL.h"
)
endif()

# Headers from the production source tree
target_include_directories(projectMSDL_testcorelib
PUBLIC
${PROJECT_SOURCE_DIR}/src
)

# Compile definitions that are commonly referenced
target_compile_definitions(projectMSDL_testcorelib
PRIVATE
PROJECTMSDL_CONFIG_LOCATION="${DEFAULT_CONFIG_PATH}"
PROJECTMSDL_VERSION="${PROJECT_VERSION}"
)

# Linker set (add to this only when the linker asks)
target_link_libraries(projectMSDL_testcorelib
PRIVATE
SDL2::SDL2
Poco::Util
Poco::Foundation
ProjectMSDL-GUI
ProjectMSDL-Notifications
libprojectM::playlist
)

# ======
# Test-only core library WITHOUT RenderLoop
# ======

# Build a core library from production sources to test on
add_library(projectMSDL_testcorelib_norenderloop
# Add .cpp files as needed for testing
# Examples:
# ${PROJECT_SOURCE_DIR}/src/SDLRenderingWindow.cpp
# ${PROJECT_SOURCE_DIR}/src/RenderLoop.cpp
# ${PROJECT_SOURCE_DIR}/src/ProjectMWrapper.cpp
# For now, we'll include a simple file just so this thing works. It can be removed if unneeded later.
${PROJECT_SOURCE_DIR}/src/FPSLimiter.cpp
${PROJECT_SOURCE_DIR}/src/ProjectMSDLApplication.cpp
${PROJECT_SOURCE_DIR}/src/ProjectMWrapper.cpp
${PROJECT_SOURCE_DIR}/src/SDLRenderingWindow.cpp
${PROJECT_SOURCE_DIR}/src/AudioCapture.cpp
)

if (WIN32)
target_sources(projectMSDL_testcorelib_norenderloop PRIVATE
${PROJECT_SOURCE_DIR}/src/AudioCaptureImpl_WASAPI.cpp
)
target_compile_definitions(projectMSDL_testcorelib_norenderloop PRIVATE
AUDIO_IMPL_HEADER="AudioCaptureImpl_WASAPI.h"
USE_GLEW
)
else()
target_sources(projectMSDL_testcorelib_norenderloop PRIVATE
${PROJECT_SOURCE_DIR}/src/AudioCaptureImpl_SDL.cpp
)
target_compile_definitions(projectMSDL_testcorelib_norenderloop PRIVATE
AUDIO_IMPL_HEADER="AudioCaptureImpl_SDL.h"
)
endif()

# Headers from the production source tree
target_include_directories(projectMSDL_testcorelib_norenderloop
PUBLIC
${PROJECT_SOURCE_DIR}/src
)

# Compile definitions that are commonly referenced
target_compile_definitions(projectMSDL_testcorelib_norenderloop
PRIVATE
PROJECTMSDL_CONFIG_LOCATION="${DEFAULT_CONFIG_PATH}"
PROJECTMSDL_VERSION="${PROJECT_VERSION}"
)

# Linker set (add to this only when the linker asks)
target_link_libraries(projectMSDL_testcorelib_norenderloop
PRIVATE
SDL2::SDL2
Poco::Util
Poco::Foundation
ProjectMSDL-GUI
ProjectMSDL-Notifications
libprojectM::playlist
)

# ======
# Actual test subdirs
# Add to this when defining more testing directories
# (To be kept in this file after integration of above code into src/CMakeLists.txt)
# ======
add_subdirectory(renderer)
add_subdirectory(audio)
add_subdirectory(cli)
add_subdirectory(ui)
Loading
Loading