Repository navigation
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
662 lines (628 loc) · 38.3 KB
/
Copy pathCMakeLists.txt
File metadata and controls
662 lines (628 loc) · 38.3 KB
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
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
cmake_minimum_required(VERSION 3.24)
project(DisruptorRecomp C CXX)
if(WIN32)
enable_language(RC)
endif()
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 20)
# A Linux release runs on systems whose C++ library is older than the compiler's: glibc is all it asks of them.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_link_options(-static-libstdc++ -static-libgcc)
endif()
# libGL.so.1 is on every Linux system that has OpenGL, GLVND's libOpenGL.so.0 only where its own package is installed.
set(OpenGL_GL_PREFERENCE LEGACY)
if(WIN32 AND NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
message(FATAL_ERROR
"DisruptorRecomp supports 64-bit Windows builds only. "
"Use an x64 Visual Studio developer environment.")
endif()
set(PSXRECOMP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/psxrecomp" CACHE PATH
"Path to the pinned PSXRecomp checkout")
option(DISRUPTOR_DEV_MENU
"Build the in-game Disruptor settings menu"
ON)
option(DISRUPTOR_FRAME_INTERPOLATION
"Build the experimental presentation-only frame interpolator"
ON)
if(DEFINED PSX_GAME_VERSION AND NOT PSX_GAME_VERSION STREQUAL "")
set(DISRUPTOR_DEV_TOOLS_DEFAULT OFF)
else()
set(DISRUPTOR_DEV_TOOLS_DEFAULT ON)
endif()
option(DISRUPTOR_DEV_TOOLS
"Build the developer tools of the Debug tab, such as starting any mission"
${DISRUPTOR_DEV_TOOLS_DEFAULT})
if(DISRUPTOR_DEV_TOOLS AND DEFINED PSX_GAME_VERSION AND NOT PSX_GAME_VERSION STREQUAL "")
message(FATAL_ERROR "A build with PSX_GAME_VERSION is a release: set DISRUPTOR_DEV_TOOLS=OFF")
endif()
set(DISRUPTOR_EXTRA_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/achievements/game_client.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/backdrop_tiles.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/sky_grower.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/billboard_aspect.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/capsule.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/cheats.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/control_probe.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/diagnostics.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/far_rendering.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/precision_routes.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/movie_smoothing.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/frame/frame_rate.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/frame/stock_frames.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/host.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/audio/bass_cut.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/saved.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/user_folder.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/game_mark.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/intro_skip.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/streamed_reads.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/main_menu_exit.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/menu_mouse.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/state_screen.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/card_choice.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/language/language.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/language/language_briefing.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/language/language_disc.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/language/language_hints.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/language/language_movie_sound.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/language/language_source.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/language/save_words.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/restart.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/baton_choice.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/mouse_aim.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/list_message.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/name_entry.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/psionic_change.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/selection_wheel.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/weapon_list.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/render_arena.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/grown_quad.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/hud_widgets.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/mover_motion.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/ddgi_view.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/adaptive_resolution.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/ddgi_level.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/sprite_depth.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/input/vertical_camera.cpp")
if(DISRUPTOR_DEV_TOOLS)
list(APPEND DISRUPTOR_EXTRA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/mission_select.cpp")
list(APPEND DISRUPTOR_EXTRA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/sky_dump.cpp")
endif()
# The project deliberately uses the redistributable OpenBIOS backend only.
set(PSXRECOMP_BIOS_STEMS "OpenBIOS" CACHE STRING "" FORCE)
set(PSX_RECOMP_UI OFF CACHE BOOL "" FORCE)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src")
# The framework's settings reader takes the game's section of settings.toml from here, in every target alike.
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings")
add_compile_definitions(PSX_HAS_GAME_USER_SETTINGS=1)
include("${PSXRECOMP_ROOT}/runtime/runtime.cmake")
# The depfile names the hash header by a relative path and its rule by an absolute one, so a new key was missed.
set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/capsule.cpp" APPEND
PROPERTY OBJECT_DEPENDS "${PSXRECOMP_ROOT}/runtime/include/overlay_codegen_hash.h")
# The in-game menu and the launcher both draw with ImGui.
include(FetchContent)
FetchContent_Declare(disruptor_imgui
URL
"https://github.com/ocornut/imgui/archive/refs/tags/v1.93.0.tar.gz"
URL_HASH
"SHA256=f7bf6bc76e5d79d40d751096663e6c5d18daf08129dd52e7f7b09e4251c8eeee"
DOWNLOAD_EXTRACT_TIMESTAMP FALSE)
FetchContent_MakeAvailable(disruptor_imgui)
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/achievements.cmake")
if(DISRUPTOR_DEV_MENU)
if(PSX_SDL3)
set(DISRUPTOR_IMGUI_SDL_BACKEND
"${disruptor_imgui_SOURCE_DIR}/backends/imgui_impl_sdl3.cpp")
else()
set(DISRUPTOR_IMGUI_SDL_BACKEND
"${disruptor_imgui_SOURCE_DIR}/backends/imgui_impl_sdl2.cpp")
endif()
add_library(disruptor-imgui STATIC
"${disruptor_imgui_SOURCE_DIR}/imgui.cpp"
"${disruptor_imgui_SOURCE_DIR}/imgui_draw.cpp"
"${disruptor_imgui_SOURCE_DIR}/imgui_tables.cpp"
"${disruptor_imgui_SOURCE_DIR}/imgui_widgets.cpp"
"${DISRUPTOR_IMGUI_SDL_BACKEND}"
"${disruptor_imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp")
target_include_directories(disruptor-imgui PUBLIC
"${disruptor_imgui_SOURCE_DIR}"
"${disruptor_imgui_SOURCE_DIR}/backends")
target_link_libraries(disruptor-imgui PRIVATE ${PSX_SDL_LIBRARIES})
target_compile_features(disruptor-imgui PUBLIC cxx_std_20)
if(WIN32)
target_compile_definitions(
disruptor-imgui PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:NOMINMAX>")
endif()
list(APPEND DISRUPTOR_EXTRA_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/options.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/preferences.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/rows.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_controls.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_display.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_enhancements.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_audio.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_experimental.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_debug.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_cheats.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_achievements.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/achievements_overlay.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/password_hint.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/state_browser.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_system.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/tab_language.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/menu/menu.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/ui/selection_wheel.cpp")
if(DISRUPTOR_FRAME_INTERPOLATION)
list(APPEND DISRUPTOR_EXTRA_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/frame/present_rate.cpp")
endif()
set(DISRUPTOR_WINDOW_ICON "${CMAKE_CURRENT_SOURCE_DIR}/src/launcher/assets/app-64.bmp")
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/window_icon.cpp"
COMMAND "${CMAKE_COMMAND}" "-DINPUT=${DISRUPTOR_WINDOW_ICON}" "-DOUTPUT=${CMAKE_CURRENT_BINARY_DIR}/window_icon.cpp"
-DNAME=disruptor_window_icon_bmp -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/embed_bytes.cmake"
DEPENDS "${DISRUPTOR_WINDOW_ICON}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/embed_bytes.cmake"
VERBATIM)
list(APPEND DISRUPTOR_EXTRA_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/window_icon.cpp")
endif()
file(GLOB GAME_GENERATED_FULL CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/generated/SLUS_002.24.code_full.c"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/SLUS_002.24.code_full_*.c")
set(GAME_GENERATED_DISPATCH
"${CMAKE_CURRENT_SOURCE_DIR}/generated/SLUS_002.24.code_dispatch.c")
set(DISRUPTOR_STATIC_OVERLAY_DEFAULT OFF)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/generated/overlays_static.c")
set(DISRUPTOR_STATIC_OVERLAY_DEFAULT ON)
endif()
option(DISRUPTOR_USE_CAPTURED_STATIC_OVERLAY
"Link generated/overlays_static.c when a private captured-code build has produced it"
${DISRUPTOR_STATIC_OVERLAY_DEFAULT})
set(GAME_OVERLAY_STATIC "")
if(DISRUPTOR_USE_CAPTURED_STATIC_OVERLAY)
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/generated/overlays_static.c")
message(FATAL_ERROR
"DISRUPTOR_USE_CAPTURED_STATIC_OVERLAY is enabled, but the private "
"generated/overlays_static.c file does not exist")
endif()
set(GAME_OVERLAY_STATIC
"${CMAKE_CURRENT_SOURCE_DIR}/generated/overlays_static.c")
endif()
# The framework runs a statically linked plugin only when a package declares it: the game's own, one hidden feature on by default.
set(DISRUPTOR_PLUGINS
disruptor.baton_choice
disruptor.card_choice.menu
disruptor.ddgi.vsync
disruptor.ddgi.world
disruptor.far_rendering.renderer
disruptor.far_rendering.room_objects
disruptor.far_rendering.sector_edges
disruptor.frame_rate.vsync
disruptor.god_mode.damage
disruptor.intro_skip.renderer
disruptor.language.briefing
disruptor.language.hint.move
disruptor.language.hint.read
disruptor.language.hint.stage
disruptor.language.layout
disruptor.language.movie_sound
disruptor.language.text
disruptor.list_message.draw
disruptor.list_message.loads
disruptor.list_message.sent
disruptor.list_message.tick
disruptor.main_menu_exit.draw
disruptor.main_menu_exit.menu
disruptor.menu_mouse.draw
disruptor.menu_mouse.icon
disruptor.menu_mouse.load
disruptor.menu_mouse.pause
disruptor.menu_mouse.tick
disruptor.mover_motion.draw
disruptor.mover_motion.drawn
disruptor.mover_motion.tick
disruptor.mover_motion.vsync
disruptor.mover_motion.world
disruptor.name_entry
disruptor.password_hint.draw
disruptor.psionic_change.tick
disruptor.render_arena
disruptor.save_words.text
disruptor.state_screen.pause
disruptor.stock_frames.effects
disruptor.stock_frames.message
disruptor.stock_frames.sounds
disruptor.stock_frames.tick
disruptor.stock_frames.vsync
disruptor.streamed_reads
disruptor.vertical_camera.renderer
)
if(DISRUPTOR_DEV_TOOLS)
list(APPEND DISRUPTOR_PLUGINS disruptor.mission_select)
endif()
set(DISRUPTOR_PRELOADED_MODS "${CMAKE_CURRENT_BINARY_DIR}/disruptor_mods")
set(disruptor_manifest "format_version = 5\nid = \"disruptor.game\"\nversion = \"1.0.0\"\nname = \"Disruptor Recompiled\"\nauthor = \"Disruptor Recompiled\"\ndescription = \"The game's own enhancements and fixes, set in its own menu.\"\nresolver = \"declarative\"\nsave_compatibility = \"shared\"\n\n[[target]]\ngame_id = \"SLUS-00224\"\n\n[[feature]]\nid = \"game\"\nname = \"Disruptor Recompiled\"\ndescription = \"The game's own enhancements and fixes, set in its own menu.\"\ndefault_enabled = true\nhidden = true\n")
foreach(plugin IN LISTS DISRUPTOR_PLUGINS)
string(APPEND disruptor_manifest "\n[[plugin]]\nfeature = \"game\"\nid = \"${plugin}\"\n")
endforeach()
file(CONFIGURE OUTPUT "${DISRUPTOR_PRELOADED_MODS}/packages/disruptor.game/1.0.0/manifest.toml"
CONTENT "${disruptor_manifest}")
option(DISRUPTOR_PGXP "Compile the generated code with the framework's PGXP dataflow hooks" OFF)
set(DISRUPTOR_PGXP_ARG)
if(DISRUPTOR_PGXP)
set(DISRUPTOR_PGXP_ARG PGXP)
endif()
psxrecomp_add_runtime_target(psx-runtime ${DISRUPTOR_PGXP_ARG}
PRELOADED_MODS_DIR "${DISRUPTOR_PRELOADED_MODS}"
APP_ICON "${CMAKE_CURRENT_SOURCE_DIR}/src/launcher/assets/app.ico"
GAME_GENERATED_FULL_C ${GAME_GENERATED_FULL}
GAME_GENERATED_DISPATCH_C "${GAME_GENERATED_DISPATCH}"
GAME_OVERLAY_STATIC_C "${GAME_OVERLAY_STATIC}"
EXTRAS_SOURCES
${DISRUPTOR_EXTRA_SOURCES}
DEBUG_PORT 4624
WINDOW_TITLE "Disruptor Recompiled"
DEFAULT_GAME_CONFIG_PATH "game.toml"
EXE_NAME "DisruptorRecompiled"
)
if(BUILD_TESTING)
# The audit runs the linked game, which needs the translated code.
set_tests_properties(psx_mod_plugin_audit_psx-runtime PROPERTIES LABELS retail)
endif()
target_compile_definitions(psx-runtime PRIVATE
PSX_HAS_GAME_HOST=1)
disruptor_achievements_library(disruptor-achievements)
target_link_libraries(psx-runtime PRIVATE disruptor-achievements)
if(DISRUPTOR_DEV_TOOLS)
target_compile_definitions(psx-runtime PRIVATE DISRUPTOR_DEV_TOOLS=1)
add_executable(disruptor-sky-grow "${CMAKE_CURRENT_SOURCE_DIR}/tools/sky_grow/sky_grow.cpp")
target_include_directories(disruptor-sky-grow PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src")
endif()
if(NOT DISRUPTOR_FRAME_INTERPOLATION)
target_compile_definitions(psx-runtime PRIVATE
# Keep the experimental sources available, but compile out frame
# blending, temporal capture and the high-refresh presenter by default.
PSX_DISABLE_FRAME_INTERPOLATION=1)
endif()
if(DISRUPTOR_DEV_MENU)
target_compile_definitions(psx-runtime PRIVATE PSX_FRAME_INTERPOLATION_GEOMETRY_DEFAULT=1)
target_link_libraries(psx-runtime PRIVATE disruptor-imgui)
endif()
if(WIN32)
target_compile_definitions(
psx-runtime PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:NOMINMAX>")
endif()
target_sources(psx-runtime PRIVATE "${PSXRECOMP_ROOT}/runtime/src/disruptor_renderer_compat.c")
if(MSVC)
# The runtime sources with C11 atomics only: generated C stays in MSVC's extension-compatible mode, strict /std:c11 rejects its address constants.
foreach(source audio_trace autocompile boot_state debug_server gpu_gl_renderer guest_tty host_overlay host_span_ring
overlay_capture render_thread starvation_ring)
set_property(SOURCE "${PSXRECOMP_ROOT}/runtime/src/${source}.c" APPEND PROPERTY COMPILE_OPTIONS
"/std:c11" "/experimental:c11atomics")
endforeach()
# The framework's texture-pack and mod sources treat u8string() as std::string (C++17).
foreach(source texture_pack_install duckstation_texture_pack gpu_hd_textures mod_packages mod_runtime)
set_property(SOURCE "${PSXRECOMP_ROOT}/runtime/src/${source}.cpp" APPEND PROPERTY COMPILE_OPTIONS "/Zc:char8_t-")
endforeach()
else()
foreach(source texture_pack_install duckstation_texture_pack gpu_hd_textures mod_packages mod_runtime)
set_property(SOURCE "${PSXRECOMP_ROOT}/runtime/src/${source}.cpp" APPEND PROPERTY COMPILE_OPTIONS "-fno-char8_t")
endforeach()
endif()
if(WIN32)
# UTF-8 as the game's code page: a path in settings.toml may hold letters the system's own page lacks.
if(MINGW)
target_sources(psx-runtime PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/game/disruptor.rc")
else()
target_sources(psx-runtime PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/game/disruptor.manifest")
endif()
endif()
include(CTest)
if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_subdirectory(src/launcher)
endif()
if(BUILD_TESTING)
find_package(Python3 3.11 REQUIRED COMPONENTS Interpreter)
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/DisruptorTests.cmake")
if(TARGET disruptor-launcher)
# The launcher's keyboard and gamepad paths, driven hidden through its picture mode. 77: no display here.
add_test(NAME disruptor_launcher_navigation
COMMAND "${Python3_EXECUTABLE}" -B "${PROJECT_SOURCE_DIR}/tests/unit/launcher_navigation_test.py"
"$<TARGET_FILE:disruptor-launcher>")
set_tests_properties(disruptor_launcher_navigation PROPERTIES SKIP_RETURN_CODE 77)
endif()
disruptor_contract(backdrop_tiles RETAIL)
disruptor_contract(sky_pass)
disruptor_contract(entry_hooks)
disruptor_contract(render_groups)
disruptor_contract(idle_skip RETAIL)
disruptor_contract(precision_words)
disruptor_contract(host_present)
disruptor_contract(depth24_sync)
disruptor_contract(geometry_provenance)
disruptor_contract(step_fusion RETAIL)
disruptor_contract(hot_paths)
disruptor_contract(phase_a)
disruptor_contract(perspective_texture)
disruptor_contract(pinned_corner)
disruptor_contract(dev_menu)
disruptor_contract(loaded_state)
disruptor_contract(save_point)
disruptor_contract(cheats)
disruptor_contract(gpu_dma)
disruptor_contract(weapon_selection RETAIL)
disruptor_contract(selection_wheel RETAIL)
disruptor_contract(vertical_camera)
disruptor_contract(far_rendering)
disruptor_contract(frame_kind)
disruptor_contract(temporal_presenter)
disruptor_contract(menu_wide)
disruptor_contract(hud_scale)
disruptor_contract(hud_widget)
disruptor_contract(name_entry RETAIL)
disruptor_contract(fast_forward_key)
disruptor_contract(grown_quad RETAIL)
disruptor_contract(mover_steps RETAIL)
disruptor_contract(stock_frames RETAIL)
disruptor_contract(list_message RETAIL)
disruptor_contract(shot_lights RETAIL)
disruptor_contract(sprite_range RETAIL)
disruptor_contract(intro_skip RETAIL)
disruptor_contract(language RETAIL)
disruptor_contract(main_menu_exit RETAIL)
disruptor_contract(language_disc RETAIL)
disruptor_contract(frame_rate RETAIL)
disruptor_contract(widescreen_cull RETAIL)
disruptor_contract(billboard_aspect)
disruptor_contract(launcher)
disruptor_contract(release_text)
disruptor_contract(capsule)
disruptor_contract(gap_filling)
disruptor_contract(world_depth)
disruptor_contract(supplemental)
disruptor_contract(world_texel)
disruptor_contract(near_face)
disruptor_contract(smooth_turn)
disruptor_contract(sticks)
disruptor_contract(probe_lighting)
disruptor_contract(ambient_occlusion)
disruptor_contract(smooth_fade)
disruptor_contract(antialiasing)
disruptor_contract(debug_tab)
disruptor_contract(diagnostics)
disruptor_contract(instruction_hooks)
disruptor_contract(state_key)
disruptor_contract(test_registration)
disruptor_contract(achievements)
add_test(NAME disruptor_framework_tool
COMMAND "${Python3_EXECUTABLE}" -B
"${CMAKE_CURRENT_SOURCE_DIR}/tests/contracts/test_framework_tool.py")
# The contracts and some unit tests read framework files from the checkout: it must hold what framework/ says.
file(REAL_PATH "${PSXRECOMP_ROOT}" framework_checkout)
file(REAL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/psxrecomp" framework_expected)
if(NOT framework_checkout STREQUAL framework_expected)
message(FATAL_ERROR "The tests read the framework from ${framework_expected}, not ${framework_checkout}")
endif()
add_test(NAME disruptor_framework_in_step
COMMAND "${Python3_EXECUTABLE}" -B
"${CMAKE_CURRENT_SOURCE_DIR}/tools/framework.py" check --framework "${PSXRECOMP_ROOT}")
endif()
if(BUILD_TESTING AND NOT CMAKE_CROSSCOMPILING)
disruptor_unit_test(disruptor_user_settings_persistence tests/unit/user_settings_persistence_test.cpp
TARGET disruptor-user-settings-test
SOURCES
"${PSXRECOMP_ROOT}/recompiler/src/config_loader.cpp"
"${PSXRECOMP_ROOT}/recompiler/src/ps1_exe_parser.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/saved.cpp"
INCLUDES
"${PSXRECOMP_ROOT}/recompiler/src"
"${PSXRECOMP_ROOT}/recompiler/include"
"${PSXRECOMP_ROOT}/recompiler/lib/fmt/include"
"${PSXRECOMP_ROOT}/recompiler/lib/toml11"
DEFINITIONS
FMT_HEADER_ONLY=1
"$<$<CXX_COMPILER_ID:MSVC>:NOMINMAX>"
"$<$<CXX_COMPILER_ID:MSVC>:WIN32_LEAN_AND_MEAN>")
disruptor_unit_test(disruptor_game_config tests/unit/game_config_test.cpp
TARGET disruptor-game-config-test
SOURCES
"${PSXRECOMP_ROOT}/recompiler/src/config_loader.cpp"
"${PSXRECOMP_ROOT}/recompiler/src/ps1_exe_parser.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/saved.cpp"
INCLUDES
"${PSXRECOMP_ROOT}/recompiler/src"
"${PSXRECOMP_ROOT}/recompiler/include"
"${PSXRECOMP_ROOT}/recompiler/lib/fmt/include"
"${PSXRECOMP_ROOT}/recompiler/lib/toml11"
DEFINITIONS
FMT_HEADER_ONLY=1
"$<$<CXX_COMPILER_ID:MSVC>:NOMINMAX>"
"$<$<CXX_COMPILER_ID:MSVC>:WIN32_LEAN_AND_MEAN>")
target_compile_definitions(disruptor-game-config-test PRIVATE "DISRUPTOR_SOURCE_DIR=R\"(${PROJECT_SOURCE_DIR})\"")
disruptor_unit_test(disruptor_user_folder tests/unit/user_folder_test.cpp RUNTIME_HEADERS
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/user_folder.cpp")
disruptor_unit_test(disruptor_game_mark tests/unit/game_mark_test.cpp
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/game_mark.cpp")
disruptor_unit_test(disruptor_game_package tests/unit/disruptor_game_package_test.cpp)
disruptor_unit_test(disruptor_card_choice tests/unit/disruptor_card_choice_test.cpp)
disruptor_unit_test(disruptor_save_words tests/unit/disruptor_save_words_test.cpp)
disruptor_unit_test(disruptor_save_words_hooks tests/unit/disruptor_save_words_hooks_test.cpp
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/language/save_words.cpp"
INCLUDES src "${PSXRECOMP_ROOT}/runtime/include")
disruptor_unit_test(disruptor_mouse_aim tests/unit/disruptor_mouse_aim_test.cpp
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/settings/user_folder.cpp"
INCLUDES tests/support/stubs "${PSXRECOMP_ROOT}/runtime/include"
DEFINITIONS PSX_SDL3=1)
disruptor_unit_test(disruptor_sticks tests/unit/disruptor_sticks_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_selection_wheel tests/unit/disruptor_selection_wheel_test.cpp
INCLUDES tests/support/stubs DEFINITIONS PSX_SDL3=1)
set_tests_properties(disruptor_mouse_aim PROPERTIES
ENVIRONMENT "PSX_DISRUPTOR_MOUSE_AIM=;PSX_DISRUPTOR_VERTICAL_LOOK=;PSX_DISRUPTOR_MODERN_CONTROLS=;PSX_DISRUPTOR_HIGH_PRECISION_CAMERA=")
add_test(NAME disruptor_mouse_aim_replay
COMMAND disruptor-mouse-aim-test --replay)
set_tests_properties(disruptor_mouse_aim_replay PROPERTIES
ENVIRONMENT "PSX_DISRUPTOR_CAPSULE_REPLAY=capsule;PSX_DISRUPTOR_MOUSE_AIM=;PSX_DISRUPTOR_VERTICAL_LOOK=;PSX_DISRUPTOR_MODERN_CONTROLS=;PSX_DISRUPTOR_HIGH_PRECISION_CAMERA=")
add_test(NAME disruptor_mouse_aim_registration
COMMAND disruptor-mouse-aim-test --registration)
set_tests_properties(disruptor_mouse_aim_registration PROPERTIES
ENVIRONMENT "PSX_DISRUPTOR_MOUSE_AIM=1;PSX_DISRUPTOR_VERTICAL_LOOK=;PSX_DISRUPTOR_MODERN_CONTROLS=;PSX_DISRUPTOR_HIGH_PRECISION_CAMERA=")
add_test(NAME disruptor_vertical_look_registration
COMMAND disruptor-mouse-aim-test --registration)
set_tests_properties(disruptor_vertical_look_registration PROPERTIES
ENVIRONMENT "PSX_DISRUPTOR_MOUSE_AIM=;PSX_DISRUPTOR_VERTICAL_LOOK=1;PSX_DISRUPTOR_MODERN_CONTROLS=;PSX_DISRUPTOR_HIGH_PRECISION_CAMERA=")
add_test(NAME disruptor_modern_controls_registration
COMMAND disruptor-mouse-aim-test --registration)
set_tests_properties(disruptor_modern_controls_registration PROPERTIES
ENVIRONMENT "PSX_DISRUPTOR_MOUSE_AIM=;PSX_DISRUPTOR_VERTICAL_LOOK=;PSX_DISRUPTOR_MODERN_CONTROLS=1;PSX_DISRUPTOR_HIGH_PRECISION_CAMERA=")
add_test(NAME disruptor_high_precision_camera_registration
COMMAND disruptor-mouse-aim-test --registration)
set_tests_properties(disruptor_high_precision_camera_registration PROPERTIES
ENVIRONMENT "PSX_DISRUPTOR_MOUSE_AIM=;PSX_DISRUPTOR_VERTICAL_LOOK=;PSX_DISRUPTOR_MODERN_CONTROLS=;PSX_DISRUPTOR_HIGH_PRECISION_CAMERA=1")
disruptor_unit_test(disruptor_diagnostics tests/unit/disruptor_diagnostics_test.cpp
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/diagnostics.cpp"
INCLUDES tests/support/stubs
DEFINITIONS PSX_SDL3=1)
set_tests_properties(disruptor_diagnostics PROPERTIES ENVIRONMENT "PSX_DISRUPTOR_DETAILED_LOGGING=")
add_test(NAME disruptor_diagnostics_forced COMMAND disruptor-diagnostics-test --forced)
set_tests_properties(disruptor_diagnostics_forced PROPERTIES ENVIRONMENT "PSX_DISRUPTOR_DETAILED_LOGGING=1")
add_test(NAME disruptor_diagnostics_refused COMMAND disruptor-diagnostics-test --refused)
set_tests_properties(disruptor_diagnostics_refused PROPERTIES ENVIRONMENT "PSX_DISRUPTOR_DETAILED_LOGGING=0")
disruptor_unit_test(disruptor_cheats tests/unit/disruptor_cheats_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_vertical_camera tests/unit/disruptor_vertical_camera_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_far_rendering tests/unit/disruptor_far_rendering_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_sector_reach tests/unit/disruptor_sector_reach_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_portal_reach tests/unit/disruptor_portal_reach_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_sky_panorama tests/unit/disruptor_sky_panorama_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_sky_extension tests/unit/disruptor_sky_extension_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_misplaced_riser tests/unit/disruptor_misplaced_riser_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_near_split tests/unit/disruptor_near_split_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_marked_corners tests/unit/disruptor_marked_corners_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_streamed_reads tests/unit/disruptor_streamed_reads_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_main_menu_exit tests/unit/disruptor_main_menu_exit_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_main_menu_exit_hooks tests/unit/disruptor_main_menu_exit_hooks_test.cpp
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/main_menu_exit.cpp"
INCLUDES tests/support/stubs src "${PSXRECOMP_ROOT}/runtime/include"
DEFINITIONS PSX_SDL3=1)
set_tests_properties(disruptor_main_menu_exit_hooks PROPERTIES
ENVIRONMENT_MODIFICATION "PSX_DISRUPTOR_CAPSULE_REPLAY=unset:")
add_test(NAME disruptor_main_menu_exit_hooks_replay
COMMAND disruptor-main-menu-exit-hooks-test --replay)
set_tests_properties(disruptor_main_menu_exit_hooks_replay PROPERTIES
ENVIRONMENT "PSX_DISRUPTOR_CAPSULE_REPLAY=capsule")
disruptor_unit_test(disruptor_menu_rows tests/unit/disruptor_menu_rows_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_crosshair tests/unit/disruptor_crosshair_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_password_hint tests/unit/disruptor_password_hint_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_states_row tests/unit/disruptor_states_row_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_state_browser tests/unit/disruptor_state_browser_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_state_files tests/unit/disruptor_state_files_test.cpp INCLUDES src)
target_link_libraries(disruptor-state-files-test PRIVATE ZLIB::ZLIB)
disruptor_unit_test(disruptor_menu_mouse_hooks tests/unit/disruptor_menu_mouse_hooks_test.cpp
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/session/menu_mouse.cpp"
INCLUDES tests/support/stubs src "${PSXRECOMP_ROOT}/runtime/include"
DEFINITIONS PSX_SDL3=1)
set_tests_properties(disruptor_menu_mouse_hooks PROPERTIES
ENVIRONMENT_MODIFICATION "PSX_DISRUPTOR_CAPSULE_REPLAY=unset:")
add_test(NAME disruptor_menu_mouse_hooks_replay
COMMAND disruptor-menu-mouse-hooks-test --replay)
set_tests_properties(disruptor_menu_mouse_hooks_replay PROPERTIES
ENVIRONMENT "PSX_DISRUPTOR_CAPSULE_REPLAY=capsule")
add_test(NAME disruptor_menu_mouse_hooks_refused
COMMAND disruptor-menu-mouse-hooks-test --refused)
set_tests_properties(disruptor_menu_mouse_hooks_refused PROPERTIES
ENVIRONMENT_MODIFICATION "PSX_DISRUPTOR_CAPSULE_REPLAY=unset:;DISRUPTOR_HOOK_REFUSED=set:8001D3D8")
disruptor_unit_test(disruptor_render_arena tests/unit/disruptor_render_arena_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_name_entry tests/unit/disruptor_name_entry_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_baton_choice tests/unit/disruptor_baton_choice_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_backdrop_tiles tests/unit/disruptor_backdrop_tiles_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_intro_skip tests/unit/disruptor_intro_skip_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_weapon_load tests/unit/disruptor_weapon_load_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_weapon_list tests/unit/disruptor_weapon_list_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_frame_rate tests/unit/disruptor_frame_rate_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_bass_cut tests/unit/disruptor_bass_cut_test.cpp
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/audio/bass_cut.cpp")
disruptor_unit_test(psx_cyc_overclock tests/unit/psx_cyc_overclock_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(psx_cyc_run tests/unit/psx_cyc_run_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_language tests/unit/disruptor_language_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_language_hints tests/unit/disruptor_language_hints_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_language_movie_sound tests/unit/disruptor_language_movie_sound_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_language_briefing tests/unit/disruptor_language_briefing_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_language_disc tests/unit/disruptor_language_disc_test.cpp)
disruptor_unit_test(disruptor_launcher_menu_art tests/unit/launcher_menu_art_test.cpp
RUNTIME_HEADERS SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/launcher/menu_art.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/launcher/chd_image.cpp"
"${PSXRECOMP_ROOT}/runtime/src/iso_reader.cpp" "${PSXRECOMP_ROOT}/runtime/src/cue_sheet.cpp")
target_link_libraries(disruptor-launcher-menu-art-test PRIVATE chdr-static)
target_include_directories(disruptor-launcher-menu-art-test PRIVATE "${PSXRECOMP_ROOT}/recompiler/include")
disruptor_unit_test(disruptor_language_overlay tests/unit/disruptor_language_overlay_test.cpp
INCLUDES
"${PSXRECOMP_ROOT}/runtime/include"
"${CMAKE_CURRENT_SOURCE_DIR}/src")
add_test(NAME disruptor_language_overlay_tall
COMMAND disruptor-language-overlay-test tall)
disruptor_unit_test(disruptor_capsule tests/unit/disruptor_capsule_test.cpp INCLUDES src)
disruptor_unit_test(disruptor_restart tests/unit/disruptor_restart_test.cpp RUNTIME_HEADERS
ARGUMENTS run "${CMAKE_CURRENT_BINARY_DIR}/disruptor_restart_test.txt")
disruptor_unit_test(disruptor_present_rate tests/unit/disruptor_present_rate_test.cpp
INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/tests/support/present_rate_fakes")
disruptor_unit_test(disruptor_grown_quad tests/unit/disruptor_grown_quad_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_mover_steps tests/unit/disruptor_mover_steps_test.cpp)
disruptor_unit_test(disruptor_object_steps tests/unit/disruptor_object_steps_test.cpp)
disruptor_unit_test(disruptor_stock_frames tests/unit/disruptor_stock_frames_test.cpp)
disruptor_unit_test(disruptor_list_message tests/unit/disruptor_list_message_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_shot_lights tests/unit/disruptor_shot_lights_test.cpp)
disruptor_unit_test(disruptor_psionic_change tests/unit/disruptor_psionic_change_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_sprite_depth tests/unit/disruptor_sprite_depth_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_billboard_aspect tests/unit/disruptor_billboard_aspect_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_ws_frame_kind tests/unit/gpu_ws_frame_kind_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_ws_menu tests/unit/gpu_ws_menu_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_texture_row tests/unit/gpu_texture_row_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_ws_hud_scale tests/unit/gpu_ws_hud_scale_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_sky_fog tests/unit/gpu_sky_fog_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_supplemental tests/unit/gpu_supplemental_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_coverage tests/unit/gpu_coverage_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_dma_step tests/unit/gpu_dma_step_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_presentation tests/unit/gpu_presentation_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_ws_hud_widget tests/unit/gpu_ws_hud_widget_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_ws_tag_match tests/unit/gpu_ws_tag_match_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_host_ui_flags tests/unit/host_ui_flags_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_temporal_sprite tests/unit/gpu_temporal_sprite_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_temporal_match tests/unit/gpu_temporal_match_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_temporal_mesh tests/unit/gpu_temporal_mesh_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_temporal_camera_search tests/unit/gpu_temporal_camera_search_test.cpp
RUNTIME_HEADERS SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/tests/unit/gpu_temporal_camera_scalar.cpp")
disruptor_unit_test(disruptor_gpu_pinned_corner tests/unit/gpu_pinned_corner_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_turned_perspective tests/unit/gpu_turned_perspective_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_turn_clip tests/unit/gpu_turn_clip_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_ddgi_turn tests/unit/gpu_ddgi_turn_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_ddgi_bvh tests/unit/gpu_ddgi_bvh_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_ddgi_mask tests/unit/gpu_ddgi_mask_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_ddgi_level tests/unit/disruptor_ddgi_level_test.cpp RUNTIME_HEADERS INCLUDES src)
disruptor_unit_test(disruptor_movie_filter tests/unit/movie_filter_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_world_depth tests/unit/gpu_world_depth_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_near_face tests/unit/gpu_near_face_test.cpp RUNTIME_HEADERS)
disruptor_unit_test(disruptor_gpu_world_texel tests/unit/gpu_world_texel_test.cpp RUNTIME_HEADERS
INCLUDES "${PSXRECOMP_ROOT}/runtime/src")
disruptor_unit_test(disruptor_presentation_yaw_math tests/unit/presentation_yaw_math_test.cpp)
disruptor_unit_test(disruptor_gte_precision_store_pc tests/unit/gte_precision_store_pc_test.cpp RUNTIME_HEADERS
SOURCES "${PSXRECOMP_ROOT}/runtime/src/gte.cpp" "${PSXRECOMP_ROOT}/runtime/src/pgxp.cpp"
DEFINITIONS PSX_NO_DEBUG_TOOLS=1 PSX_GTE_REGISTER_TEST=1 PSX_ENABLE_BLOCK_CYCLES=1)
disruptor_unit_test(disruptor_resolution tests/unit/resolution_test.cpp INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/src")
disruptor_unit_test(psxrecomp_render_thread_core tests/unit/render_thread_core_test.cpp RUNTIME_HEADERS
SOURCES "${PSXRECOMP_ROOT}/runtime/src/render_thread.c")
disruptor_unit_test(psxrecomp_memcard_publish tests/unit/memcard_publish_test.cpp RUNTIME_HEADERS
SOURCES "${PSXRECOMP_ROOT}/runtime/src/memcard.c")
disruptor_unit_test(disruptor_adaptive_resolution_hooks tests/unit/adaptive_resolution_hooks_test.cpp
INCLUDES tests/support/stubs src "${PSXRECOMP_ROOT}/runtime/include" SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/game/render/adaptive_resolution.cpp"
"${PSXRECOMP_ROOT}/runtime/src/dynamic_resolution.c" DEFINITIONS PSX_SDL3=1)
set_tests_properties(disruptor_adaptive_resolution_hooks PROPERTIES
ENVIRONMENT_MODIFICATION "PSX_DYNRES=unset:;PSX_DYNRES_WORK_SCALE=unset:;PSX_DISRUPTOR_CAPSULE_REPLAY=unset:")
disruptor_unit_test(disruptor_adaptive_resolution tests/unit/adaptive_resolution_test.cpp RUNTIME_HEADERS
INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/src" SOURCES "${PSXRECOMP_ROOT}/runtime/src/dynamic_resolution.c")
disruptor_unit_test(psxrecomp_dynamic_resolution psxrecomp/runtime/tests/test_dynamic_resolution.c RUNTIME_HEADERS
SOURCES "${PSXRECOMP_ROOT}/runtime/src/dynamic_resolution.c")
disruptor_unit_test(psxrecomp_dynamic_resolution_rt psxrecomp/runtime/tests/test_dynamic_resolution_rt.c RUNTIME_HEADERS
SOURCES "${PSXRECOMP_ROOT}/runtime/src/dynamic_resolution.c")
disruptor_unit_test(host_pick_slot tests/unit/host_pick_slot_test.cpp)
disruptor_unit_test(host_borderless tests/unit/host_borderless_test.cpp)
disruptor_unit_test(host_pad_edits tests/unit/pad_edits_test.cpp)
add_test(NAME host_borderless_contract
COMMAND "${Python3_EXECUTABLE}" -B
"${CMAKE_CURRENT_SOURCE_DIR}/tests/contracts/test_borderless_contract.py")
endif()