# The launcher stub and the standalone launcher, both platforms.
#
# The Windows section is the original file, unchanged, inside if (WIN32). The
# POSIX section builds the same programs from the *_posix sources and the
# content stack's POSIX ports. Neither is an afterthought: the four-artifact
# rule (see the server vault's linux-build note) means a release is not a
# release until both platforms built from the same commit.

# Start of tes3mp addition
# 0.51 port: SiltVersions.hpp (the engine/launcher rev stamps) is generated into the build
# root on every build by the silt-version target. The old fork defined it in
# components/CMakeLists.txt next to git-version (0.51 calls that one get-version); it lives
# here so the launcher builds without touching components. The guard lets the client port
# define it earlier instead - whichever comes first wins, never both.
if (NOT TARGET silt-version)
    if (GIT_CHECKOUT)
        add_custom_target(silt-version
            COMMAND ${CMAKE_COMMAND}
                -DGIT_EXECUTABLE=${GIT_EXECUTABLE}
                -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
                -DVERSION_HPP_DIR=${OpenMW_BINARY_DIR}
                -P ${CMAKE_SOURCE_DIR}/cmake/SiltVersion.cmake
            VERBATIM)
    else ()
        file(WRITE "${OpenMW_BINARY_DIR}/SiltVersions.hpp"
            "#ifndef OPENMW_SILTVERSIONS_HPP
#define OPENMW_SILTVERSIONS_HPP
#define SILTSTRIDER_ENGINE_REV \"unknown\"
#define SILTSTRIDER_LAUNCHER_REV \"unknown\"
#endif
")
    endif ()
endif ()
# End of tes3mp addition

if (WIN32)

# Start of tes3mp addition
# 0.51's root CMakeLists sets, for every Windows target: NOMB and NOGDI (the engine's name
# clashes), UNICODE/_UNICODE (Qt 6 precompiled headers) and SDL_MAIN_HANDLED. This directory is
# plain Win32: the stub calls MessageBoxW, the launcher draws with GDI+, every wide call is
# spelled out with its W, and LauncherMain defines SDL_MAIN_HANDLED itself. Take them back
# here only; the engine keeps them.
get_directory_property(SILT_DIR_DEFS COMPILE_DEFINITIONS)
list(REMOVE_ITEM SILT_DIR_DEFS NOMB NOGDI UNICODE _UNICODE SDL_MAIN_HANDLED)
set_directory_properties(PROPERTIES COMPILE_DEFINITIONS "${SILT_DIR_DEFS}")
# End of tes3mp addition

# The launcher stub.
#
# Deliberately depends on nothing but the operating system. It sits at the root of the
# player's folder with no DLLs beside it, which is the entire reason it exists - so it
# must not need any.
#
# That includes the Visual C++ runtime. A stub that imports MSVCP140.dll fails to start
# on a machine without the redistributable, with a loader error no player can act on,
# and it fails at the one moment where nothing else has run yet to explain why. The CRT
# is therefore linked statically.

set(SILTSTRIDER_SOURCES
    main.cpp
    ${CMAKE_SOURCE_DIR}/files/siltstrider/SiltStrider.rc
)

add_executable(SiltStrider WIN32 ${SILTSTRIDER_SOURCES})

target_link_libraries(SiltStrider shell32)

# The .rc refers to SiltStrider.ico and the manifest by bare filename.
set_source_files_properties(
    ${CMAKE_SOURCE_DIR}/files/siltstrider/SiltStrider.rc
    PROPERTIES COMPILE_FLAGS "/I\"${CMAKE_SOURCE_DIR}/files/siltstrider\""
)

if (MSVC)
    # Static CRT. Set both ways so it holds whether or not CMP0091 is NEW: the property
    # is what modern CMake honours, and the flag rewrite covers the old behaviour where
    # /MD is baked into CMAKE_CXX_FLAGS_<CONFIG>.
    set_property(TARGET SiltStrider PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

    foreach(flag_var
            CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
            CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
        string(REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
        string(REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
    endforeach()

    # The rewrite above is confined to THIS directory scope, so the engine and every
    # other target keep the dynamic runtime they were built and tested against.
    # Propagating it upwards would quietly relink the whole project.

    target_compile_options(SiltStrider PRIVATE
        $<$<CONFIG:Debug>:/MTd>
        $<$<NOT:$<CONFIG:Debug>>:/MT>)

    set_target_properties(SiltStrider PROPERTIES
        VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
endif()

# The launcher as its own program.
#
# Built from the SAME sources the engine compiles into itself
# (mwmp/content/UpdateScreen.cpp and friends), so there is one launcher
# implementation with two lives: in-process inside tes3mp for hand-launched
# clients and old installs, and this standalone executable for everyone else.
# The split is what lets the window outlive Play - the game is spawned detached
# and the launcher keeps running its downloads.
#
# It lives in content\bin alongside SDL2.dll, which is why - unlike the stub -
# it is allowed real dependencies. The CRT is still static, matching every
# other tool in this directory: the fewer ways this exe can fail to start on a
# machine we have never seen, the better, and SDL2's C ABI does not care which
# CRT its caller was built against.
set(LAUNCHER_CONTENT_DIR ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content)

# CR2: the launcher offers a crash report before Play, and sends it itself (a running process window
# outside the game). The same files the game compiles for its crash monitor: the session marker and
# the record, the report's files (the gzip is Boost.Beast's header-only deflate - no Boost library
# is linked, so /MT holds), the upload, the native window and the flow. Standard library and the OS
# only.
set(LAUNCHER_CRASH_SOURCES
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashSession.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashReport.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashUpload.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashWindow.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashFlow.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/ClientPlatform.cpp
)

add_executable(SiltStriderLauncher WIN32
    LauncherMain.cpp
    ${LAUNCHER_CONTENT_DIR}/UpdateScreen.cpp
    ${LAUNCHER_CONTENT_DIR}/Sync.cpp
    ${LAUNCHER_CONTENT_DIR}/DiscordAuth.cpp
    ${LAUNCHER_CONTENT_DIR}/Http.cpp
    ${LAUNCHER_CONTENT_DIR}/Json.cpp
    ${LAUNCHER_CONTENT_DIR}/Crypto.cpp
    ${LAUNCHER_CONTENT_DIR}/Morrowind.cpp
    ${LAUNCHER_CONTENT_DIR}/Text.cpp
    ${LAUNCHER_CRASH_SOURCES}
    ${CMAKE_SOURCE_DIR}/files/siltstrider/SiltStrider.rc
)

target_include_directories(SiltStriderLauncher PRIVATE
    ${LAUNCHER_CONTENT_DIR}
    ${OpenMW_BINARY_DIR})   # 0.51 port: SiltVersions.hpp

# bcrypt/crypt32 for the signature and hash checks, winhttp for transport,
# ws2_32 for the sign-in's loopback listener, gdiplus for decoding the backdrop,
# shell32 for opening the browser. SDL2 comes from the dependency bundle and its
# DLL already sits in content\bin - the whole reason this exe lives there.
# SDL2main is deliberately absent: LauncherMain.cpp provides its own wWinMain
# and tells SDL so with SDL_MAIN_HANDLED.
target_link_libraries(SiltStriderLauncher
    SDL2::SDL2   # 0.51 port: the imported target, not SDL2_LIBRARIES
    ZLIB::ZLIB   # 0.51 port: CrashReport's gzip (was Boost.Beast, which the 0.51 bundle lacks)
    bcrypt winhttp crypt32 gdiplus shell32 ws2_32)

# SiltVersions.hpp (the engine/launcher rev stamps drawn bottom-centre) is
# generated into the build root by the silt-version target before anything
# compiles. The target only exists on a git checkout; a tarball build gets a
# static "unknown" header written at configure time instead.
if (TARGET silt-version)
    add_dependencies(SiltStriderLauncher silt-version)
endif()

if (MSVC)
    target_compile_options(SiltStriderLauncher PRIVATE
        $<$<CONFIG:Debug>:/MTd>
        $<$<NOT:$<CONFIG:Debug>>:/MT>)
endif()

# Checks for the content updater's parsing and crypto.
#
# Standalone on purpose: the two pieces most worth being certain about should be
# runnable in a second without launching the game. Its signature vectors come from the
# real signing key, so it proves the C++ verifier and the Node publisher agree - a
# verifier that is self-consistently wrong would pass any test written only in C++.
add_executable(SiltStriderContentTest
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/ContentTest.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Crypto.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Json.cpp
    # Start of tes3mp change
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Sync.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Morrowind.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Http.cpp
    # End of tes3mp change
)

target_include_directories(SiltStriderContentTest PRIVATE
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content)

# Start of tes3mp change
target_link_libraries(SiltStriderContentTest bcrypt winhttp crypt32)
# End of tes3mp change

if (MSVC)
    target_compile_options(SiltStriderContentTest PRIVATE
        $<$<CONFIG:Debug>:/MTd>
        $<$<NOT:$<CONFIG:Debug>>:/MT>)
endif()

# Headless sync, for testing and repair.
add_executable(SiltStriderSync
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/SyncCli.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Sync.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Morrowind.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Http.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Crypto.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Json.cpp
)

target_include_directories(SiltStriderSync PRIVATE
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content)

target_link_libraries(SiltStriderSync bcrypt winhttp crypt32)

if (MSVC)
    target_compile_options(SiltStriderSync PRIVATE
        $<$<CONFIG:Debug>:/MTd>
        $<$<NOT:$<CONFIG:Debug>>:/MT>)
endif()

# Reports which Morrowind installs are detected on this machine.
add_executable(SiltStriderFindMorrowind
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/MorrowindFindCli.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content/Morrowind.cpp
)
target_include_directories(SiltStriderFindMorrowind PRIVATE
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content)
if (MSVC)
    target_compile_options(SiltStriderFindMorrowind PRIVATE
        $<$<CONFIG:Debug>:/MTd> $<$<NOT:$<CONFIG:Debug>>:/MT>)
endif()

# C4129 ("unrecognized character escape sequence") is an ERROR here.
#
# Three of these shipped at once, and none of them announced itself:
#
#   L"\dev"        -> "dev"     envRoot became "<root>dev", so Public Test synced
#                               correctly and then launched Live's openmw.cfg
#   L"\settings"   -> "settings"  --silt-settings pointed at "<root>settings"
#   "\/"           -> "/"       find_last_of matched forward slash only, so a
#                               Windows path never split and installRoot silently
#                               stayed at its default
#
# MSVC accepts all three, drops the backslash, and warns - into a build log
# nobody reads. Every one produced a plausible-looking wrong path rather than a
# failure, which is the expensive kind of bug: the launcher reported success and
# the game quietly ran the wrong environment.
#
# Path building in this program is almost entirely wide literals with
# backslashes, so the next one is a matter of time. /we4129 makes it a build
# failure instead of a warning.
if (MSVC)
    target_compile_options(SiltStrider PRIVATE /we4129)
    target_compile_options(SiltStriderFindMorrowind PRIVATE /we4129)
endif()

else (WIN32)
# ============================================================= POSIX build ==
#
# NOT COMPILED OR TESTED YET: written on a Windows box with no
# Linux toolchain. Expect the first Linux configure to shake out find_package
# names and link order before anything else does.

set(LAUNCHER_CONTENT_DIR ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/content)

# The content stack's POSIX ports lean on libcurl (transport, transparent
# gzip), OpenSSL (hashing, ECDSA, the certificate pin - and libcurl must be an
# OpenSSL build for the pin, which Debian/Ubuntu's libcurl4-openssl-dev is)
# and FreeType (the launcher's text).
find_package(CURL REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(Freetype REQUIRED)

# The launcher's own image decoding. Windows uses GDI+; there is no equivalent
# on POSIX, so PNG goes through libpng's simplified API and JPEG through
# libjpeg. Both are already build dependencies (OSG pulls them in), so this
# adds nothing to install or bundle.
#
# NOT osgDB, which was tried first: SiltStriderLauncher is a lean binary that
# does not link OSG, so it failed to link - and dragging a scene-graph library
# into the launcher for two images would make startup depend on osgPlugins
# being discoverable, which is fragility bought for nothing.
find_package(PNG REQUIRED)
find_package(JPEG REQUIRED)

# ---- the stub --------------------------------------------------------------
#
# Same self-containment constraint as the Windows stub, translated: no
# dependency a distro might not ship. libstdc++ and libgcc are linked
# statically, leaving glibc as the only dynamic dependency - the one library
# every distribution (SteamOS included) is guaranteed to carry, and one that
# is backward compatible as long as the build machine's glibc is OLDER than
# every player's. That is why the canonical build environment is Debian
# bullseye (see linux-build in the server vault): build there and the stub
# runs everywhere newer.
add_executable(SiltStrider main_posix.cpp)

target_link_options(SiltStrider PRIVATE -static-libstdc++ -static-libgcc)

# the launcher ---------------------------------------------------------- CR2: see the Windows
# section - the same crash report files.
set(LAUNCHER_CRASH_SOURCES
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashSession.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashReport.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashUpload.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashWindow.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/CrashFlow.cpp
    ${CMAKE_SOURCE_DIR}/apps/openmw/mwmp/ClientPlatform.cpp
)

add_executable(SiltStriderLauncher
    LauncherMain_posix.cpp
    ${LAUNCHER_CONTENT_DIR}/UpdateScreen.cpp
    ${LAUNCHER_CONTENT_DIR}/Sync.cpp
    ${LAUNCHER_CONTENT_DIR}/DiscordAuth.cpp
    ${LAUNCHER_CONTENT_DIR}/Http.cpp
    ${LAUNCHER_CONTENT_DIR}/HttpPosix.cpp
    ${LAUNCHER_CONTENT_DIR}/Json.cpp
    ${LAUNCHER_CONTENT_DIR}/Crypto.cpp
    ${LAUNCHER_CONTENT_DIR}/CryptoPosix.cpp
    ${LAUNCHER_CONTENT_DIR}/Morrowind.cpp
    ${LAUNCHER_CONTENT_DIR}/MorrowindPosix.cpp
    ${LAUNCHER_CONTENT_DIR}/Text.cpp
    ${LAUNCHER_CONTENT_DIR}/TextPosix.cpp
    ${LAUNCHER_CRASH_SOURCES}
)

target_include_directories(SiltStriderLauncher PRIVATE
    ${LAUNCHER_CONTENT_DIR}
    ${OpenMW_BINARY_DIR}
    ${CURL_INCLUDE_DIRS}
    ${OPENSSL_INCLUDE_DIR}
    ${FREETYPE_INCLUDE_DIRS}
    ${PNG_INCLUDE_DIRS}
    ${JPEG_INCLUDE_DIRS})

target_link_libraries(SiltStriderLauncher
    SDL2::SDL2
    ${CURL_LIBRARIES}
    ${OPENSSL_SSL_LIBRARY}
    ${OPENSSL_CRYPTO_LIBRARY}
    ${FREETYPE_LIBRARIES}
    ${PNG_LIBRARIES}
    ${JPEG_LIBRARIES}
    pthread)

target_link_options(SiltStriderLauncher PRIVATE -static-libstdc++ -static-libgcc)

if (TARGET silt-version)
    add_dependencies(SiltStriderLauncher silt-version)
endif()

# ---- content self-checks ---------------------------------------------------
#
# These two are the FIRST things to run on a fresh Linux build, before the
# game or the launcher: SiltStriderContentTest proves the OpenSSL crypto
# agrees with the Node publisher's signatures, and SiltStriderSync --verify
# exercises the whole transport + store path headlessly.
add_executable(SiltStriderContentTest
    ${LAUNCHER_CONTENT_DIR}/ContentTest.cpp
    ${LAUNCHER_CONTENT_DIR}/Crypto.cpp
    ${LAUNCHER_CONTENT_DIR}/CryptoPosix.cpp
    ${LAUNCHER_CONTENT_DIR}/Json.cpp
    # Start of tes3mp change
    ${LAUNCHER_CONTENT_DIR}/Sync.cpp
    ${LAUNCHER_CONTENT_DIR}/Morrowind.cpp
    ${LAUNCHER_CONTENT_DIR}/MorrowindPosix.cpp
    ${LAUNCHER_CONTENT_DIR}/Http.cpp
    ${LAUNCHER_CONTENT_DIR}/HttpPosix.cpp
    # End of tes3mp change
)
target_include_directories(SiltStriderContentTest PRIVATE ${LAUNCHER_CONTENT_DIR}
    ${CURL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR})
target_link_libraries(SiltStriderContentTest
    ${CURL_LIBRARIES} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} pthread)

add_executable(SiltStriderSync
    ${LAUNCHER_CONTENT_DIR}/SyncCli.cpp
    ${LAUNCHER_CONTENT_DIR}/Sync.cpp
    ${LAUNCHER_CONTENT_DIR}/Morrowind.cpp
    ${LAUNCHER_CONTENT_DIR}/MorrowindPosix.cpp
    ${LAUNCHER_CONTENT_DIR}/Http.cpp
    ${LAUNCHER_CONTENT_DIR}/HttpPosix.cpp
    ${LAUNCHER_CONTENT_DIR}/Crypto.cpp
    ${LAUNCHER_CONTENT_DIR}/CryptoPosix.cpp
    ${LAUNCHER_CONTENT_DIR}/Json.cpp
)
target_include_directories(SiltStriderSync PRIVATE ${LAUNCHER_CONTENT_DIR}
    ${CURL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR})
target_link_libraries(SiltStriderSync
    ${CURL_LIBRARIES} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} pthread)

add_executable(SiltStriderFindMorrowind
    ${LAUNCHER_CONTENT_DIR}/MorrowindFindCli.cpp
    ${LAUNCHER_CONTENT_DIR}/Morrowind.cpp
    ${LAUNCHER_CONTENT_DIR}/MorrowindPosix.cpp
)
target_include_directories(SiltStriderFindMorrowind PRIVATE ${LAUNCHER_CONTENT_DIR})

endif (WIN32)

# Start of tes3mp addition
# 0.51 port: the header-only rule checks below compile sources that live in the multiplayer
# client (apps/openmw/mwmp, mwmechanics, mwgui). A target is made only when its source is
# in this tree, so the launcher builds before the client port has landed and each check
# appears on its own once the file does.
function(silt_header_test name dir source)
    if (EXISTS ${CMAKE_SOURCE_DIR}/${dir}/${source})
        add_executable(${name} ${CMAKE_SOURCE_DIR}/${dir}/${source})
        target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR}/${dir})
        if (MSVC)
            target_compile_options(${name} PRIVATE
                $<$<CONFIG:Debug>:/MTd>
                $<$<NOT:$<CONFIG:Debug>>:/MT>)
        endif()
    endif()
endfunction()
# End of tes3mp addition

# checks for the ghost slot table (apps/openmw/mwmp/GhostSlots.hpp), which gives every vessel's
# ghost deck a slot of its own. Header-only and standard C++, so one target serves both platforms;
# the server repo's tools/tests/ghost-slots.lua runs it.
silt_header_test(SiltStriderGhostSlotsTest apps/openmw/mwmp GhostSlotsTest.cpp)

# P2-1M3: checks for the water strider's burst gait (apps/openmw/mwmp/BurstGait.hpp): the stroke
# profile, one clip cycle per stroke, the foot slide per stroke and the stroke detector. Header-only
# and standard C++; the server repo's tools/tests/burst-gait.lua runs it.
silt_header_test(SiltStriderBurstGaitTest apps/openmw/mwmp BurstGaitTest.cpp)

# P2M4: checks for the creature drive (apps/openmw/mwmp/CreatureDrive.hpp), the Immersive Riding
# mod's movement model: speed ratio ramp, brake and coast, turning, the clip rates. Header-only and
# standard C++; the server repo's tools/tests/mounts.lua runs it.
silt_header_test(SiltStriderCreatureDriveTest apps/openmw/mwmp CreatureDriveTest.cpp)

# checks for the cart tow rules (apps/openmw/mwmp/CartTow.hpp): the rigid drawbar, the Strength
# speed of pulling by hand, a mount's hitch, the wheels' field and turn. Header-only and standard
# C++; the server repo's tools/tests/carts.lua runs it.
silt_header_test(SiltStriderCartTowTest apps/openmw/mwmp CartTowTest.cpp)

# placement tilt: checks for the group-yaw compose and ESM Euler decompose
# (apps/openmw/mwmp/PlacementPose.hpp). Header-only and standard C++.
silt_header_test(SiltStriderPlacementPoseTest apps/openmw/mwmp PlacementPoseTest.cpp)

# checks for the body-width node scale (apps/openmw/mwmp/BodyScale.hpp), which keeps a character's
# race height and weight under a body width. Header-only and standard C++, so one target serves both
# platforms; the server repo's tools/tests/body-scale.lua runs it.
silt_header_test(SiltStriderBodyScaleTest apps/openmw/mwmp BodyScaleTest.cpp)

# AV1, the AIRIS 360 degree view: checks for the pure half (apps/openmw/mwmp/ViewStrip.hpp) -
# heading math, the cylindrical stitch of four faces, the labels and their stacking, the font, the
# upload chunking under the 64 KiB cut. Header-only and standard C++, so one target serves both
# platforms.
silt_header_test(SiltStriderViewStripTest apps/openmw/mwmp ViewStripTest.cpp)

# checks for the arrest window gate (apps/openmw/mwmechanics/ArrestGate.hpp) - no arrest dialogue
# opens, and none stays open, on a player a guard is fighting. Header-only and standard C++, so one
# target serves both platforms; the server repo's tools/tests/guard-fight-window.lua runs it.
silt_header_test(SiltStriderArrestGateTest apps/openmw/mwmechanics ArrestGateTest.cpp)

# checks for the per-faction bounty list the character sheet shows
# (apps/openmw/mwgui/FactionBountyList.hpp) - rows added on the fly, a row at 0 gone, Total bounty
# the sum. Header-only and standard C++, so one target serves both platforms; the server repo's
# tools/tests/guard-recognition.lua runs it.
silt_header_test(SiltStriderFactionBountyTest apps/openmw/mwgui FactionBountyListTest.cpp)

# checks for the frontier wall's rule (apps/openmw/mwmp/FrontierRule.hpp) - which points of Distant
# Landscapes of Tamriel's cells are walled, and how a step against the wall is held and slides.
# Header-only and standard C++, so one target serves both platforms; the server repo's
# tools/tests/frontier.lua runs it.
silt_header_test(SiltStriderFrontierTest apps/openmw/mwmp FrontierTest.cpp)

# RC1-D6b, checks for the faction alias and faction leave (apps/openmw/mwmp/FactionAlias.hpp) - one
# guild under every regional id, the fold of rows that arrived before the table, the merged
# reactions, and a RANK row below 0 as a clean leave. Header-only and standard C++, so one target
# serves both platforms; the server repo's tools/tests/faction-alias.lua runs it, and replays the
# server's own packets through it (--replay).
silt_header_test(SiltStriderFactionAliasTest apps/openmw/mwmp FactionAliasTest.cpp)

# checks for the one-murder-per-victim ledger (apps/openmw/mwmp/MurderOnce.hpp) - an NPC another
# client runs, re-killed on the killer's client while the authority's stale health resurrects her,
# is one murder; a real resurrection is a new life. Header-only and standard C++, so one target
# serves both platforms.
silt_header_test(SiltStriderMurderOnceTest apps/openmw/mwmp MurderOnceTest.cpp)

# the quick exit at the end of a normal quit (apps/openmw/quickexit.hpp) - its step runner, and
# source checks on the order main.cpp, engine.cpp, Networking.cpp, debugging.cpp and the crash
# catcher follow (the server told first, the world never freed). Header-only and standard C++, so
# one target serves both platforms. The server repo's tools/tests/quick-exit.lua runs it.
silt_header_test(SiltStriderQuickExitTest apps/openmw QuickExitTest.cpp)

# Active block and parry (siltstrider 772bd51718.. 5ba5dab674): the skill ladder, the perfect parry
# window, the fatigue drain, the per-tool and per-material tables, held to the mod's own numbers.
# Header-only (apps/openmw/mwmechanics/parrytables.hpp) and standard C++; apps/openmw/MiniGTest.hpp
# stands in for googletest, so one target serves both platforms.
silt_header_test(SiltStriderParryTablesTest apps/openmw/mwmechanics ParryTablesTest.cpp)

# The world map's province labels (siltstrider 15a8622461, 1f0d2ca28c): the zoom bands and their
# crossfade (mapzoomfade.hpp), the border polyline smoothing (mapsmoothing.hpp) and the label
# push-apart (maplabellayout.hpp). All three are engine-free headers; MiniGTest.hpp stands in for
# googletest.
silt_header_test(SiltStriderMapZoomFadeTest apps/openmw/mwgui MapZoomFadeTest.cpp)

# (siltstrider fceeaa15d): checks who owns the first-person look pitch
# (apps/openmw/mwrender/lookpitchrule.hpp) - a posed rider's look holds while the hull turns his
# body, the hand-back when the pose ends, third person and the ground unchanged - on a model of the
# camera's arithmetic. Header only, standard library only. The server repo's
# tools/tests/ride-look-pitch.lua runs it.
silt_header_test(SiltStriderLookPitchTest apps/openmw/mwrender LookPitchTest.cpp)

# Reset Controls to Default and the packaged defaults (siltstrider 16d156dcc2, fc3d46591d): the
# shipped files/siltstrider/defaults/input_v3.xml and the compiled table in
# apps/openmw/mwinput/defaultbindings.hpp must say the same thing, action by action. Standard C++
# and SDL's headers only.
if (EXISTS ${CMAKE_SOURCE_DIR}/apps/openmw/mwinput/DefaultBindingsTest.cpp)
    add_executable(SiltStriderDefaultBindingsTest ${CMAKE_SOURCE_DIR}/apps/openmw/mwinput/DefaultBindingsTest.cpp)
    target_include_directories(SiltStriderDefaultBindingsTest PRIVATE ${CMAKE_SOURCE_DIR}/apps/openmw/mwinput)
    target_link_libraries(SiltStriderDefaultBindingsTest SDL2::SDL2)
    target_compile_definitions(SiltStriderDefaultBindingsTest PRIVATE
        SILTSTRIDER_INPUT_DEFAULTS_XML="${CMAKE_SOURCE_DIR}/files/siltstrider/defaults/input_v3.xml")
    if (MSVC)
        target_compile_options(SiltStriderDefaultBindingsTest PRIVATE
            $<$<CONFIG:Debug>:/MTd>
            $<$<NOT:$<CONFIG:Debug>>:/MT>)
    endif()
endif()
