Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .vscode/c_cpp_properties.clang.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
// Copy this file to c_cpp_properties.json and adjust these paths if needed.
"env": {
// LLVM installed with its default Windows installer location.
"CLANG_CL_PATH": "${env:ProgramFiles}/LLVM/bin/clang-cl.exe",
// Visual Studio 2022 Community. Change the edition or installation path as needed.
"MSVC_ROOT": "${env:ProgramFiles}/Microsoft Visual Studio/2022/Community",
"MSVC_VERSION": "14.44.35207",
// The Windows SDK is normally installed under Program Files (x86).
"WINDOWS_SDK_ROOT": "${env:ProgramFiles(x86)}/Windows Kits/10",
"WINDOWS_SDK_VERSION": "10.0.26100.0",
// Set this to the CMake binary directory used for the clang-cl build.
"CLANG_BUILD_DIR": "${workspaceFolder}/build/clang-cl"
},
"configurations": [
{
"name": "Win32 clang-cl with MSVC headers",
"compilerPath": "${CLANG_CL_PATH}",
"compilerArgs": [
"--target=i686-pc-windows-msvc",
"/clang:-fms-compatibility-version=19.44"
],
"intelliSenseMode": "windows-clang-x86",
"cStandard": "c17",
"cppStandard": "c++20",
"includePath": [
"${workspaceFolder}/code",
"${workspaceFolder}/code/vqalib",
"${workspaceFolder}/thirdparty/**",
"${CLANG_BUILD_DIR}/generated",
"${MSVC_ROOT}/VC/Tools/MSVC/${MSVC_VERSION}/include",
"${MSVC_ROOT}/VC/Tools/MSVC/${MSVC_VERSION}/atlmfc/include",
"${WINDOWS_SDK_ROOT}/Include/${WINDOWS_SDK_VERSION}/ucrt",
"${WINDOWS_SDK_ROOT}/Include/${WINDOWS_SDK_VERSION}/shared",
"${WINDOWS_SDK_ROOT}/Include/${WINDOWS_SDK_VERSION}/um",
"${WINDOWS_SDK_ROOT}/Include/${WINDOWS_SDK_VERSION}/winrt",
"${WINDOWS_SDK_ROOT}/Include/${WINDOWS_SDK_VERSION}/cppwinrt"
],
"defines": [
"WIN32",
"_WIN32",
"_WINDOWS",
"_MBCS",
"NOMINMAX",
"NO_BLOWFISH_DLL"
]
}
],
"version": 4
}
24 changes: 22 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.23)

project(OpenTS VERSION 0.2.0 LANGUAGES C CXX ASM_MASM)
enable_language(RC)

# A SemVer prerelease label, which project() cannot carry because it takes numbers only. Set it
# to "beta1" and the version reads 0.1.0-beta1; leave it empty outside a prerelease series. The
Expand All @@ -11,8 +12,27 @@ set(OPENTS_VERSION_PRERELEASE "")
# alone. Every other build names the commit it came from as well.
option(OPENTS_OFFICIAL_BUILD "Build as an official release of the declared version" OFF)

if(NOT MSVC OR MSVC_VERSION LESS 1930)
message(FATAL_ERROR "OpenTS requires the Visual Studio 2022 MSVC toolchain.")
option(OPENTS_EXPERIMENTAL_CLANG_CL "Build with clang-cl using the MSVC ABI" OFF)

set(OPENTS_MSVC_ABI_COMPILER OFF)
if(MSVC)
if(MSVC_VERSION LESS 1930)
message(FATAL_ERROR "OpenTS requires MSVC 19.30 or newer.")
endif()
set(OPENTS_MSVC_ABI_COMPILER ON)
elseif(OPENTS_EXPERIMENTAL_CLANG_CL
AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(OPENTS_MSVC_ABI_COMPILER ON)
set(CMAKE_DEPFILE_FLAGS_RC "" CACHE STRING "" FORCE)
set(CMAKE_RC_COMPILE_OBJECT
"<CMAKE_RC_COMPILER> /C 1252 <DEFINES> <INCLUDES> <FLAGS> /fo<OBJECT> <SOURCE>"
CACHE STRING "" FORCE)
else()
message(FATAL_ERROR
"OpenTS requires the Visual Studio 2022 MSVC toolchain. "
"The unsupported clang-cl experiment must be configured with "
"-DOPENTS_EXPERIMENTAL_CLANG_CL=ON.")
endif()

set(CMAKE_CXX_STANDARD 20)
Expand Down
23 changes: 23 additions & 0 deletions cmake/clang-cl-bx-compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*******************************************************************************
* O P E N T S
******************************************************************************
* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright 2026 OpenTS contributors
******************************************************************************/

#pragma once

#ifndef BX_CONFIG_DEBUG
#ifdef _DEBUG
#define BX_CONFIG_DEBUG 1
#else
#define BX_CONFIG_DEBUG 0
#endif
#endif

#include <bx/bx.h>

#if defined(__clang__) && defined(_M_IX86)
#undef __stdcall
#define __stdcall __attribute__((stdcall))
#endif
72 changes: 72 additions & 0 deletions cmake/toolchains/clang-cl-msvc.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86)

set(OPENTS_EXPERIMENTAL_CLANG_CL ON CACHE BOOL "" FORCE)
set(OPENTS_MSVC_ROOT "" CACHE PATH "Path to the MSVC and Windows SDK files")
list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES OPENTS_MSVC_ROOT)

if(NOT OPENTS_MSVC_ROOT AND DEFINED ENV{OPENTS_MSVC_ROOT})
set(OPENTS_MSVC_ROOT "$ENV{OPENTS_MSVC_ROOT}" CACHE PATH "" FORCE)
endif()

if(NOT OPENTS_MSVC_ROOT)
message(FATAL_ERROR
"Set OPENTS_MSVC_ROOT to the directory containing MSVC and the Windows SDK.")
endif()

set(_opents_msvc_version "14.44.35207")
set(_opents_sdk_version "10.0.26100.0")
set(_opents_msvc_dir "${OPENTS_MSVC_ROOT}/VC/Tools/MSVC/${_opents_msvc_version}")
set(_opents_sdk_dir "${OPENTS_MSVC_ROOT}/Windows Kits/10")

foreach(_required_path
"${_opents_msvc_dir}/include"
"${_opents_sdk_dir}/Include/${_opents_sdk_version}/um")
if(NOT EXISTS "${_required_path}")
message(FATAL_ERROR "Required MSVC component not found: ${_required_path}")
endif()
endforeach()

find_program(_opents_clang_cl clang-cl REQUIRED)
find_program(_opents_lld_link lld-link REQUIRED)
find_program(_opents_llvm_lib llvm-lib REQUIRED)
find_program(_opents_llvm_mt llvm-mt REQUIRED)
find_program(_opents_llvm_rc llvm-rc REQUIRED)
find_program(_opents_uasm uasm REQUIRED)

set(CMAKE_C_COMPILER "${_opents_clang_cl}")
set(CMAKE_CXX_COMPILER "${_opents_clang_cl}")
set(CMAKE_C_COMPILER_TARGET i686-pc-windows-msvc)
set(CMAKE_CXX_COMPILER_TARGET i686-pc-windows-msvc)
set(CMAKE_C_FLAGS_INIT "/clang:-fms-compatibility-version=19.44")
set(CMAKE_CXX_FLAGS_INIT "/clang:-fms-compatibility-version=19.44")
set(CMAKE_LINKER "${_opents_lld_link}")
set(CMAKE_AR "${_opents_llvm_lib}")
set(CMAKE_RC_COMPILER "${_opents_llvm_rc}" CACHE FILEPATH "" FORCE)
set(CMAKE_MT "${_opents_llvm_mt}")
set(CMAKE_ASM_MASM_COMPILER "${_opents_uasm}" CACHE FILEPATH "" FORCE)

set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES
"${_opents_msvc_dir}/atlmfc/include"
"${_opents_msvc_dir}/include"
"${_opents_sdk_dir}/Include/${_opents_sdk_version}/shared"
"${_opents_sdk_dir}/Include/${_opents_sdk_version}/ucrt"
"${_opents_sdk_dir}/Include/${_opents_sdk_version}/um"
"${_opents_sdk_dir}/Include/${_opents_sdk_version}/winrt")
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_C_STANDARD_INCLUDE_DIRECTORIES})

set(_opents_rc_flags "")
foreach(_include_dir IN LISTS CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
string(APPEND _opents_rc_flags " /I\"${_include_dir}\"")
endforeach()
set(CMAKE_RC_FLAGS_INIT "${_opents_rc_flags}")

set(_opents_linker_paths
"/libpath:\"${_opents_msvc_dir}/atlmfc/lib/x86\""
"/libpath:\"${_opents_msvc_dir}/lib/x86\""
"/libpath:\"${_opents_sdk_dir}/Lib/${_opents_sdk_version}/ucrt/x86\""
"/libpath:\"${_opents_sdk_dir}/Lib/${_opents_sdk_version}/um/x86\"")
string(JOIN " " _opents_linker_flags ${_opents_linker_paths})
set(CMAKE_EXE_LINKER_FLAGS_INIT "${_opents_linker_flags}")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "${_opents_linker_flags}")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "${_opents_linker_flags}")
53 changes: 44 additions & 9 deletions code/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ endforeach()
#
message(STATUS "${PROJECT_NAME}: Creating '${PROJECT_NAME}' executable...")

if(OPENTS_EXPERIMENTAL_CLANG_CL)
set(CMAKE_DEPFILE_FLAGS_RC "")
set(CMAKE_RC_COMPILE_OBJECT
"<CMAKE_RC_COMPILER> /C 1252 <DEFINES> <INCLUDES> <FLAGS> /fo<OBJECT> <SOURCE>")
endif()

add_executable(OpenTS WIN32 ${OPENTS_SRC})
target_compile_features(OpenTS PRIVATE cxx_std_20)

Expand Down Expand Up @@ -92,6 +98,16 @@ set_target_properties(OpenTS PROPERTIES
#
message(STATUS "${PROJECT_NAME}: Applying compiler flags...")

if(OPENTS_EXPERIMENTAL_CLANG_CL)
set(OPENTS_ASM_MASM_OPTIONS -Zi -c -coff -Cx -safeseh)
set(OPENTS_ASM_MASM_SOURCE_OPTIONS "-Zi -c -coff -Cx -safeseh")
set(OPENTS_PARALLEL_COMPILE_OPTION "")
else()
set(OPENTS_ASM_MASM_OPTIONS /Zi /c /coff /Cx /safeseh)
set(OPENTS_ASM_MASM_SOURCE_OPTIONS "/Zi /c /coff /Cx /safeseh")
set(OPENTS_PARALLEL_COMPILE_OPTION /MP)
endif()

set(OPENTS_COMPILE_OPTIONS

# ================= DEBUG =================
Expand All @@ -101,17 +117,17 @@ set(OPENTS_COMPILE_OPTIONS
# /arch:SSE2 -- IEEE-754 single precision, no x87 excess precision.
# /fp:precise -- no reassociation of the engine's accumulations.
$<$<COMPILE_LANGUAGE:CXX>:
/Zi /Od /RTC1 /GR /MP /EHsc /Oy- /MTd /Zc:__cplusplus /arch:SSE2 /fp:precise
/Zi /Od /RTC1 /GR ${OPENTS_PARALLEL_COMPILE_OPTION} /EHsc /Oy- /MTd /Zc:__cplusplus /arch:SSE2 /fp:precise
>

# ---------- C ----------
$<$<COMPILE_LANGUAGE:C>:
/Zi /Od /RTC1 /MP /Oy- /arch:SSE2 /fp:precise
/Zi /Od /RTC1 ${OPENTS_PARALLEL_COMPILE_OPTION} /Oy- /arch:SSE2 /fp:precise
>

# ---------- MASM ----------
$<$<COMPILE_LANGUAGE:ASM_MASM>:
/Zi /c /coff /Cx /safeseh
${OPENTS_ASM_MASM_OPTIONS}
>
>

Expand All @@ -122,23 +138,31 @@ set(OPENTS_COMPILE_OPTIONS
# /arch:SSE2 -- IEEE-754 single precision, no x87 excess precision.
# /fp:precise -- no reassociation of the engine's accumulations.
$<$<COMPILE_LANGUAGE:CXX>:
/Zi /O2 /GF /GR /MP /EHsc /MT /Zc:__cplusplus /arch:SSE2 /fp:precise
/Zi /O2 /GF /GR ${OPENTS_PARALLEL_COMPILE_OPTION} /EHsc /MT /Zc:__cplusplus /arch:SSE2 /fp:precise
>

# ---------- C ----------
$<$<COMPILE_LANGUAGE:C>:
/Zi /O2 /GF /MP /arch:SSE2 /fp:precise
/Zi /O2 /GF ${OPENTS_PARALLEL_COMPILE_OPTION} /arch:SSE2 /fp:precise
>

# ---------- MASM ----------
$<$<COMPILE_LANGUAGE:ASM_MASM>:
/Zi /c /coff /Cx /safeseh
${OPENTS_ASM_MASM_OPTIONS}
>
>
)

target_compile_options(OpenTS PRIVATE ${OPENTS_COMPILE_OPTIONS})

if(OPENTS_EXPERIMENTAL_CLANG_CL)
target_compile_options(OpenTS PRIVATE
$<$<COMPILE_LANGUAGE:C,CXX>:
/clang:-Wno-c++11-narrowing
>
)
endif()

#
# ---------------------------------------------------------
# Subprojects
Expand All @@ -163,9 +187,20 @@ set(BGFX_ROOT "${CMAKE_SOURCE_DIR}/thirdparty/bgfx.cmake/bgfx")
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/bgfxbackend.cpp" PROPERTIES
INCLUDE_DIRECTORIES
"${BGFX_ROOT}/include;${CMAKE_SOURCE_DIR}/thirdparty/bgfx.cmake/bx/include;${BGFX_ROOT}/examples/common/imgui"
COMPILE_DEFINITIONS
"BX_CONFIG_DEBUG=$<IF:$<CONFIG:Debug>,1,$<BOOL:${BX_CONFIG_DEBUG}>>"
COMPILE_OPTIONS "/Zc:preprocessor"
)

# bx rewrites __stdcall while its headers are being parsed by clang-cl. Force the
# compatibility header into the renderer translation unit as well as bx/bgfx so the
# MSVC standard-library headers that follow still see the Win32 calling convention.
if(OPENTS_EXPERIMENTAL_CLANG_CL AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/bgfxbackend.cpp" APPEND PROPERTY
COMPILE_OPTIONS "/FI${CMAKE_SOURCE_DIR}/cmake/clang-cl-bx-compat.h"
)
endif()

message(STATUS "${PROJECT_NAME}: Adding compilier definitions...")
target_compile_definitions(OpenTS PRIVATE
WIN32
Expand Down Expand Up @@ -218,7 +253,7 @@ target_link_libraries(OpenTS PRIVATE
ole32 oleaut32 uuid odbc32 odbccp32
)

if (MSVC)
if (OPENTS_MSVC_ABI_COMPILER)
target_link_options(OpenTS PRIVATE
/SUBSYSTEM:WINDOWS
/DEBUG
Expand All @@ -243,12 +278,12 @@ message(STATUS "${PROJECT_NAME}: Adding MASM support...")

enable_language(ASM_MASM)

# All .asm files compile automatically using ML.EXE with appropriate flags.
# The experimental clang-cl toolchain uses native UASM; Visual Studio uses ML.EXE.
foreach(f ${OPENTS_SRC})
if(f MATCHES "\\.asm$")
set_source_files_properties(${f} PROPERTIES
LANGUAGE ASM_MASM
COMPILE_FLAGS "-Zi -c -coff -Cx"
COMPILE_FLAGS "${OPENTS_ASM_MASM_SOURCE_OPTIONS}"
)
endif()
endforeach()
Expand Down
2 changes: 1 addition & 1 deletion code/_wsproto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

#include "always.h"

#include "_WSProto.h"
#include "_wsproto.h"


WinsockInterfaceClass *PacketTransport = 0; //The object for interfacing with Winsock
28 changes: 28 additions & 0 deletions code/bgfxbackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@
#include "dbgprint.h"
#include "except.h"

#include <bx/allocator.h>
#include <bgfx/bgfx.h>
#include <bgfx/embedded_shader.h>

#include <vs_ocornut_imgui.bin.h>
#include <fs_ocornut_imgui.bin.h>

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <malloc.h>


static const bgfx::EmbeddedShader _EmbeddedShaders[] = {
Expand Down Expand Up @@ -119,6 +122,30 @@ class BackendCallback : public bgfx::CallbackI
static BackendCallback _Callback;


// bgfx contains cache-line-aligned render records but requests their backing arrays with
// the allocator's default alignment. The Win32 CRT only guarantees eight-byte alignment,
// which is insufficient when clang-cl copies those records with aligned SSE instructions.
class BackendAllocator : public bx::AllocatorI
{
public:
virtual ~BackendAllocator(void) override {}

virtual void * realloc(void * ptr, size_t size, size_t alignment, const char *, uint32_t) override
{
if (size == 0) {
_aligned_free(ptr);
return(NULL);
}

const size_t cachelinealignment = BX_CACHE_LINE_SIZE;
alignment = std::max(alignment, cachelinealignment);
return(_aligned_realloc(ptr, size, alignment));
}
};

static BackendAllocator _Allocator;


/// <summary>
/// Builds the table that widens a 565 pixel to the 32 bit color the fallback path uploads.
/// </summary>
Expand Down Expand Up @@ -273,6 +300,7 @@ bool Backend_Init(HWND window, int windowwidth, int windowheight, BackendRendere
init.resolution.height = (uint32_t)windowheight;
init.resolution.reset = _ResetFlags;
init.callback = &_Callback;
init.allocator = &_Allocator;

switch (renderer) {
case BACKEND_RENDERER_D3D11:
Expand Down
Loading
Loading