Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d12e4e099 |
+72
-40
@@ -6,14 +6,11 @@ variables:
|
||||
DOCKER_HOST: tcp://docker:2375
|
||||
DOCKER_DRIVER: overlay2
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
# Where to push the dev image. Leave empty to not push at all.
|
||||
# Examples: "192.168.1.11:9090/<group>/openra3" or "docker.io/<user>/openra3"
|
||||
IMAGE_NAME: ""
|
||||
DOCKER_BUILDKIT: "1"
|
||||
# apt mirror used inside both images (override per pipeline if needed)
|
||||
APT_MIRROR: "http://mirrors.tuna.tsinghua.edu.cn/ubuntu"
|
||||
|
||||
image_build:
|
||||
stage: image
|
||||
image: docker:latest
|
||||
.dind: &dind
|
||||
services:
|
||||
- name: docker:dind
|
||||
# Pull docker.io images through the intranet Harbor pull-through cache;
|
||||
@@ -21,44 +18,79 @@ image_build:
|
||||
command:
|
||||
- --registry-mirror=http://192.168.1.11:9090/dockerhub
|
||||
- --insecure-registry=192.168.1.11:9090
|
||||
script:
|
||||
- docker build --target dev -t openra3-dev:local --build-arg APT_MIRROR=$APT_MIRROR .
|
||||
- docker save openra3-dev:local -o dev-image.tar
|
||||
- |
|
||||
if [ -n "$IMAGE_NAME" ]; then
|
||||
# add `docker login` here if IMAGE_NAME points to a private registry
|
||||
docker tag openra3-dev:local $IMAGE_NAME:$CI_COMMIT_SHORT_SHA
|
||||
docker push $IMAGE_NAME:$CI_COMMIT_SHORT_SHA
|
||||
fi
|
||||
artifacts:
|
||||
name: "dev-image-$CI_COMMIT_SHORT_SHA"
|
||||
paths:
|
||||
- dev-image.tar
|
||||
expire_in: 1 day
|
||||
|
||||
# --- build the two isolated toolchain images ---------------------------------
|
||||
linux_image:
|
||||
stage: image
|
||||
image: docker:latest
|
||||
services: *dind
|
||||
tags:
|
||||
- docker
|
||||
script:
|
||||
- docker build --target dev -t openra3-linux:local --build-arg APT_MIRROR=$APT_MIRROR .
|
||||
- docker save openra3-linux:local -o linux-image.tar
|
||||
artifacts:
|
||||
name: "linux-image-$CI_COMMIT_SHORT_SHA"
|
||||
paths:
|
||||
- linux-image.tar
|
||||
expire_in: 1 day
|
||||
|
||||
build_test_package:
|
||||
windows_image:
|
||||
stage: image
|
||||
image: docker:latest
|
||||
services: *dind
|
||||
tags:
|
||||
- docker
|
||||
script:
|
||||
- docker build -f Dockerfile.win --target dev -t openra3-windows:local --build-arg APT_MIRROR=$APT_MIRROR .
|
||||
- docker save openra3-windows:local -o windows-image.tar
|
||||
artifacts:
|
||||
name: "windows-image-$CI_COMMIT_SHORT_SHA"
|
||||
paths:
|
||||
- windows-image.tar
|
||||
expire_in: 1 day
|
||||
|
||||
# --- build and test each target ----------------------------------------------
|
||||
build_linux:
|
||||
stage: build
|
||||
image: docker:latest
|
||||
services:
|
||||
- name: docker:dind
|
||||
command:
|
||||
- --registry-mirror=http://192.168.1.11:9090/dockerhub
|
||||
- --insecure-registry=192.168.1.11:9090
|
||||
needs:
|
||||
- image_build
|
||||
before_script:
|
||||
- docker load -i dev-image.tar
|
||||
script:
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-dev:local cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-dev:local cmake --build build -j
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-dev:local ctest --test-dir build --output-on-failure
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-dev:local bash -c "mkdir -p artifacts_bin && cp build/bin/openra3 artifacts_bin/"
|
||||
artifacts:
|
||||
name: "$CI_PROJECT_NAME-executables-$CI_COMMIT_SHORT_SHA"
|
||||
paths:
|
||||
- artifacts_bin/
|
||||
expire_in: 7 days
|
||||
services: *dind
|
||||
tags:
|
||||
- docker
|
||||
needs:
|
||||
- linux_image
|
||||
before_script:
|
||||
- docker load -i linux-image.tar
|
||||
script:
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-linux:local cmake -S . -B build/linux -G Ninja -DCMAKE_BUILD_TYPE=Release
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-linux:local cmake --build build/linux -j
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-linux:local ctest --test-dir build/linux --output-on-failure
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-linux:local bash -c "mkdir -p artifacts/linux && cp build/linux/bin/openra3 artifacts/linux/"
|
||||
artifacts:
|
||||
name: "$CI_PROJECT_NAME-linux-$CI_COMMIT_SHORT_SHA"
|
||||
paths:
|
||||
- artifacts/linux/
|
||||
expire_in: 7 days
|
||||
|
||||
build_windows:
|
||||
stage: build
|
||||
image: docker:latest
|
||||
services: *dind
|
||||
tags:
|
||||
- docker
|
||||
needs:
|
||||
- windows_image
|
||||
before_script:
|
||||
- docker load -i windows-image.tar
|
||||
script:
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-windows:local
|
||||
cmake -S . -B build/windows -G Ninja
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/llvm-mingw-x86_64.cmake
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-windows:local cmake --build build/windows -j
|
||||
- docker run --rm -v "$(pwd):/work" -w /work openra3-windows:local bash -c "mkdir -p artifacts/windows && cp build/windows/bin/openra3.exe build/windows/bin/SDL3.dll artifacts/windows/"
|
||||
artifacts:
|
||||
name: "$CI_PROJECT_NAME-windows-$CI_COMMIT_SHORT_SHA"
|
||||
paths:
|
||||
- artifacts/windows/
|
||||
expire_in: 7 days
|
||||
|
||||
+107
-94
@@ -1,10 +1,31 @@
|
||||
cmake_minimum_required(VERSION 3.28)
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
|
||||
project(OpenRA3 VERSION 0.0.1 LANGUAGES CXX)
|
||||
# --- C++26 modules + `import std;` (clang + libc++) -------------------------
|
||||
# CMake gates `import std` behind an experimental value documented in
|
||||
# Help/dev/experimental.rst for the CMake version in use.
|
||||
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
|
||||
|
||||
# Path to the standard-library module description. A cross toolchain overrides
|
||||
# this before the compiler is probed; this default targets the Linux LLVM
|
||||
# package.
|
||||
if(NOT CMAKE_CXX_STDLIB_MODULES_JSON)
|
||||
set(CMAKE_CXX_STDLIB_MODULES_JSON "/usr/lib/llvm-21/lib/libc++.modules.json")
|
||||
endif()
|
||||
|
||||
# libc++ must be selected before the compiler is probed: CMake builds its
|
||||
# internal standard-library module target during `project()`, and that target
|
||||
# only sees `CMAKE_CXX_FLAGS` (not later `add_compile_options`). The standard
|
||||
# and extension settings must also be in place before `project()` so the
|
||||
# internal `std.pcm` is built with the same configuration as our modules.
|
||||
set(CMAKE_CXX_FLAGS_INIT "-stdlib=libc++")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-stdlib=libc++")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-stdlib=libc++")
|
||||
set(CMAKE_CXX_STANDARD 26)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
|
||||
|
||||
project(OpenRA3 VERSION 0.1.0 LANGUAGES CXX)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
|
||||
@@ -15,121 +36,113 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
option(OPENRA3_WERROR "Treat warnings as errors" OFF)
|
||||
|
||||
function(openra3_target_defaults target)
|
||||
target_compile_options(${target} PRIVATE -Wall -Wextra -Wpedantic)
|
||||
target_compile_options(${target} PRIVATE -Wall -Wextra)
|
||||
set_property(TARGET ${target} PROPERTY CXX_MODULE_STD ON)
|
||||
if(OPENRA3_WERROR)
|
||||
target_compile_options(${target} PRIVATE -Werror)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# --- engine core: fundamental types, math, strings, random, message stream ---
|
||||
add_library(ra3_core STATIC)
|
||||
target_sources(ra3_core
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/core/ra3.core.cppm
|
||||
)
|
||||
openra3_target_defaults(ra3_core)
|
||||
|
||||
# --- game logic: objects, players, teams, spatial partition, game loop ---
|
||||
add_library(ra3_logic STATIC)
|
||||
target_sources(ra3_logic
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/logic/ra3.logic.cppm
|
||||
)
|
||||
target_link_libraries(ra3_logic PUBLIC ra3_core)
|
||||
openra3_target_defaults(ra3_logic)
|
||||
|
||||
# --- client: headless display/input abstraction and the client facade ---
|
||||
add_library(ra3_client STATIC)
|
||||
target_sources(ra3_client
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/client/ra3.client.cppm
|
||||
)
|
||||
target_link_libraries(ra3_client PUBLIC ra3_core ra3_logic)
|
||||
openra3_target_defaults(ra3_client)
|
||||
|
||||
# --- RA3 game definitions: factions, player templates, science, special powers ---
|
||||
add_library(ra3_game STATIC)
|
||||
target_sources(ra3_game
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/game/ra3.game.cppm
|
||||
)
|
||||
target_link_libraries(ra3_game PUBLIC ra3_core ra3_logic)
|
||||
openra3_target_defaults(ra3_game)
|
||||
|
||||
# --- filesystem: BIG4 archives, RefPack codec, local install locator ---
|
||||
add_library(ra3_fs STATIC)
|
||||
target_sources(ra3_fs
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/fs/ra3.fs.cppm
|
||||
)
|
||||
target_link_libraries(ra3_fs PUBLIC ra3_core)
|
||||
openra3_target_defaults(ra3_fs)
|
||||
|
||||
# --- map discovery/loading (real .big data, user's local install) ---
|
||||
add_library(ra3_map STATIC)
|
||||
target_sources(ra3_map
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/map/ra3.map.cppm
|
||||
)
|
||||
target_link_libraries(ra3_map PUBLIC ra3_core ra3_fs)
|
||||
openra3_target_defaults(ra3_map)
|
||||
|
||||
# --- minimal headless skirmish simulation ---
|
||||
add_library(ra3_skirmish STATIC)
|
||||
target_sources(ra3_skirmish
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/skirmish/ra3.skirmish.cppm
|
||||
)
|
||||
target_link_libraries(ra3_skirmish PUBLIC ra3_core ra3_logic ra3_game ra3_map)
|
||||
openra3_target_defaults(ra3_skirmish)
|
||||
|
||||
# --- software renderer: framebuffer, TGA decode, BMP encode, map compositing ---
|
||||
add_library(ra3_render STATIC)
|
||||
target_sources(ra3_render
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/render/ra3.render.cppm
|
||||
)
|
||||
target_link_libraries(ra3_render PUBLIC ra3_core)
|
||||
openra3_target_defaults(ra3_render)
|
||||
|
||||
# --- windowed viewer: SDL3 when available, otherwise a null backend ---
|
||||
# --- SDL3: pkg-config on Linux, or an explicit MinGW root for Windows --------
|
||||
add_library(openra3_sdl3 INTERFACE)
|
||||
set(OPENRA3_HAS_SDL3 OFF)
|
||||
if(OPENRA3_SDL3_ROOT)
|
||||
target_include_directories(openra3_sdl3 INTERFACE "${OPENRA3_SDL3_ROOT}/x86_64-w64-mingw32/include")
|
||||
target_link_libraries(openra3_sdl3 INTERFACE "${OPENRA3_SDL3_ROOT}/x86_64-w64-mingw32/lib/libSDL3.dll.a")
|
||||
set(OPENRA3_HAS_SDL3 ON)
|
||||
else()
|
||||
find_package(PkgConfig QUIET)
|
||||
if(PkgConfig_FOUND)
|
||||
pkg_check_modules(SDL3 QUIET IMPORTED_TARGET sdl3)
|
||||
endif()
|
||||
add_library(ra3_ui STATIC)
|
||||
if(SDL3_FOUND)
|
||||
target_sources(ra3_ui
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/ui/ra3.ui.sdl.cppm
|
||||
)
|
||||
target_link_libraries(ra3_ui PUBLIC ra3_core ra3_render PkgConfig::SDL3)
|
||||
message(STATUS "OpenRA3: SDL3 ${SDL3_VERSION} found - windowed viewer enabled")
|
||||
target_link_libraries(openra3_sdl3 INTERFACE PkgConfig::SDL3)
|
||||
set(OPENRA3_HAS_SDL3 ON)
|
||||
endif()
|
||||
endif()
|
||||
if(OPENRA3_HAS_SDL3)
|
||||
message(STATUS "OpenRA3: SDL3 found - windowed viewer enabled")
|
||||
else()
|
||||
target_sources(ra3_ui
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/ui/ra3.ui.null.cppm
|
||||
)
|
||||
target_link_libraries(ra3_ui PUBLIC ra3_core ra3_render)
|
||||
message(STATUS "OpenRA3: SDL3 not found - offscreen BMP output only")
|
||||
endif()
|
||||
|
||||
# --- engine core -------------------------------------------------------------
|
||||
add_library(ra3_core STATIC)
|
||||
target_sources(ra3_core PUBLIC FILE_SET CXX_MODULES FILES src/core/ra3.core.cppm)
|
||||
openra3_target_defaults(ra3_core)
|
||||
|
||||
# --- game logic --------------------------------------------------------------
|
||||
add_library(ra3_logic STATIC)
|
||||
target_sources(ra3_logic PUBLIC FILE_SET CXX_MODULES FILES src/logic/ra3.logic.cppm)
|
||||
target_link_libraries(ra3_logic PUBLIC ra3_core)
|
||||
openra3_target_defaults(ra3_logic)
|
||||
|
||||
# --- client ------------------------------------------------------------------
|
||||
add_library(ra3_client STATIC)
|
||||
target_sources(ra3_client PUBLIC FILE_SET CXX_MODULES FILES src/client/ra3.client.cppm)
|
||||
target_link_libraries(ra3_client PUBLIC ra3_core ra3_logic)
|
||||
openra3_target_defaults(ra3_client)
|
||||
|
||||
# --- RA3 game definitions ----------------------------------------------------
|
||||
add_library(ra3_game STATIC)
|
||||
target_sources(ra3_game PUBLIC FILE_SET CXX_MODULES FILES src/game/ra3.game.cppm)
|
||||
target_link_libraries(ra3_game PUBLIC ra3_core ra3_logic)
|
||||
openra3_target_defaults(ra3_game)
|
||||
|
||||
# --- filesystem: BIG4 + RefPack ---------------------------------------------
|
||||
add_library(ra3_fs STATIC)
|
||||
target_sources(ra3_fs PUBLIC FILE_SET CXX_MODULES FILES src/fs/ra3.fs.cppm)
|
||||
target_link_libraries(ra3_fs PUBLIC ra3_core)
|
||||
openra3_target_defaults(ra3_fs)
|
||||
|
||||
# --- map discovery/loading ---------------------------------------------------
|
||||
add_library(ra3_map STATIC)
|
||||
target_sources(ra3_map PUBLIC FILE_SET CXX_MODULES FILES src/map/ra3.map.cppm)
|
||||
target_link_libraries(ra3_map PUBLIC ra3_core ra3_fs)
|
||||
openra3_target_defaults(ra3_map)
|
||||
|
||||
# --- minimal skirmish simulation --------------------------------------------
|
||||
add_library(ra3_skirmish STATIC)
|
||||
target_sources(ra3_skirmish PUBLIC FILE_SET CXX_MODULES FILES src/skirmish/ra3.skirmish.cppm)
|
||||
target_link_libraries(ra3_skirmish PUBLIC ra3_core ra3_logic ra3_game ra3_map)
|
||||
openra3_target_defaults(ra3_skirmish)
|
||||
|
||||
# --- software renderer -------------------------------------------------------
|
||||
add_library(ra3_render STATIC)
|
||||
target_sources(ra3_render PUBLIC FILE_SET CXX_MODULES FILES src/render/ra3.render.cppm)
|
||||
target_link_libraries(ra3_render PUBLIC ra3_core)
|
||||
openra3_target_defaults(ra3_render)
|
||||
|
||||
# --- windowed viewer (SDL3 or null) -----------------------------------------
|
||||
add_library(ra3_ui STATIC)
|
||||
if(OPENRA3_HAS_SDL3)
|
||||
target_sources(ra3_ui PUBLIC FILE_SET CXX_MODULES FILES src/ui/ra3.ui.sdl.cppm)
|
||||
target_link_libraries(ra3_ui PUBLIC ra3_core ra3_render openra3_sdl3)
|
||||
else()
|
||||
target_sources(ra3_ui PUBLIC FILE_SET CXX_MODULES FILES src/ui/ra3.ui.null.cppm)
|
||||
target_link_libraries(ra3_ui PUBLIC ra3_core ra3_render)
|
||||
endif()
|
||||
openra3_target_defaults(ra3_ui)
|
||||
|
||||
# --- umbrella module re-exporting the whole SDK ---
|
||||
# --- umbrella -----------------------------------------------------------------
|
||||
add_library(ra3 STATIC)
|
||||
target_sources(ra3
|
||||
PUBLIC FILE_SET CXX_MODULES FILES
|
||||
src/ra3.cppm
|
||||
)
|
||||
target_sources(ra3 PUBLIC FILE_SET CXX_MODULES FILES src/ra3.cppm)
|
||||
target_link_libraries(ra3 PUBLIC ra3_core ra3_logic ra3_client ra3_game ra3_fs ra3_map ra3_skirmish ra3_render ra3_ui)
|
||||
openra3_target_defaults(ra3)
|
||||
|
||||
# --- the headless game executable ---
|
||||
# --- executable ---------------------------------------------------------------
|
||||
add_executable(openra3 apps/openra3/main.cpp)
|
||||
target_link_libraries(openra3 PRIVATE ra3)
|
||||
openra3_target_defaults(openra3)
|
||||
|
||||
# --- unit tests ---
|
||||
if(WIN32 AND OPENRA3_SDL3_ROOT)
|
||||
add_custom_command(TARGET openra3 POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${OPENRA3_SDL3_ROOT}/x86_64-w64-mingw32/bin/SDL3.dll"
|
||||
"$<TARGET_FILE_DIR:openra3>")
|
||||
endif()
|
||||
|
||||
# --- tests --------------------------------------------------------------------
|
||||
enable_testing()
|
||||
add_executable(ra3_tests tests/ra3_tests.cpp)
|
||||
target_link_libraries(ra3_tests PRIVATE ra3)
|
||||
|
||||
+19
-17
@@ -1,7 +1,9 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# dev target: full toolchain + debug tools for development and debugging.
|
||||
# Base image and compiler are the latest stable (ubuntu:26.04 ships gcc/g++ 16).
|
||||
# Linux build environment. Isolated from the Windows cross image (Dockerfile.win)
|
||||
# so the two toolchains and their standard libraries never interfere.
|
||||
#
|
||||
# dev target: clang + libc++ (for `import std;`) + SDL3 + debug tools.
|
||||
FROM ubuntu:26.04 AS dev
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
@@ -23,44 +25,44 @@ RUN --mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
sleep 5; \
|
||||
done \
|
||||
&& apt-get -o Acquire::Retries=5 install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
clang-21 \
|
||||
clang-tools-21 \
|
||||
cmake \
|
||||
g++-16 \
|
||||
gdb \
|
||||
git \
|
||||
libc++-21-dev \
|
||||
libc++abi-21-dev \
|
||||
libsdl3-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Pin the toolchain to GCC 16 (the distro default is still GCC 15).
|
||||
ENV CC=gcc-16
|
||||
ENV CXX=g++-16
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-16 100 \
|
||||
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-16 100 \
|
||||
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-16 100
|
||||
ENV CC=clang-21
|
||||
ENV CXX=clang++-21
|
||||
|
||||
WORKDIR /work
|
||||
COPY . .
|
||||
|
||||
# C++26 modules need CMake >= 3.28, the Ninja generator and a module-aware gcc.
|
||||
RUN cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
|
||||
&& cmake --build build -j \
|
||||
&& ctest --test-dir build --output-on-failure
|
||||
RUN cmake -S . -B build/linux -G Ninja -DCMAKE_BUILD_TYPE=Release \
|
||||
&& cmake --build build/linux -j \
|
||||
&& ctest --test-dir build/linux --output-on-failure
|
||||
|
||||
# deploy target: runtime dependencies + final binary, minimal and fast.
|
||||
FROM ubuntu:26.04 AS deploy
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get -o Acquire::Retries=5 update \
|
||||
RUN --mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
apt-get -o Acquire::Retries=5 update \
|
||||
&& apt-get -o Acquire::Retries=5 install -y --no-install-recommends \
|
||||
libc++1 \
|
||||
libc++abi1 \
|
||||
libsdl3-0 \
|
||||
libstdc++6 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=dev /work/build/bin/openra3 /app/openra3
|
||||
COPY --from=dev /work/build/linux/bin/openra3 /app/openra3
|
||||
|
||||
ENTRYPOINT ["/app/openra3"]
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Windows cross-build environment (x86_64), fully isolated from the Linux image
|
||||
# in Dockerfile so the two toolchains and standard libraries never interfere.
|
||||
#
|
||||
# Toolchain: llvm-mingw (clang + libc++ + the libc++ `std` module, MSVCRT
|
||||
# runtime) with the official SDL3 MinGW development package.
|
||||
|
||||
FROM ubuntu:26.04 AS dev
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG APT_MIRROR=""
|
||||
RUN if [ -n "$APT_MIRROR" ]; then \
|
||||
sed -i -e "s|http://archive.ubuntu.com/ubuntu|${APT_MIRROR}|g" \
|
||||
-e "s|http://security.ubuntu.com/ubuntu|${APT_MIRROR}|g" \
|
||||
-e "s|http://ports.ubuntu.com/ubuntu-ports|${APT_MIRROR}|g" \
|
||||
/etc/apt/sources.list /etc/apt/sources.list.d/*.sources 2>/dev/null || true; \
|
||||
fi
|
||||
|
||||
RUN --mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
for attempt in 1 2 3 4 5; do \
|
||||
apt-get -o Acquire::Retries=5 update && break; \
|
||||
echo "apt-get update failed (attempt $attempt), retrying"; \
|
||||
sleep 5; \
|
||||
done \
|
||||
&& apt-get -o Acquire::Retries=5 install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
cmake \
|
||||
curl \
|
||||
ninja-build \
|
||||
xz-utils \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Pinned toolchain + SDL3 versions (override with --build-arg to bump).
|
||||
ARG LLVM_MINGW_VERSION=20260908
|
||||
ARG LLVM_MINGW_FLAVOR=msvcrt
|
||||
ARG SDL3_VERSION=3.4.16
|
||||
|
||||
RUN mkdir -p /opt/llvm-mingw /opt/sdl3-mingw \
|
||||
&& curl -fL "https://github.com/mstorsjo/llvm-mingw/releases/download/${LLVM_MINGW_VERSION}/llvm-mingw-${LLVM_MINGW_VERSION}-${LLVM_MINGW_FLAVOR}-ubuntu-22.04-x86_64.tar.xz" \
|
||||
| tar -xJ -C /opt/llvm-mingw --strip-components=1 \
|
||||
&& curl -fL "https://github.com/libsdl-org/SDL/releases/download/release-${SDL3_VERSION}/SDL3-devel-${SDL3_VERSION}-mingw.tar.gz" \
|
||||
| tar -xz -C /opt/sdl3-mingw --strip-components=1
|
||||
|
||||
ENV OPENRA3_LLVM_MINGW_ROOT=/opt/llvm-mingw
|
||||
ENV OPENRA3_SDL3_ROOT=/opt/sdl3-mingw
|
||||
|
||||
WORKDIR /work
|
||||
COPY . .
|
||||
|
||||
RUN cmake -S . -B build/windows -G Ninja \
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/llvm-mingw-x86_64.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
&& cmake --build build/windows -j
|
||||
|
||||
# package target: the .exe plus the SDL3 runtime DLL.
|
||||
FROM ubuntu:26.04 AS package
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=dev /work/build/windows/bin/openra3.exe /app/
|
||||
COPY --from=dev /work/build/windows/bin/SDL3.dll /app/
|
||||
@@ -1,7 +1,8 @@
|
||||
# OpenRA3
|
||||
|
||||
A from-scratch, portable re-implementation of **Command & Conquer: Red Alert 3**
|
||||
in **C++26** using **C++ modules**, built with **GCC 16**.
|
||||
in **C++26** using **C++ modules** and `import std;`, built with **Clang** for
|
||||
both **Linux** and **Windows**.
|
||||
|
||||
Red Alert 3 runs SAGE 2.0. EA never released that engine's C++ source, but it
|
||||
did open-source the closely related SAGE 1.0 engine as
|
||||
@@ -17,11 +18,13 @@ Ghidra.
|
||||
|
||||
## Status
|
||||
|
||||
OpenRA3 is at **v0.0.1**. The engine compiles and runs headless, and a **minimal
|
||||
OpenRA3 is at **v0.2.0**. The engine compiles and runs headless, and a **minimal
|
||||
skirmish** is playable: it reads a real multiplayer map out of your install,
|
||||
recovers the player start waypoints, and simulates two sides earning credits,
|
||||
training units and fighting until one base falls. The map and match state can be
|
||||
**rendered** to a window (SDL3) or to an image.
|
||||
**rendered** to a window (SDL3) or to an image. The whole tree builds for
|
||||
**Linux** (clang + libc++) and cross-compiles to **Windows** (`openra3.exe` +
|
||||
`SDL3.dll`) with llvm-mingw — both using C++26 modules and `import std;`.
|
||||
|
||||
```text
|
||||
$ openra3 skirmish --game-dir "/game" --map map_mp_2_feasel4
|
||||
@@ -73,19 +76,48 @@ built-in test map so the project still builds and runs in CI.
|
||||
| `tests/ra3_tests.cpp` | smoke tests (run via `ctest`) |
|
||||
| `tools/` | reference fetch + Ghidra-driven reconstruction helpers |
|
||||
| `docs/` | architecture, reverse-engineering notes, roadmap |
|
||||
| `Dockerfile` | `dev` (toolchain) and `deploy` (runtime) targets |
|
||||
| `.gitlab-ci.yml` | build → test → package pipeline |
|
||||
| `Dockerfile` | Linux build image (`dev` toolchain + `deploy` runtime) |
|
||||
| `Dockerfile.win` | isolated Windows cross-build image (llvm-mingw + SDL3 MinGW) |
|
||||
| `cmake/toolchains/` | `llvm-mingw-x86_64.cmake` cross toolchain |
|
||||
| `scripts/` | `build-linux.sh` / `build-windows.sh` one-shot builders |
|
||||
| `.gitlab-ci.yml` | build both targets → test → package pipeline |
|
||||
|
||||
## Why Clang + `import std;`
|
||||
|
||||
The engine never `#include`s the standard library: every module does
|
||||
`import std;`. CMake's support for that (`CXX_MODULE_STD`) works today with
|
||||
Clang + libc++. Linux uses the distro clang (LLVM 21); Windows cross-compiles
|
||||
with [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) (clang 23 + libc++ +
|
||||
the libc++ `std` module). The two toolchains live in **separate images** so
|
||||
their compilers and standard libraries never interfere.
|
||||
|
||||
## Build
|
||||
|
||||
The host needs no toolchain: build inside the container.
|
||||
The host needs no toolchain: each target builds inside its own image.
|
||||
|
||||
```bash
|
||||
docker build --target dev -t openra3-dev:local .
|
||||
# Linux -> build/linux/bin/openra3
|
||||
scripts/build-linux.sh
|
||||
|
||||
docker run --rm -v "$PWD:/work" -w /work openra3-dev:local cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
|
||||
docker run --rm -v "$PWD:/work" -w /work openra3-dev:local cmake --build build -j
|
||||
docker run --rm -v "$PWD:/work" -w /work openra3-dev:local ctest --test-dir build --output-on-failure
|
||||
# Windows -> build/windows/bin/openra3.exe (+ SDL3.dll)
|
||||
scripts/build-windows.sh
|
||||
```
|
||||
|
||||
Or drive Docker directly:
|
||||
|
||||
```bash
|
||||
docker build --target dev -t openra3-linux:local .
|
||||
docker run --rm -v "$PWD:/work" -w /work openra3-linux:local \
|
||||
cmake -S . -B build/linux -G Ninja -DCMAKE_BUILD_TYPE=Release
|
||||
docker run --rm -v "$PWD:/work" -w /work openra3-linux:local cmake --build build/linux -j
|
||||
docker run --rm -v "$PWD:/work" -w /work openra3-linux:local ctest --test-dir build/linux --output-on-failure
|
||||
|
||||
docker build -f Dockerfile.win --target dev -t openra3-windows:local .
|
||||
docker run --rm -v "$PWD:/work" -w /work openra3-windows:local \
|
||||
cmake -S . -B build/windows -G Ninja \
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/llvm-mingw-x86_64.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
docker run --rm -v "$PWD:/work" -w /work openra3-windows:local cmake --build build/windows -j
|
||||
```
|
||||
|
||||
Behind a slow or blocked mirror, pass `--build-arg APT_MIRROR=<url>`.
|
||||
@@ -94,14 +126,17 @@ Behind a slow or blocked mirror, pass `--build-arg APT_MIRROR=<url>`.
|
||||
|
||||
```bash
|
||||
# list the maps in your install
|
||||
docker run --rm -v "/path/to/Red Alert 3:/game:ro" openra3-dev:local \
|
||||
./build/bin/openra3 maps --game-dir /game
|
||||
docker run --rm -v "/path/to/Red Alert 3:/game:ro" openra3-linux:local \
|
||||
/work/build/linux/bin/openra3 maps --game-dir /game
|
||||
|
||||
# play a headless skirmish on a real map
|
||||
docker run --rm -v "/path/to/Red Alert 3:/game:ro" openra3-dev:local \
|
||||
./build/bin/openra3 skirmish --game-dir /game --map map_mp_2_feasel4 --seed 7
|
||||
docker run --rm -v "/path/to/Red Alert 3:/game:ro" openra3-linux:local \
|
||||
/work/build/linux/bin/openra3 skirmish --game-dir /game --map map_mp_2_feasel4 --seed 7
|
||||
```
|
||||
|
||||
The Windows build is a native `openra3.exe` — copy it next to `SDL3.dll` and run
|
||||
it from `cmd`/PowerShell, e.g. `openra3.exe skirmish --game-dir "C:\Red Alert 3"`.
|
||||
|
||||
`--frames N` caps the simulation length (default 15 minutes of game time at
|
||||
30 Hz). The result is deterministic for a given map and seed.
|
||||
|
||||
@@ -113,10 +148,13 @@ The renderer draws the map's own overview art, a world grid and the match state
|
||||
**Offscreen image** (works anywhere, no display needed):
|
||||
|
||||
```bash
|
||||
docker run --rm -v "/path/to/Red Alert 3:/game:ro" -v "$PWD/out:/out" openra3-dev:local \
|
||||
/work/build/bin/openra3 render --game-dir /game --map map_mp_2_feasel4 --out /out/map.bmp
|
||||
docker run --rm -v "/path/to/Red Alert 3:/game:ro" -v "$PWD/out:/out" openra3-linux:local \
|
||||
/work/build/linux/bin/openra3 render --game-dir /game --map map_mp_2_feasel4 --out /out/map.bmp
|
||||
```
|
||||
|
||||
On Windows the same command runs natively: `openra3.exe render --game-dir
|
||||
"C:\Red Alert 3" --map map_mp_2_feasel4` opens an SDL3 window.
|
||||
|
||||
**Interactive window** (SDL3; drag to pan, wheel to zoom, Esc to quit). In a
|
||||
container you need an X server on the host — on Windows run
|
||||
[VcXsrv](https://sourceforge.net/projects/vcxsrv/) and launch it with "Disable
|
||||
@@ -124,7 +162,7 @@ access control", then:
|
||||
|
||||
```bash
|
||||
docker run --rm -v "/path/to/Red Alert 3:/game:ro" -e DISPLAY=host.docker.internal:0.0 \
|
||||
openra3-dev:local /work/build/bin/openra3 render --game-dir /game --map map_mp_2_feasel4
|
||||
openra3-linux:local /work/build/linux/bin/openra3 render --game-dir /game --map map_mp_2_feasel4
|
||||
```
|
||||
|
||||
If no display is available the viewer falls back to writing `openra3_view.bmp`.
|
||||
|
||||
+1
-10
@@ -1,13 +1,4 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
import std;
|
||||
import ra3;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Cross-compile for Windows x86_64 with llvm-mingw: clang + libc++ + the
|
||||
# libc++ `std` module, targeting the MSVCRT MinGW runtime (which is what the
|
||||
# official SDL3 MinGW package links against).
|
||||
|
||||
# The `import std` gate must be set before the compiler is probed; a toolchain
|
||||
# file is processed earlier than the project's own top-level settings.
|
||||
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||
|
||||
set(OPENRA3_LLVM_MINGW_ROOT "/opt/llvm-mingw" CACHE PATH "llvm-mingw installation root")
|
||||
if(NOT EXISTS "${OPENRA3_LLVM_MINGW_ROOT}/bin/clang++")
|
||||
message(FATAL_ERROR "llvm-mingw not found at ${OPENRA3_LLVM_MINGW_ROOT} (expected bin/clang++)")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_COMPILER "${OPENRA3_LLVM_MINGW_ROOT}/bin/clang")
|
||||
set(CMAKE_CXX_COMPILER "${OPENRA3_LLVM_MINGW_ROOT}/bin/clang++")
|
||||
set(CMAKE_C_COMPILER_TARGET x86_64-w64-mingw32)
|
||||
set(CMAKE_CXX_COMPILER_TARGET x86_64-w64-mingw32)
|
||||
# CMake's standard-library detection does not pass COMPILER_TARGET, so without
|
||||
# this it probes the host standard library. Putting the target in ARG1 makes
|
||||
# the probe see libc++ (the MinGW target's library).
|
||||
set(CMAKE_C_COMPILER_ARG1 "--target=x86_64-w64-mingw32")
|
||||
set(CMAKE_CXX_COMPILER_ARG1 "--target=x86_64-w64-mingw32")
|
||||
|
||||
# libc++ standard-library module description for the MinGW target. Must be set
|
||||
# before the compiler is probed so CMake can build `import std;`.
|
||||
set(CMAKE_CXX_STDLIB_MODULES_JSON "${OPENRA3_LLVM_MINGW_ROOT}/x86_64-w64-mingw32/lib/libc++.modules.json")
|
||||
|
||||
# Select libc++ explicitly so CMake's `import std` detection recognises the
|
||||
# standard library (llvm-mingw defaults to it, but CMake keys off -stdlib=).
|
||||
set(CMAKE_CXX_FLAGS_INIT "-stdlib=libc++")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-stdlib=libc++")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-stdlib=libc++")
|
||||
|
||||
# Official SDL3 MinGW development package (headers + import library + DLL).
|
||||
set(OPENRA3_SDL3_ROOT "/opt/sdl3-mingw" CACHE PATH "SDL3 MinGW development package root")
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH "${OPENRA3_LLVM_MINGW_ROOT}/x86_64-w64-mingw32")
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
@@ -1,7 +1,9 @@
|
||||
# Architecture
|
||||
|
||||
OpenRA3 is organised as a stack of C++ modules. Each layer may import the ones
|
||||
below it, never the ones above.
|
||||
OpenRA3 is organised as a stack of C++26 modules. Each layer may import the ones
|
||||
below it, never the ones above. Every module uses `import std;` for the standard
|
||||
library; the engine is built with Clang + libc++ on Linux and cross-compiled
|
||||
with llvm-mingw for Windows.
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────┐
|
||||
|
||||
@@ -14,6 +14,10 @@ that each one produces something that builds and runs.
|
||||
- [x] **v0.1.0 — map renderer + window.** Software ARGB framebuffer, TGA
|
||||
decoder for the map art, BMP output, map/grid/unit compositing, and an
|
||||
SDL3 window viewer (pan/zoom).
|
||||
- [x] **v0.2.0 — dual toolchain.** Switched to Clang + libc++ with
|
||||
`import std;` in every module; added an isolated Windows cross-build
|
||||
(llvm-mingw + SDL3 MinGW) producing `openra3.exe` + `SDL3.dll`, alongside
|
||||
the Linux build. Both images are separate to keep the toolchains apart.
|
||||
|
||||
## Next
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build the Linux target inside its own isolated image (Dockerfile).
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
IMAGE="${OPENRA3_LINUX_IMAGE:-openra3-linux:local}"
|
||||
BUILD_DIR="${1:-build/linux}"
|
||||
|
||||
docker build --target dev -t "$IMAGE" "$ROOT"
|
||||
docker run --rm -v "$ROOT:/work" -w /work "$IMAGE" cmake -S . -B "$BUILD_DIR" -G Ninja -DCMAKE_BUILD_TYPE=Release
|
||||
docker run --rm -v "$ROOT:/work" -w /work "$IMAGE" cmake --build "$BUILD_DIR" -j
|
||||
docker run --rm -v "$ROOT:/work" -w /work "$IMAGE" ctest --test-dir "$BUILD_DIR" --output-on-failure
|
||||
|
||||
echo "Linux build: $ROOT/$BUILD_DIR/bin/openra3"
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build the Windows x86_64 target inside its own isolated image (Dockerfile.win).
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
IMAGE="${OPENRA3_WINDOWS_IMAGE:-openra3-windows:local}"
|
||||
BUILD_DIR="${1:-build/windows}"
|
||||
|
||||
docker build --target dev -f "$ROOT/Dockerfile.win" -t "$IMAGE" "$ROOT"
|
||||
docker run --rm -v "$ROOT:/work" -w /work "$IMAGE" \
|
||||
cmake -S . -B "$BUILD_DIR" -G Ninja \
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/llvm-mingw-x86_64.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
docker run --rm -v "$ROOT:/work" -w /work "$IMAGE" cmake --build "$BUILD_DIR" -j
|
||||
|
||||
echo "Windows build: $ROOT/$BUILD_DIR/bin/openra3.exe (+ SDL3.dll)"
|
||||
@@ -1,11 +1,7 @@
|
||||
module;
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
|
||||
export module ra3.client;
|
||||
|
||||
import std;
|
||||
|
||||
import ra3.core;
|
||||
import ra3.logic;
|
||||
|
||||
|
||||
+3
-16
@@ -1,20 +1,7 @@
|
||||
module;
|
||||
|
||||
#include <cmath>
|
||||
#include <compare>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
export module ra3.core;
|
||||
|
||||
import std;
|
||||
|
||||
/**
|
||||
* Fundamental engine types shared by every OpenRA3 module.
|
||||
*
|
||||
@@ -24,7 +11,7 @@ export module ra3.core;
|
||||
*/
|
||||
export namespace ra3::core {
|
||||
inline constexpr int version_major = 0;
|
||||
inline constexpr int version_minor = 1;
|
||||
inline constexpr int version_minor = 2;
|
||||
inline constexpr int version_patch = 0;
|
||||
|
||||
using real = float;
|
||||
|
||||
+2
-18
@@ -1,23 +1,7 @@
|
||||
module;
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
export module ra3.fs;
|
||||
|
||||
import std;
|
||||
|
||||
export import ra3.core;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
module;
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
export module ra3.game;
|
||||
|
||||
import std;
|
||||
|
||||
import ra3.core;
|
||||
import ra3.logic;
|
||||
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
module;
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
export module ra3.logic;
|
||||
|
||||
import std;
|
||||
|
||||
import ra3.core;
|
||||
|
||||
/**
|
||||
|
||||
+2
-13
@@ -1,18 +1,7 @@
|
||||
module;
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
export module ra3.map;
|
||||
|
||||
import std;
|
||||
|
||||
export import ra3.core;
|
||||
export import ra3.fs;
|
||||
|
||||
|
||||
@@ -1,18 +1,7 @@
|
||||
module;
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
export module ra3.render;
|
||||
|
||||
import std;
|
||||
|
||||
export import ra3.core;
|
||||
|
||||
/**
|
||||
@@ -223,7 +212,7 @@ export namespace ra3::render {
|
||||
out[at + 2U] = static_cast<uint8>(value >> 16U);
|
||||
out[at + 3U] = static_cast<uint8>(value >> 24U);
|
||||
};
|
||||
auto put16 = [&out](usize at, uint16_t value) {
|
||||
auto put16 = [&out](usize at, std::uint16_t value) {
|
||||
out[at] = static_cast<uint8>(value);
|
||||
out[at + 1U] = static_cast<uint8>(value >> 8U);
|
||||
};
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
module;
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
export module ra3.skirmish;
|
||||
|
||||
import std;
|
||||
|
||||
export import ra3.core;
|
||||
export import ra3.map;
|
||||
export import ra3.game;
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
module;
|
||||
|
||||
#include <string>
|
||||
|
||||
export module ra3.ui;
|
||||
|
||||
import std;
|
||||
export import ra3.core;
|
||||
import ra3.render;
|
||||
|
||||
|
||||
@@ -2,11 +2,9 @@ module;
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
export module ra3.ui;
|
||||
|
||||
import std;
|
||||
export import ra3.core;
|
||||
import ra3.render;
|
||||
|
||||
|
||||
+1
-9
@@ -1,12 +1,4 @@
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
import std;
|
||||
import ra3;
|
||||
|
||||
namespace {
|
||||
|
||||
Reference in New Issue
Block a user