Files
dayz-dma/CMakeLists.txt
T

313 lines
12 KiB
CMake

cmake_minimum_required(VERSION 3.20)
project(dayz-memory-cpp CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# -------------------------------------------------------------------------
# Platform guard
# -------------------------------------------------------------------------
if(NOT WIN32)
message(FATAL_ERROR "dayz-memory-cpp is Windows-only (requires VolkDMA / WinAPI)")
endif()
# -------------------------------------------------------------------------
# Paths to VolkDMA (sibling checkout)
# -------------------------------------------------------------------------
set(VOLKDMA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../dayz-dma/dma-dayz-cpp-master/VolkDMA")
# -------------------------------------------------------------------------
# Dependencies — nlohmann/json, spdlog via FetchContent; ImGui from local copy
# -------------------------------------------------------------------------
include(FetchContent)
FetchContent_Declare(json
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz
URL_HASH SHA256=d6c65aca6b1ed68e7a182f4757257b107ae403032760ed6ef121c9d55e81757d
)
FetchContent_Declare(spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.14.1
GIT_SHALLOW TRUE
)
# cpp-httplib — header-only HTTP/1.1 server used by WebRadarServer
FetchContent_Declare(httplib
GIT_REPOSITORY https://github.com/yhirose/cpp-httplib.git
GIT_TAG v0.18.1
GIT_SHALLOW TRUE
)
# stb — single-file image load/write libraries
FetchContent_Declare(stb
GIT_REPOSITORY https://github.com/nothings/stb.git
GIT_TAG master
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(json spdlog httplib stb)
# Vendored Lumin ImGui (1.91.3 + FreeType) and its menu framework.
set(LUMIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/lumin")
set(IMGUI_DIR "${LUMIN_DIR}/thirdparty/imgui")
set(FREETYPE_DIR "${LUMIN_DIR}/thirdparty/freetype")
set(FRAMEWORK_DIR "${LUMIN_DIR}/framework")
# -------------------------------------------------------------------------
# ImGui sources (Lumin's bundled ImGui + FreeType atlas builder)
# -------------------------------------------------------------------------
set(IMGUI_SOURCES
"${IMGUI_DIR}/imgui.cpp"
"${IMGUI_DIR}/imgui_draw.cpp"
"${IMGUI_DIR}/imgui_tables.cpp"
"${IMGUI_DIR}/imgui_widgets.cpp"
"${IMGUI_DIR}/imgui_freetype.cpp"
"${IMGUI_DIR}/backends/imgui_impl_win32.cpp"
"${IMGUI_DIR}/backends/imgui_impl_dx11.cpp"
)
# -------------------------------------------------------------------------
# Lumin menu framework sources (the actual menu UI)
# -------------------------------------------------------------------------
set(FRAMEWORK_SOURCES
"${FRAMEWORK_DIR}/gui.cpp"
"${FRAMEWORK_DIR}/helpers/draw.cpp"
"${FRAMEWORK_DIR}/helpers/fonts.cpp"
"${FRAMEWORK_DIR}/widgets/helpers.cpp"
"${FRAMEWORK_DIR}/widgets/notify.cpp"
"${FRAMEWORK_DIR}/widgets/text_field.cpp"
"${FRAMEWORK_DIR}/widgets/widgets.cpp"
"${FRAMEWORK_DIR}/widgets/window.cpp"
)
# -------------------------------------------------------------------------
# Sources — project + VolkDMA implementation files
# -------------------------------------------------------------------------
file(GLOB_RECURSE PROJECT_SOURCES "src/*.cpp")
# Explicit list ensures new files are picked up without a CMake cache reset.
list(APPEND PROJECT_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/SigScanner/SigScanner.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/Overlay/OverlayWindow.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/Overlay/GameOverlay.cpp"
)
list(REMOVE_DUPLICATES PROJECT_SOURCES)
set(VOLKDMA_SOURCES
"${VOLKDMA_ROOT}/src/dma.cpp"
"${VOLKDMA_ROOT}/src/process.cpp"
"${VOLKDMA_ROOT}/src/inputstate.cpp"
)
# -------------------------------------------------------------------------
# Embed map PNGs as Windows RCDATA resources
#
# Maps present in maps/ at configure time are baked into the binary so the
# server works out-of-the-box without copying anything next to the exe.
# A PNG placed on disk at runtime (maps/<id>.png next to the exe) still
# takes priority, so maps can be updated without rebuilding.
#
# Re-run CMake if you add new PNGs to maps/ after the initial configure.
# -------------------------------------------------------------------------
set(MAPS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/maps")
set(EMBEDDED_MAPS_RC "${CMAKE_CURRENT_BINARY_DIR}/maps_embedded.rc")
set(EMBEDDED_MAPS_CPP "${CMAKE_CURRENT_BINARY_DIR}/EmbeddedMaps.cpp")
set(MAP_IDS chernarusplus livonia namalsk banov deadfall deerisle esseker lux sakhal takistan alteria)
set(MAP_RIDS 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011)
set(RC_LINES "")
set(CPP_CASES "")
foreach(MAP_ID MAP_RID IN ZIP_LISTS MAP_IDS MAP_RIDS)
if(EXISTS "${MAPS_SOURCE_DIR}/${MAP_ID}.png")
string(APPEND RC_LINES "${MAP_RID} RCDATA \"${MAPS_SOURCE_DIR}/${MAP_ID}.png\"\n")
string(APPEND CPP_CASES " if (mapId == \"${MAP_ID}\") return LoadRcData(${MAP_RID});\n")
message(STATUS "Embedding map: ${MAP_ID}")
else()
message(STATUS "Skipping map (not found): ${MAP_ID}")
endif()
endforeach()
file(WRITE "${EMBEDDED_MAPS_RC}" "// Auto-generated by CMake — do not edit.\n${RC_LINES}")
file(WRITE "${EMBEDDED_MAPS_CPP}"
"// Auto-generated by CMake — do not edit.
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <cstdint>
#include <utility>
#include \"EmbeddedMaps.h\"
static std::pair<const uint8_t*, size_t> LoadRcData(int resourceId) {
HRSRC hRes = FindResource(nullptr, MAKEINTRESOURCE(resourceId), RT_RCDATA);
if (!hRes) return {nullptr, 0};
HGLOBAL hData = LoadResource(nullptr, hRes);
if (!hData) return {nullptr, 0};
const void* ptr = LockResource(hData);
DWORD sz = SizeofResource(nullptr, hRes);
if (!ptr || sz == 0) return {nullptr, 0};
return {static_cast<const uint8_t*>(ptr), sz};
}
std::pair<const uint8_t*, size_t> GetEmbeddedMap(const std::string& mapId) {
${CPP_CASES} return {nullptr, 0};
}
")
add_executable(dayz-memory-cpp
${PROJECT_SOURCES}
${VOLKDMA_SOURCES}
${IMGUI_SOURCES}
${FRAMEWORK_SOURCES}
)
# Wire in the generated RC + CPP files.
target_sources(dayz-memory-cpp PRIVATE
"${EMBEDDED_MAPS_RC}"
"${EMBEDDED_MAPS_CPP}"
)
# -------------------------------------------------------------------------
# Include directories
# -------------------------------------------------------------------------
target_include_directories(dayz-memory-cpp PRIVATE
# Own source tree
"${CMAKE_CURRENT_SOURCE_DIR}/src"
# ImGui core + Win32/DX11 backends
"${IMGUI_DIR}"
"${IMGUI_DIR}/backends"
# FreeType headers (atlas builder)
"${FREETYPE_DIR}/include"
# Lumin framework root — lets sources include "framework/headers/includes.h"
"${LUMIN_DIR}"
"${FRAMEWORK_DIR}"
# VolkDMA repo root — VolkDMA's own source files use paths like
# "include/VolkDMA/dma.hh" and "external/vmm/vmmdll.h" that are
# relative to this root, so this entry must come first.
"${VOLKDMA_ROOT}"
# VolkDMA public headers (provides <VolkDMA/dma.hh> etc.)
"${VOLKDMA_ROOT}/include"
# VolkLog (required by VolkDMA's dma.cpp / process.cpp)
"${VOLKDMA_ROOT}/external/VolkLog/include"
# Raw vmmdll / leechcore headers (used in VmmAccessor.cpp + VolkDMA sources)
"${VOLKDMA_ROOT}/external/vmm"
"${VOLKDMA_ROOT}/external/leechcore"
# cpp-httplib (header-only; FetchContent populates httplib_SOURCE_DIR)
"${httplib_SOURCE_DIR}"
# stb (header-only image library; stb_impl.cpp provides the implementation)
"${stb_SOURCE_DIR}"
)
# -------------------------------------------------------------------------
# Link directories
# -------------------------------------------------------------------------
target_link_directories(dayz-memory-cpp PRIVATE
"${VOLKDMA_ROOT}/external/vmm"
"${VOLKDMA_ROOT}/external/leechcore"
)
# -------------------------------------------------------------------------
# Link libraries
# -------------------------------------------------------------------------
target_link_libraries(dayz-memory-cpp PRIVATE
nlohmann_json::nlohmann_json
spdlog::spdlog
vmm
leechcore
# FreeType (prebuilt x64) — Lumin font atlas builder
"${FREETYPE_DIR}/win64/freetype.lib"
# DirectX 11 + DXGI (for ImGui DX11 window)
d3d11
dxgi
# WinSock2 — required by cpp-httplib on Windows
Ws2_32
)
# -------------------------------------------------------------------------
# Post-build: copy VolkDMA runtime DLLs next to the executable.
# Without these (vmm.dll, leechcore.dll, FTD3XX.dll) the process exits with
# 0xC0000135 (STATUS_DLL_NOT_FOUND) immediately on launch.
# -------------------------------------------------------------------------
set(VOLKDMA_DLLS_DIR "${VOLKDMA_ROOT}/dlls")
foreach(DLL vmm.dll leechcore.dll FTD3XX.dll)
add_custom_command(TARGET dayz-memory-cpp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${VOLKDMA_DLLS_DIR}/${DLL}"
"$<TARGET_FILE_DIR:dayz-memory-cpp>/${DLL}"
COMMENT "Copying ${DLL} to output directory"
)
endforeach()
# Copy webroot/ directory next to the executable so the HTTP server can serve it.
add_custom_command(TARGET dayz-memory-cpp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_SOURCE_DIR}/webroot"
"$<TARGET_FILE_DIR:dayz-memory-cpp>/webroot"
COMMENT "Copying webroot to output directory"
)
# Copy the Lumin icon font next to the executable so the menu's tab icons load
# (flaticon_uicons_regular_rounded_path is resolved relative to the work dir).
add_custom_command(TARGET dayz-memory-cpp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${FRAMEWORK_DIR}/data/uicons"
"$<TARGET_FILE_DIR:dayz-memory-cpp>/data/uicons"
COMMENT "Copying Lumin uicons font to output directory"
)
# Copy config/ directory next to the executable (config.cfg, item_filters.json).
add_custom_command(TARGET dayz-memory-cpp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_SOURCE_DIR}/config"
"$<TARGET_FILE_DIR:dayz-memory-cpp>/config"
COMMENT "Copying config to output directory"
)
# Copy maps/ directory next to the executable so MapTileService can find PNGs.
# maps/ is git-ignored (user-supplied), so only copy when it exists.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maps")
add_custom_command(TARGET dayz-memory-cpp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_SOURCE_DIR}/maps"
"$<TARGET_FILE_DIR:dayz-memory-cpp>/maps"
COMMENT "Copying maps to output directory"
)
endif()
# -------------------------------------------------------------------------
# Compiler definitions
# -------------------------------------------------------------------------
target_compile_definitions(dayz-memory-cpp PRIVATE
_WIN32_WINNT=0x0601
# Build the ImGui font atlas with FreeType (Lumin requirement; also set in
# the vendored imconfig.h, kept here so every TU agrees).
IMGUI_ENABLE_FREETYPE
IMGUI_DEFINE_MATH_OPERATORS
# WIN32_LEAN_AND_MEAN is intentionally NOT set globally: vmmdll.h requires
# NTSTATUS from <winternl.h>, which windows.h omits when LEAN_AND_MEAN is
# defined. Our own headers define it locally before including <Windows.h>.
NOMINMAX
)
# -------------------------------------------------------------------------
# MSVC-specific flags
# -------------------------------------------------------------------------
if(MSVC)
target_compile_options(dayz-memory-cpp PRIVATE
/W4
/WX- # vmmdll / VolkDMA headers generate some W4 noise
/permissive-
/utf-8
)
endif()