blob: b7c175b0d89c8a79dd46e928f8877c18cc670740 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
|
cmake_minimum_required(VERSION 3.16)
project(demo64k LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#-- - Configuration Options -- -
option(DEMO_SIZE_OPT "Enable size optimization flags" OFF)
option(DEMO_STRIP_ALL "Strip all unnecessary code for final build" OFF)
option(DEMO_BUILD_TESTS "Build tests" OFF)
option(DEMO_BUILD_TOOLS "Build tools" OFF)
option(DEMO_ENABLE_COVERAGE "Enable code coverage generation (macOS only)" OFF)
option(DEMO_ALL_OPTIONS "Activate all options at once" OFF)
if (DEMO_ALL_OPTIONS)
set(DEMO_SIZE_OPT ON)
set(DEMO_STRIP_ALL ON)
set(DEMO_BUILD_TESTS ON)
set(DEMO_BUILD_TOOLS ON)
endif()
if (DEMO_STRIP_ALL)
add_definitions(-DSTRIP_ALL)
set(DEMO_SIZE_OPT ON)
endif()
if (DEMO_ENABLE_COVERAGE AND APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
# Coverage requires debug info
set(CMAKE_BUILD_TYPE Debug)
endif()
#-- - Platform Detection and Core Setup -- -
if(APPLE)
add_definitions(-DGLFW_EXPOSE_NATIVE_COCOA)
elseif(WIN32)
add_definitions(-DGLFW_EXPOSE_NATIVE_WIN32)
elseif(UNIX)
if(DEFINED CMAKE_USE_WAYLAND)
add_definitions(-DGLFW_EXPOSE_NATIVE_WAYLAND)
else()
add_definitions(-DGLFW_EXPOSE_NATIVE_X11)
endif()
endif()
#-- - Dependencies & Includes -- -
set(CORE_INCLUDES src third_party)
if (DEMO_CROSS_COMPILE_WIN32)
add_definitions(-DDEMO_CROSS_COMPILE_WIN32)
set(WINDOWS_DEPS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/windows")
set(WGPU_INCLUDE_DIR "${WINDOWS_DEPS_DIR}/include")
set(WGPU_LIBRARY "${WINDOWS_DEPS_DIR}/lib/libwgpu_native.dll.a")
set(GLFW3_INCLUDE_DIR "${WINDOWS_DEPS_DIR}/include")
set(GLFW3_LIBRARY "${WINDOWS_DEPS_DIR}/lib/libglfw3.a")
list(APPEND CORE_INCLUDES ${WGPU_INCLUDE_DIR} ${WGPU_INCLUDE_DIR}/webgpu ${GLFW3_INCLUDE_DIR})
set(DEMO_LIBS ${GLFW3_LIBRARY} ${WGPU_LIBRARY} -lgdi32 -lws2_32 -luser32 -lkernel32 -lshell32 -ladvapi32 -ldwmapi)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
else()
find_library(WGPU_LIBRARY NAMES wgpu_native libwgpu_native REQUIRED)
find_path(WGPU_ROOT_INCLUDE_DIR NAMES wgpu.h REQUIRED)
list(APPEND CORE_INCLUDES ${WGPU_ROOT_INCLUDE_DIR} ${WGPU_ROOT_INCLUDE_DIR}/webgpu-headers)
find_package(glfw3 REQUIRED)
set(DEMO_LIBS glfw ${WGPU_LIBRARY})
endif()
list(APPEND CORE_INCLUDES third_party/glfw3webgpu)
include_directories(${CORE_INCLUDES})
if (APPLE)
set_source_files_properties(src/platform.cc third_party/glfw3webgpu/glfw3webgpu.c PROPERTIES COMPILE_FLAGS "-x objective-c++")
list(APPEND DEMO_LIBS "-framework Metal" "-framework Foundation" "-framework Cocoa" "-framework QuartzCore")
elseif (NOT DEMO_CROSS_COMPILE_WIN32)
list(APPEND DEMO_LIBS pthread m dl)
endif()
#-- - Source Groups -- -
set(AUDIO_SOURCES src/audio/audio.cc src/audio/miniaudio_backend.cc src/audio/gen.cc src/audio/fdct.cc src/audio/idct.cc src/audio/window.cc src/audio/synth.cc src/audio/tracker.cc)
set(PROCEDURAL_SOURCES src/procedural/generator.cc)
set(GPU_SOURCES
src/gpu/gpu.cc
src/gpu/effect.cc
src/gpu/effects/heptagon_effect.cc
src/gpu/effects/particles_effect.cc
src/gpu/effects/passthrough_effect.cc
src/gpu/effects/moving_ellipse_effect.cc
src/gpu/effects/particle_spray_effect.cc
src/gpu/effects/gaussian_blur_effect.cc
src/gpu/effects/solarize_effect.cc
src/gpu/effects/distort_effect.cc
src/gpu/effects/chroma_aberration_effect.cc
src/gpu/effects/post_process_helper.cc
src/gpu/effects/shaders.cc
src/gpu/effects/hybrid_3d_effect.cc
src/gpu/effects/shader_composer.cc
src/gpu/texture_manager.cc
)
set(3D_SOURCES
src/3d/renderer.cc
src/3d/visual_debug.cc
)
set(PLATFORM_SOURCES src/platform.cc third_party/glfw3webgpu/glfw3webgpu.c)
set(UTIL_SOURCES src/util/asset_manager.cc)
#-- - Subsystem Libraries -- -
add_library(util STATIC ${UTIL_SOURCES})
add_dependencies(util generate_demo_assets generate_test_assets)
add_library(procedural STATIC ${PROCEDURAL_SOURCES})
add_library(audio STATIC ${AUDIO_SOURCES})
add_library(3d STATIC ${3D_SOURCES})
add_library(gpu STATIC ${GPU_SOURCES})
target_include_directories(util PUBLIC ${CORE_INCLUDES})
target_include_directories(procedural PUBLIC ${CORE_INCLUDES})
target_include_directories(audio PUBLIC ${CORE_INCLUDES})
target_include_directories(3d PUBLIC ${CORE_INCLUDES})
target_include_directories(gpu PUBLIC ${CORE_INCLUDES})
# Note: Static libraries do not strictly need to link dependencies,
# but if they did, PRIVATE would propagate to the executable.
# We will link them in the executable to be explicit and avoid order issues.
#-- - Tools Setup -- -
if (DEFINED ASSET_PACKER_PATH)
set(ASSET_PACKER_CMD ${ASSET_PACKER_PATH})
set(ASSET_PACKER_DEPENDS ${ASSET_PACKER_PATH})
else()
add_executable(asset_packer tools/asset_packer.cc)
target_link_libraries(asset_packer PRIVATE procedural)
set(ASSET_PACKER_CMD $<TARGET_FILE:asset_packer>)
set(ASSET_PACKER_DEPENDS asset_packer)
endif()
if (DEFINED SEQ_COMPILER_PATH)
set(SEQ_COMPILER_CMD ${SEQ_COMPILER_PATH})
set(SEQ_COMPILER_DEPENDS ${SEQ_COMPILER_PATH})
else()
add_executable(seq_compiler tools/seq_compiler.cc)
set(SEQ_COMPILER_CMD $<TARGET_FILE:seq_compiler>)
set(SEQ_COMPILER_DEPENDS seq_compiler)
endif()
if (DEFINED TRACKER_COMPILER_PATH)
set(TRACKER_COMPILER_CMD ${TRACKER_COMPILER_PATH})
set(TRACKER_COMPILER_DEPENDS ${TRACKER_COMPILER_PATH})
else()
add_executable(tracker_compiler tools/tracker_compiler.cc)
set(TRACKER_COMPILER_CMD $<TARGET_FILE:tracker_compiler>)
set(TRACKER_COMPILER_DEPENDS tracker_compiler)
endif()
# Always build a host-native tracker_compiler for code generation purposes
add_executable(tracker_compiler_host tools/tracker_compiler.cc)
set_target_properties(tracker_compiler_host PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tools_host")
# Determine which tracker compiler to use for code generation
if (DEMO_CROSS_COMPILE_WIN32)
set(TRACKER_COMPILER_FINAL_CMD "${CMAKE_SOURCE_DIR}/build_native/tools_host/tracker_compiler_host")
set(TRACKER_COMPILER_FINAL_DEPENDS tracker_compiler_host)
else()
set(TRACKER_COMPILER_FINAL_CMD ${TRACKER_COMPILER_CMD})
set(TRACKER_COMPILER_FINAL_DEPENDS ${TRACKER_COMPILER_DEPENDS})
endif()
#-- - Code Generation Helpers -- -
function(pack_assets NAME INPUT_TXT HEADER_VAR DATA_CC_VAR TARGET_NAME)
set(OUT_H ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/${NAME}.h)
set(OUT_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/${NAME}_data.cc)
add_custom_command(
OUTPUT ${OUT_H} ${OUT_CC}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/generated
COMMAND ${ASSET_PACKER_CMD} ${INPUT_TXT} ${OUT_H} ${OUT_CC}
DEPENDS ${ASSET_PACKER_DEPENDS} ${INPUT_TXT}
COMMENT "Generating assets for ${NAME}..."
)
set(${HEADER_VAR} ${OUT_H} PARENT_SCOPE)
set(${DATA_CC_VAR} ${OUT_CC} PARENT_SCOPE)
add_custom_target(${TARGET_NAME} DEPENDS ${OUT_H} ${OUT_CC})
endfunction()
# A separate function for test assets to avoid polluting the source tree
function(pack_test_assets NAME INPUT_TXT HEADER_VAR DATA_CC_VAR TARGET_NAME)
set(OUT_H ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test/${NAME}.h)
set(OUT_CC ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test/${NAME}_data.cc)
add_custom_command(
OUTPUT ${OUT_H} ${OUT_CC}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test
COMMAND ${ASSET_PACKER_CMD} ${INPUT_TXT} ${OUT_H} ${OUT_CC}
DEPENDS ${ASSET_PACKER_DEPENDS} ${INPUT_TXT}
COMMENT "Generating assets for test ${NAME}..."
)
set(${HEADER_VAR} ${OUT_H} PARENT_SCOPE)
set(${DATA_CC_VAR} ${OUT_CC} PARENT_SCOPE)
add_custom_target(${TARGET_NAME} DEPENDS ${OUT_H} ${OUT_CC})
endfunction()
#-- - Build Macros -- -
macro(add_demo_executable NAME)
add_executable(${NAME} ${ARGN})
# target_link_libraries must be called manually to ensure correct order
endmacro()
macro(add_demo_test NAME TEST_NAME)
add_executable(${NAME} ${ARGN})
add_test(NAME ${TEST_NAME} COMMAND ${NAME})
endmacro()
#-- - Generation Targets -- -
set(DEMO_SEQ_PATH ${CMAKE_CURRENT_SOURCE_DIR}/assets/demo.seq)
set(GENERATED_TIMELINE_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/timeline.cc)
add_custom_command(
OUTPUT ${GENERATED_TIMELINE_CC}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/generated
COMMAND ${SEQ_COMPILER_CMD} ${DEMO_SEQ_PATH} ${GENERATED_TIMELINE_CC}
DEPENDS ${SEQ_COMPILER_DEPENDS} ${DEMO_SEQ_PATH}
src/gpu/demo_effects.h
COMMENT "Compiling demo sequence..."
)
add_custom_target(generate_timeline ALL DEPENDS ${GENERATED_TIMELINE_CC})
set(TRACKER_MUSIC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/assets/music.track)
set(GENERATED_MUSIC_DATA_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/music_data.cc)
add_custom_command(
OUTPUT ${GENERATED_MUSIC_DATA_CC}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/generated
COMMAND ${TRACKER_COMPILER_FINAL_CMD} ${TRACKER_MUSIC_PATH} ${GENERATED_MUSIC_DATA_CC}
DEPENDS ${TRACKER_COMPILER_FINAL_DEPENDS} ${TRACKER_MUSIC_PATH} tracker_compiler_host
COMMENT "Compiling tracker music..."
)
add_custom_target(generate_tracker_music ALL DEPENDS ${GENERATED_MUSIC_DATA_CC})
pack_assets(assets ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/demo_assets.txt GEN_DEMO_H GEN_DEMO_CC generate_demo_assets)
pack_test_assets(test_assets ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/test_assets_list.txt GEN_TEST_H GEN_TEST_CC generate_test_assets)
#-- - Main Demo -- -
add_demo_executable(demo64k src/main.cc ${PLATFORM_SOURCES} ${GEN_DEMO_CC} ${GENERATED_TIMELINE_CC} ${GENERATED_MUSIC_DATA_CC})
add_dependencies(demo64k generate_demo_assets generate_timeline generate_tracker_music)# Link order: Internal libs first, then external libs (DEMO_LIBS).
# gpu and 3d depend on WGPU (in DEMO_LIBS).
if (APPLE)
target_link_libraries(demo64k PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
else()
target_link_libraries(demo64k PRIVATE -Wl,--start-group 3d gpu audio procedural util -Wl,--end-group ${DEMO_LIBS})
endif()
#Size optimizations
if (DEMO_SIZE_OPT)
if (MSVC)
target_compile_options(demo64k PRIVATE /Os /GS-)
target_link_options(demo64k PRIVATE /OPT:REF /OPT:ICF /INCREMENTAL:NO)
elseif (APPLE)
target_compile_options(demo64k PRIVATE -Os)
target_link_options(demo64k PRIVATE -Wl,-dead_strip)
else ()
target_compile_options(demo64k PRIVATE -Os -ffunction-sections -fdata-sections)
target_link_options(demo64k PRIVATE -Wl,--gc-sections -s)
endif()
endif()
#-- - Tests -- -
enable_testing()
if(DEMO_BUILD_TESTS)
add_demo_test(test_window HammingWindowTest src/tests/test_window.cc ${GEN_DEMO_CC})
target_link_libraries(test_window PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_window generate_demo_assets)
add_demo_test(test_maths MathUtilsTest src/tests/test_maths.cc)
add_demo_test(test_synth SynthEngineTest src/tests/test_synth.cc ${GEN_DEMO_CC})
target_link_libraries(test_synth PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_synth generate_demo_assets)
add_demo_test(test_dct DctTest src/tests/test_dct.cc ${GEN_DEMO_CC})
target_link_libraries(test_dct PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_dct generate_demo_assets)
add_demo_test(test_audio_gen AudioGenTest src/tests/test_audio_gen.cc ${GEN_DEMO_CC})
target_link_libraries(test_audio_gen PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_audio_gen generate_demo_assets)
add_demo_test(test_audio_backend AudioBackendTest src/tests/test_audio_backend.cc ${GEN_DEMO_CC})
target_link_libraries(test_audio_backend PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_audio_backend generate_demo_assets)
add_demo_test(test_mock_backend MockAudioBackendTest src/tests/test_mock_backend.cc src/audio/mock_audio_backend.cc ${GEN_DEMO_CC})
target_link_libraries(test_mock_backend PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_mock_backend generate_demo_assets)
add_demo_test(test_tracker_timing TrackerTimingTest src/tests/test_tracker_timing.cc src/audio/mock_audio_backend.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_tracker_timing PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_tracker_timing generate_demo_assets generate_tracker_music)
add_demo_test(test_variable_tempo VariableTempoTest src/tests/test_variable_tempo.cc src/audio/mock_audio_backend.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_variable_tempo PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_variable_tempo generate_demo_assets generate_tracker_music)
add_demo_test(test_tracker TrackerSystemTest src/tests/test_tracker.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_tracker PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_tracker generate_tracker_music)
add_demo_test(test_shader_assets ShaderAssetValidation src/tests/test_shader_assets.cc ${GEN_DEMO_CC})
target_link_libraries(test_shader_assets PRIVATE util procedural ${DEMO_LIBS})
add_dependencies(test_shader_assets generate_demo_assets)
add_demo_executable(test_spectool src/tests/test_spectool.cc ${PLATFORM_SOURCES} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_compile_definitions(test_spectool PRIVATE DEMO_BUILD_TOOLS)
target_link_libraries(test_spectool PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(test_spectool generate_tracker_music generate_demo_assets)
add_demo_test(test_assets AssetManagerTest src/tests/test_assets.cc ${GEN_TEST_CC})
target_include_directories(test_assets PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test)
target_compile_definitions(test_assets PRIVATE USE_TEST_ASSETS)
target_link_libraries(test_assets PRIVATE util procedural ${DEMO_LIBS})
add_dependencies(test_assets generate_test_assets)
set_source_files_properties(src/tests/test_assets.cc PROPERTIES COMPILE_DEFINITIONS "USE_TEST_ASSETS")
add_demo_test(test_sequence SequenceSystemTest src/tests/test_sequence.cc ${GEN_DEMO_CC} ${GENERATED_TIMELINE_CC} ${PLATFORM_SOURCES})
target_link_libraries(test_sequence PRIVATE 3d gpu util procedural ${DEMO_LIBS})
add_dependencies(test_sequence generate_timeline generate_demo_assets)
add_demo_test(test_procedural ProceduralGenTest src/tests/test_procedural.cc)
target_link_libraries(test_procedural PRIVATE procedural ${DEMO_LIBS})
add_demo_test(test_3d ThreeDSystemTest src/tests/test_3d.cc)
add_demo_test(test_shader_composer ShaderComposerTest src/tests/test_shader_composer.cc ${GEN_TEST_CC})
target_compile_definitions(test_shader_composer PRIVATE USE_TEST_ASSETS)
target_include_directories(test_shader_composer PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test ${CORE_INCLUDES})
target_link_libraries(test_shader_composer PRIVATE gpu util procedural ${DEMO_LIBS})
add_dependencies(test_shader_composer generate_test_assets)
add_demo_executable(test_texture_manager src/tests/test_texture_manager.cc ${PLATFORM_SOURCES} ${GENERATED_TIMELINE_CC} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_texture_manager PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
add_dependencies(test_texture_manager generate_timeline generate_demo_assets generate_tracker_music)
add_demo_executable(test_3d_render src/tests/test_3d_render.cc ${PLATFORM_SOURCES} ${GENERATED_TIMELINE_CC} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_3d_render PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
add_dependencies(test_3d_render generate_timeline generate_demo_assets generate_tracker_music)
endif()
#-- - Extra Tools -- -
if(DEMO_BUILD_TOOLS OR DEMO_BUILD_TESTS)
add_demo_executable(spectool tools/spectool.cc ${PLATFORM_SOURCES} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_compile_definitions(spectool PRIVATE DEMO_BUILD_TOOLS)
target_link_libraries(spectool PRIVATE audio util procedural ${DEMO_LIBS})
add_dependencies(spectool generate_tracker_music generate_demo_assets)
add_executable(specview tools/specview.cc)
endif()
#-- - Global Target Configuration -- -
add_custom_target(final
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen_assets.sh
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/crunch_demo.sh
DEPENDS demo64k
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_target(pack_source
COMMAND tar -czf demo_all.tgz --exclude=.git --exclude=build* --exclude=.gemini* --exclude=*.tgz --exclude=*.zip --exclude=.DS_Store .
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
|