msvc support in progress

This commit is contained in:
jacob 2024-05-03 02:35:25 -05:00
parent 00629aa988
commit 9eabdcd222
24 changed files with 556 additions and 235 deletions

View File

@ -3,13 +3,14 @@ project(powerplay)
# Options below are laid out so that running cmake with all "OFF" results in the "release" / "user" build
option(RTC "Should the build compile with runtime checks enabled (asserts, asan, etc.) - REQUIRES CRTLIB ON" OFF)
option(ASAN "Should the build compile with the address sanitizer enabled (asserts, asan, etc.) - REQUIRES CRTLIB ON" OFF)
option(CRTLIB "Should the build link with the CRTLIB" OFF)
option(DEBINFO "Should the build compile with debug info" OFF)
option(DEVELOPER "Should the build compile with developer mode enabled" OFF)
option(PROFILING "Should the build compile with profiling enabled - REQUIRES CRTLIB ON" OFF)
option(UNOPTIMIZED "Should the build compile with optimization disabled" OFF)
option(RTC "Should the build compile with runtime checks enabled (asserts, asan, etc.) - REQUIRES CRTLIB=ON" OFF)
option(ASAN "Should the build compile with the address sanitizer enabled (asserts, asan, etc.) - REQUIRES CRTLIB=ON" OFF)
option(CRTLIB "Should the build link with the CRTLIB" OFF)
option(DEBINFO "Should the build compile with debug info" OFF)
option(DEVELOPER "Should the build compile with developer mode enabled" OFF)
option(PROFILING "Should the build compile with profiling enabled - REQUIRES CRTLIB=ON, MSVC=OFF" OFF)
option(UNOPTIMIZED "Should the build compile with optimization disabled" OFF)
option(MSVC "Should the build compile using MSVC" OFF)
################################################################################
# Source files
@ -123,7 +124,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# Add executable
add_executable(powerplay_exe ${sources})
add_executable(powerplay_exe WIN32 ${sources})
set_target_properties(
powerplay_exe PROPERTIES
C_STANDARD 99
@ -142,75 +143,127 @@ target_precompile_headers(powerplay_exe PRIVATE src/common.h)
# -Wconversion \
# -Wno-sign-conversion \
set(COMPILER_WARNINGS " \
-Weverything -Werror \
-Wframe-larger-than=65536 \
\
-Wno-unused-macros -Wno-gnu-zero-variadic-macro-arguments -Wno-documentation \
-Wno-old-style-cast -Wno-conversion -Wno-sign-conversion \
-Wno-declaration-after-statement -Wno-extra-semi -Wno-extra-semi-stmt \
-Wno-bad-function-cast -Wno-class-varargs -Wno-unreachable-code-break \
-Wno-cast-align -Wno-float-equal -Wno-zero-as-null-pointer-constant \
-Wno-cast-qual -Wno-missing-noreturn -Wno-missing-field-initializers \
-Wno-missing-braces -Wno-initializer-overrides \
-Wno-c99-extensions -Wno-c++98-compat-pedantic -Wno-c++98-compat \
-Wno-switch-enum -Wno-switch-default \
-Wno-reserved-identifier -Wno-reserved-macro-identifier \
-Wno-unsafe-buffer-usage -Wno-writable-strings \
")
# -Wno-unused-vfariable -Wno-unused-but-set-variable -Wno-unused-parameter
if (MSVC)
set(COMPILER_WARNINGS "")
set(COMPILER_FLAGS "
-fuse-ld=lld-link \
-nostdlib \
-fno-strict-aliasing \
-fno-finite-loops \
-fwrapv \
-msse4.2 \
")
set(COMPILER_AND_LINKER_FLAGS)
set(LINKER_FLAGS " \
${rc_res_sources} \
-fno-strict-aliasing \
-fno-finite-loops \
-fwrapv \
-msse4.2 \
")
set(COMPILER_FLAGS)
set(LINKER_FLAGS "${rc_res_sources} /subsystem:windows")
set(C_VERSION "/std:c11")
set(CPP_VERSION "/std:c++20")
else()
set(COMPILER_WARNINGS " \
-Weverything -Werror \
-Wframe-larger-than=65536 \
\
-Wno-unused-macros -Wno-gnu-zero-variadic-macro-arguments -Wno-documentation \
-Wno-old-style-cast -Wno-conversion -Wno-sign-conversion \
-Wno-declaration-after-statement -Wno-extra-semi -Wno-extra-semi-stmt \
-Wno-bad-function-cast -Wno-class-varargs -Wno-unreachable-code-break \
-Wno-cast-align -Wno-float-equal -Wno-zero-as-null-pointer-constant \
-Wno-cast-qual -Wno-missing-noreturn -Wno-missing-field-initializers \
-Wno-missing-braces -Wno-initializer-overrides \
-Wno-c99-extensions -Wno-c++98-compat-pedantic -Wno-c++98-compat \
-Wno-switch-enum -Wno-switch-default \
-Wno-reserved-identifier -Wno-reserved-macro-identifier \
-Wno-unsafe-buffer-usage -Wno-writable-strings \
")
# -Wno-unused-vfariable -Wno-unused-but-set-variable -Wno-unused-parameter
set(COMPILER_AND_LINKER_FLAGS "
-fuse-ld=lld-link \
-nostdlib \
-fno-strict-aliasing \
-fno-finite-loops \
-fwrapv \
-msse4.2 \
")
set(COMPILER_FLAGS)
set(LINKER_FLAGS " \
${rc_res_sources} \
-fno-strict-aliasing \
-fno-finite-loops \
-fwrapv \
-msse4.2 \
")
set(C_VERSION "-std=c99")
set(CPP_VERSION "-std=c++20")
endif()
# RTC (Runtime checks)
if (RTC)
if (NOT CRTLIB)
message(FATAL_ERROR "CRTLIB (C runtime library) Must be enabled when compiling with RTC (runtime checks)")
endif()
# Enable UBSan
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fsanitize=undefined -fsanitize-trap=all -DRTC=1")
# set(COMPILER_FLAGS "${COMPILER_FLAGS} -fsanitize=undefined -DRTC=1")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DRTC=1")
if (MSVC)
if (NOT ASAN)
# Enable RTC (not compatible with ASAN)
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} /RTCcsu")
endif()
else()
# Enable UBSan
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -fsanitize=undefined -fsanitize-trap=all")
# set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -fsanitize=undefined -DRTC=1")
endif()
endif()
# CRTLIB (C runtime library)
if (CRTLIB)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -DCRTLIB=1")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DCRTLIB=1")
if (RTC)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -D_DEBUG -D_MT -D_DLL")
set(LINKER_FLAGS "${LINKER_FLAGS} -lmsvcrtd -lucrtd -lmsvcprtd -lvcruntimed")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -D_DEBUG -D_MT -D_DLL")
if (MSVC)
set(LINKER_FLAGS "${LINKER_FLAGS} msvcrtd.lib ucrtd.lib msvcprtd.lib vcruntime.lib")
else()
set(LINKER_FLAGS "${LINKER_FLAGS} -lmsvcrtd -lucrtd -lmsvcprtd -lvcruntimed")
endif()
else()
set(COMPILER_FLAGS "${COMPILER_FLAGS} -D_MT -D_DLL")
set(LINKER_FLAGS "${LINKER_FLAGS} -lmsvcrt -lucrt -lmsvcprt -lvcruntime")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -D_MT -D_DLL")
if (MSVC)
set(LINKER_FLAGS "${LINKER_FLAGS} msvcrt.lib ucrt.lib msvcprt.lib vcruntime.lib ")
else()
set(LINKER_FLAGS "${LINKER_FLAGS} -lmsvcrt -lucrt -lmsvcprt -lvcruntime")
endif()
endif()
else()
set(COMPILER_FLAGS "${COMPILER_FLAGS} -mno-stack-arg-probe -fno-builtin")
if (MSVC)
message(FATAL_ERROR "TODO")
else()
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -mno-stack-arg-probe -fno-builtin")
endif()
endif()
# Optimization
if (UNOPTIMIZED)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -O0 -DUNOPTIMIZED=1")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DUNOPTIMIZED=1")
if (MSVC)
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} /Od")
else()
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -O0")
endif()
else()
set(COMPILER_FLAGS "${COMPILER_FLAGS} -O3 -flto")
if (MSVC)
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} /O2 /LTCG")
else()
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -O3 -flto")
endif()
endif()
# Debug info
if (DEBINFO)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -g -DDEBINFO=1")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DDEBINFO=1")
if (MSVC)
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} /Zi")
else()
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -g")
endif()
endif()
# ASAN
@ -218,12 +271,17 @@ if (ASAN)
if (NOT CRTLIB)
message(FATAL_ERROR "CRTLIB (C runtime library) Must be enabled when compiling with ASAN")
endif()
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fsanitize=address -shared-libasan -DASAN=1")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DASAN=1")
if (MSVC)
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} /fsanitize=address")
else()
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -fsanitize=address -shared-libasan")
endif()
endif()
# Developer mode
if(DEVELOPER)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -DDEVELOPER=1")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DDEVELOPER=1")
endif()
# Profiling
@ -231,16 +289,19 @@ if(PROFILING)
if (NOT CRTLIB)
message(FATAL_ERROR "CRTLIB (C runtime library) Must be enabled when compiling with PROFILING")
endif()
set(COMPILER_FLAGS "${COMPILER_FLAGS} -DPROFILING=1")
if (MSVC)
message(FATAL_ERROR "MSVC not supported with PROFILING enabled (Profiling relies on Clang attributes)")
endif()
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DPROFILING=1")
# Tracy flags
set(COMPILER_FLAGS "${COMPILER_FLAGS} -DTRACY_ENABLE=1")
set(COMPILER_FLAGS "${COMPILER_FLAGS} -DTRACY_CALLSTACK=5")
set(COMPILER_FLAGS "${COMPILER_FLAGS} -DTRACY_NO_SAMPLING -DTRACY_NO_SYSTEM_TRACING -DTRACY_NO_CALLSTACK")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DTRACY_ENABLE=1")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DTRACY_CALLSTACK=5")
set(COMPILER_AND_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} -DTRACY_NO_SAMPLING -DTRACY_NO_SYSTEM_TRACING -DTRACY_NO_CALLSTACK")
# Disable warnings when compiling tracy client
set(COMPILER_WARNINGS "-Wno-everything")
endif()
set(CMAKE_C_FLAGS "${COMPILER_FLAGS} ${COMPILER_WARNINGS} -std=c99")
set(CMAKE_CXX_FLAGS "${COMPILER_FLAGS} ${COMPILER_WARNINGS} -std=c++14")
set(CMAKE_EXE_LINKER_FLAGS "${COMPILER_FLAGS} ${LINKER_FLAGS}")
set(CMAKE_C_FLAGS "${COMPILER_AND_LINKER_FLAGS} ${COMPILER_FLAGS} ${COMPILER_WARNINGS} ${C_VERSION}")
set(CMAKE_CXX_FLAGS "${COMPILER_AND_LINKER_FLAGS} ${COMPILER_FLAGS} ${COMPILER_WARNINGS} ${CPP_VERSION}")
set(CMAKE_EXE_LINKER_FLAGS "${COMPILER_AND_LINKER_FLAGS} ${LINKER_FLAGS}")

View File

@ -6,6 +6,9 @@ setlocal
:: "developer" The target will include all developer tooling
:: "profiling" The target will be compiled with profiling markup
:: "asan" The target will compile with address sanitizer enabled
:: "msvc" Compile with MSVC instead of Clang
for %%a in (%*) do set "%%a=1"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Verify environment
@ -16,14 +19,21 @@ if "%Platform%" neq "x64" (
exit /b 1
)
where /q clang.exe || (
echo ERROR: "clang.exe" not found.
exit /b 1
)
if "%msvc%" == "1" (
where /q cl.exe || (
echo ERROR: "cl.exe" not found.
exit /b 1
)
) else (
where /q clang.exe || (
echo ERROR: "clang.exe" not found.
exit /b 1
)
where /q lld-link || (
echo ERROR: "lld-link.exe" not found.
exit /b 1
where /q lld-link || (
echo ERROR: "lld-link.exe" not found.
exit /b 1
)
)
where /q ninja.exe || (
@ -42,13 +52,18 @@ where /q cmake || (
:: Must explicitly pass disabled CMake options or else missing options are
:: assumed to be equal to the value from the last build
set cmake_options_zero=-DRTC=0 -DASAN=0 -DCRTLIB=0 -DDEBINFO=0 -DDEVELOPER=0 -DPROFILING=0 -DUNOPTIMIZED=0
set cmake_options_zero=-DRTC=0 -DASAN=0 -DCRTLIB=0 -DDEBINFO=0 -DDEVELOPER=0 -DPROFILING=0 -DUNOPTIMIZED=0 -DMSVC=0
set cmake_options_enabled=
echo ========================================
for %%a in (%*) do set "%%a=1"
if "%msvc%" == "1" (
echo [Msvc]
set cmake_options_enabled=%cmake_options_enabled% -DMSVC=1
) else (
echo [Clang]
)
if "%debug%" == "1" (
echo [Debug build]
@ -82,17 +97,32 @@ echo ========================================
if not exist "build" mkdir build
cmake -H. -G Ninja -B build %cmake_options_zero% %cmake_options_enabled%^
-DCMAKE_C_COMPILER:PATH="clang.exe"^
-DCMAKE_CXX_COMPILER:PATH="clang.exe"^
-DCMAKE_C_COMPILER_ID="Clang"^
-DCMAKE_CXX_COMPILER_ID="Clang"^
-DCMAKE_SYSTEM_NAME="Generic"^
-DPLATFORM_WIN32=1
if "%msvc%" == "1" (
cmake -H. -G Ninja -B build %cmake_options_zero% %cmake_options_enabled%^
-DCMAKE_C_COMPILER:PATH="cl.exe"^
-DCMAKE_CXX_COMPILER:PATH="cl.exe"^
-DPLATFORM_WIN32=1
) else (
cmake -H. -G Ninja -B build %cmake_options_zero% %cmake_options_enabled%^
-DCMAKE_C_COMPILER:PATH="clang.exe"^
-DCMAKE_CXX_COMPILER:PATH="clang.exe"^
-DCMAKE_C_COMPILER_ID="Clang"^
-DCMAKE_CXX_COMPILER_ID="Clang"^
-DCMAKE_SYSTEM_NAME="Generic"^
-DPLATFORM_WIN32=1
)
if NOT %errorlevel% == 0 exit /b 1
if NOT %errorlevel% == 0 (
echo.
echo ERROR: Configuration failed
exit /b 1
)
cmake --build build
:: cmake --build build -v
exit /b %errorlevel%
if NOT %errorlevel% == 0 (
echo.
echo ERROR: Build failed
exit /b 1
)

View File

@ -408,7 +408,7 @@ enum cel_type {
CEL_TYPE_COMPRESSED_TILEMAP = 3
};
struct ase_header {
PACK(struct ase_header {
u32 file_size;
u16 magic;
u16 frames;
@ -429,16 +429,16 @@ struct ase_header {
u16 grid_width;
u16 grid_height;
u8 _4[84];
} PACKED;
});
struct frame_header {
PACK(struct frame_header {
u32 bytes;
u16 magic;
u16 chunks_old;
u16 frame_duration_ms;
u8 _[2];
u32 chunks_new;
} PACKED;
});
INTERNAL void push_error_copy_msg(struct arena *arena, struct ase_error_list *list, struct string msg_src)
{

View File

@ -1,7 +1,7 @@
#ifndef ATOMIC_H
#define ATOMIC_H
#if OS_WINDOWS
#if PLATFORM_WINDOWS
FORCE_INLINE i32 atomic_i32_eval(struct atomic_i32 *x) { return _InterlockedOr((volatile long *)&x->_v, 0); }
FORCE_INLINE i32 atomic_i32_inc_eval(struct atomic_i32 *x) { return _InterlockedIncrement((volatile long *)&x->_v); }

View File

@ -73,39 +73,39 @@ extern "C" {
* ========================== */
/* Compiler */
#if defined(_MSC_VER) && !defined(__clang__)
# define COMPILER_MSVC 1
# define COMPILER_CLANG 0
# define COMPILER_GCC 0
#elif defined(__clang__)
# define COMPILER_MSVC 0
#if defined(__clang__)
# define COMPILER_CLANG 1
# define COMPILER_GCC 0
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_MSVC 0
#elif defined(_MSC_VER)
# define COMPILER_CLANG 0
# define COMPILER_GCC 1
# define COMPILER_MSVC 1
#else
# error "Unknown compiler"
#endif
/* Operating system */
#if defined(_WIN32)
# define OS_WINDOWS 1
# define OS_MAC 0
# define OS_LINUX 0
# define PLATFORM_WINDOWS 1
# define PLATFORM_MAC 0
# define PLATFORM_LINUX 0
#elif defined(__APPLE__) && defined(__MACH__)
# define OS_WINDOWS 0
# define OS_MAC 1
# define OS_LINUX 0
# define PLATFORM_WINDOWS 0
# define PLATFORM_MAC 1
# define PLATFORM_LINUX 0
#elif defined(__gnu_linux__)
# define OS_WINDOWS 0
# define OS_MAC 0
# define OS_LINUX 1
# define PLATFORM_WINDOWS 0
# define PLATFORM_MAC 0
# define PLATFORM_LINUX 1
#else
# error "Unknown OS"
#endif
#if defined(__cplusplus)
# define LANGUAGE_CPP 1
#else
# define LANGUAGE_C 1
#endif
/* ========================== *
* Debug
* ========================== */
@ -115,22 +115,31 @@ extern "C" {
#define CT_ASSERT2(cond, line) CT_ASSERT3(cond, line)
#define CT_ASSERT(cond) CT_ASSERT2(cond, __LINE__)
#if DEBINFO
# define DEBUG_ALIAS(var, alias) __attribute((used)) *(alias) = &(var);
#if COMPILER_MSVC
# if DEBINFO
# define DEBUG_ALIAS(var, alias) *(alias) = &(var);
# else
# define DEBUG_ALIAS(var, alias) *(alias) = &(var);
# endif
#else
# define DEBUG_ALIAS(var, alias) __attribute((unused)) *(alias) = &(var);
# if DEBINFO
# define DEBUG_ALIAS(var, alias) __attribute((used)) *(alias) = &(var);
# else
# define DEBUG_ALIAS(var, alias) __attribute((unused)) *(alias) = &(var);
# endif
#endif
#if RTC
#define ASSERT(cond) ((cond) ? 1 : (__builtin_trap(), 0))
#define DEBUGBREAK __builtin_debugtrap()
#define DEBUGBREAKABLE { volatile i32 __DEBUGBREAKABLE_VAR = 0; (UNUSED) __DEBUGBREAKABLE_VAR; }
# if COMPILER_MSVC
# define ASSERT(cond) ((cond) ? 1 : ((*(volatile int *)0) = 0, 0))
# define DEBUGBREAK __debugbreak
# else
# define ASSERT(cond) ((cond) ? 1 : (__builtin_trap(), 0))
# define DEBUGBREAK __builtin_debugtrap()
# endif
# define DEBUGBREAKABLE { volatile i32 __DEBUGBREAKABLE_VAR = 0; (UNUSED) __DEBUGBREAKABLE_VAR; }
#else
#define ASSERT(cond) (void)(0)
# define ASSERT(cond) (void)(0)
#endif
/* Address sanitization */
@ -148,6 +157,12 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
* Common macros
* ========================== */
#if COMPILER_MSVC && LANGUAGE_CPP
# define CPPFRIENDLY_INITLIST_TYPE(type) type
# else
# define CPPFRIENDLY_INITLIST_TYPE(type) (type)
#endif
#if 1
# define INLINE static inline
#else
@ -155,7 +170,11 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
# define INLINE static inline __attribute((always_inline))
#endif
#define FORCE_INLINE static inline __attribute((always_inline))
#if COMPILER_MSVC
# define FORCE_INLINE static inline __forceinline
#else
# define FORCE_INLINE static inline __attribute((always_inline))
#endif
/* Separate `static` usage into different keywords for easier grepping */
#define LOCAL_PERSIST static
@ -163,9 +182,14 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
#define GLOBAL static
/* Read-only */
#if OS_WINDOWS
# define READONLY __declspec(allocate(".rdata"))
#elif OS_MAC
#if PLATFORM_WINDOWS
# if COMPILER_MSVC
# pragma section(".rdata$", read)
# define READONLY __declspec(allocate(".rdata$"))
# else
# define READONLY __declspec(allocate(".rdata"))
# endif
#elif PLATFORM_MAC
#define READONLY __attribute((section("__TEXT,__const")))
#else
#define READONLY __attribute((section(".rodata")))
@ -173,7 +197,12 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
/* Markup */
#define UNUSED void
#if COMPILER_CLANG
#define FALLTHROUGH __attribute((fallthrough))
#else
#define FALLTHROUGH
#endif
/* Sizes */
#define KILOBYTE(n) (n*1024ULL)
@ -182,18 +211,25 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
#define TERABYTE(n) (n*GIGABYTE(1024ULL))
/* typeof */
#if defined(__cplusplus) || (__STDC_VERSION__ < 202311L)
# define typeof(type) __typeof__(type)
#if LANGUAGE_CPP || (__STDC_VERSION__ < 202311L)
# if COMPILER_MSVC
/* Typeof not supported in MSVC */
# define typeof(type) ASSERT(false)
# define TYPEOF_DEFINED 0
# else
# define typeof(type) __typeof__(type)
# define TYPEOF_DEFINED 1
# endif
#endif
/* alignof */
#if !defined(__cplusplus) && (__STDC_VERSION__ < 202311L)
# define alignof(type) __alignof__(type)
#if LANGUAGE_C && (__STDC_VERSION__ < 202311L)
# define alignof(type) __alignof(type)
#endif
#define ARRAY_COUNT(a) (sizeof(a) / sizeof((a)[0]))
/* field macros */
/* Field macros */
#define FIELD_SIZEOF(type, field) sizeof(((type *)0)->field)
#if COMPILER_MSVC && !defined _CRT_USE_BUILTIN_OFFSETOF
# define FIELD_OFFSETOF(type, field) ((u64)&(((type *)0)->field))
@ -212,24 +248,31 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
#define IS_ARRAY(a) (IS_INDEXABLE(a) && (((void *)&a) == ((void *)a)))
/* Pack */
#define PACKED __attribute((__packed__))
#if COMPILER_MSVC
# define PACK(s) __pragma(pack(push, 1)) s __pragma(pack(pop))
#else
# define PACK(s) s __attribute((__packed__))
#endif
/* Color */
#define RGBA(r, g, b, a) (u32)((u32)(r) | ((u32)(g) << 8) | ((u32)(b) << 16) | ((u32)(a) << 24))
#define RGB(r, g, b) RGBA(r, g, b, 0xFF)
#define RGBA_32(r, g, b, a) (u32)((u32)(r) | ((u32)(g) << 8) | ((u32)(b) << 16) | ((u32)(a) << 24))
#define RGB_32(r, g, b) RGBA_32(r, g, b, 0xFF)
#define _RGB_F_TO_U8(f) ((u8)((f * 255.0f) + 0.5f))
#define RGBA_F(r, g, b, a) RGBA(_RGB_F_TO_U8(r), _RGB_F_TO_U8(g), _RGB_F_TO_U8(b), _RGB_F_TO_U8(a))
#define RGB_F(r, g, b) RGBA_F(r, g, b, 1.f)
#define RGBA_32_F(r, g, b, a) RGBA_32(_RGB_F_TO_U8(r), _RGB_F_TO_U8(g), _RGB_F_TO_U8(b), _RGB_F_TO_U8(a))
#define RGB_32_F(r, g, b) RGBA_32_F(r, g, b, 1.f)
#define COLOR_WHITE RGB(0xFF, 0xFF, 0xFF)
#define COLOR_BLACK RGB(0, 0, 0 )
#define COLOR_RED RGB(0xFF, 0, 0 )
#define COLOR_GREEN RGB(0, 0xFF, 0 )
#define COLOR_BLUE RGB(0, 0, 0xFF)
#define COLOR_WHITE RGB_32(0xFF, 0xFF, 0xFF)
#define COLOR_BLACK RGB_32(0, 0, 0 )
#define COLOR_RED RGB_32(0xFF, 0, 0 )
#define COLOR_GREEN RGB_32(0, 0xFF, 0 )
#define COLOR_BLUE RGB_32(0, 0, 0xFF)
/* Barrier */
#if defined(__x86_64) || defined(__i386__)
#if COMPILER_MSVC
# define WRITE_BARRIER() _WriteBarrier()
# define READ_BARRIER() _ReadBarrier()
#elif defined(__x86_64) || defined(__i386__)
# define WRITE_BARRIER() __asm__ volatile("" ::: "memory")
# define READ_BARRIER() __asm__ volatile("" ::: "memory")
#else
@ -258,24 +301,19 @@ typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef __int128_t i128;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef __uint128_t u128;
typedef float f32;
typedef double f64;
typedef i8 b8;
typedef i32 b32;
#define I128(hi64, lo64) (((i128)(hi64) << 64) | (lo64))
#define U128(hi64, lo64) (((u128)(hi64) << 64) | (lo64))
#define U8_MAX (0xFF)
#define U16_MAX (0xFFFF)
#define U32_MAX (0xFFFFFFFF)
#define U64_MAX (0xFFFFFFFFFFFFFFFFULG)
#define U64_MAX (0xFFFFFFFFFFFFFFFFULL)
#define I8_MAX (0x7F)
#define I16_MAX (0x7FFF)
@ -287,12 +325,74 @@ typedef i32 b32;
#define I32_MIN ((i32)-0x80000000)
#define I64_MIN ((i64)-0x8000000000000000LL)
#define F32_INFINITY (1.0 / 0.0f)
#define F64_INFINITY (1.0 / 0.0)
GLOBAL const u32 _f32_infinity_u32 = 0x7f800000;
GLOBAL const f32 *_f32_infinity = (f32 *)&_f32_infinity_u32;
GLOBAL const u64 _f64_infinity_u64 = 0x7ff0000000000000ULL;
GLOBAL const f64 *_f64_infinity = (f64 *)&_f64_infinity_u64;
#define F32_INFINITY (*_f32_infinity)
#define F64_INFINITY (*_f64_infinity)
#define PI ((f32)3.14159265358979323846)
#define TAU ((f32)6.28318530717958647693)
/* ========================== *
* Big int
* ========================== */
#if COMPILER_CLANG
#define U128(hi64, lo64) (((u128)(hi64) << 64) | (lo64))
#define U128_HI64(a) ((u64)((a) >> 64))
#define U128_LO64(a) ((u64)(a))
typedef __uint128_t u128;
INLINE b32 u128_eq(u128 a, u128 b) { return a == b; }
INLINE u128 u128_xor_u8(u128 a, u8 b) { return a ^ b; }
INLINE u128 u128_mul(u128 a, u128 b) { return a * b; }
#elif COMPILER_MSVC
#ifdef __cplusplus
# define U128(hi64, lo64) { (hi64), (lo64) }
#else
# define U128(hi64, lo64) ((u128) { .hi = (hi64), .lo = (lo64) })
#endif
#define U128_HI64(a) ((a).hi)
#define U128_LO64(a) ((a).lo)
typedef struct { u64 hi; u64 lo; } u128;
INLINE b32 u128_eq(u128 a, u128 b) { return a.hi == b.hi && a.lo == b.lo; }
INLINE u128 u128_xor_u8(u128 a, u8 b) { return U128(a.hi, a.lo ^ b); }
/* https://www.codeproject.com/Tips/784635/UInt-Bit-Operations */
u128 u128_mul(u128 a, u128 b)
{
u64 a1 = (a.lo & 0xffffffff);
u64 b1 = (b.lo & 0xffffffff);
u64 t = (a1 * b1);
u64 w3 = (t & 0xffffffff);
u64 k = (t >> 32);
a.lo >>= 32;
t = (a.lo * b1) + k;
k = (t & 0xffffffff);
u64 w1 = (t >> 32);
b.lo >>= 32;
t = (a1 * b.lo) + k;
k = (t >> 32);
u128 res = U128((a.lo * b.lo) + w1 + k, (t << 32) + w3);
res.hi += (a.hi * b.lo) + (a.lo * b.hi);
return res;
}
#endif
/* ========================== *
* Atomics
* ========================== */
@ -380,7 +480,7 @@ struct sprite_tag {
* ========================== */
/* Utility buffer constructor */
#define BUFFER(size, data) (struct buffer) {size, data}
#define BUFFER(size, data) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { (size), (data) })
/* Utility buffer constructor from static array */
#define BUFFER_FROM_ARRAY(a) \
@ -388,40 +488,27 @@ struct sprite_tag {
/* Must be array */ \
ASSERT(IS_ARRAY(a)), \
/* Must be array of bytes */ \
ASSERT(sizeof(a[0]) == sizeof(u8)), \
((struct buffer) { .size = ARRAY_COUNT(a), .data = (u8 *)a }) \
ASSERT(sizeof((a)[0]) == sizeof(u8)), \
((struct buffer) { .size = ARRAY_COUNT(a), .data = (u8 *)(a) }) \
)
#define BUFFER_FROM_STRING(str) ((struct buffer) { str.len, str.text })
#define BUFFER_FROM_STRING(str) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { (str).len, (str).text })
#define BUFFER_FROM_POINTERS(p1, p2) ((struct buffer) { (u8 *)(p2) - (u8 *)(p1), (u8 *)p1 })
#define BUFFER_FROM_POINTERS(p1, p2) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { (u8 *)(p2) - (u8 *)(p1), (u8 *)p1 })
#define BUFFER_FROM_STRUCT(ptr) ((struct buffer) { sizeof(*ptr), ptr })
#define BUFFER_FROM_STRUCT(ptr) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { sizeof(*(ptr)), (ptr) })
/* ========================== *
* String utils
* ========================== */
/* Expand C string literal with size for string initialization */
#ifdef __cplusplus
#define STR(cstr_lit) { \
(sizeof((cstr_lit)) - 1), \
(u8 *)(cstr_lit) \
}
#else
#define STR(cstr_lit) (struct string) { \
.len = (sizeof((cstr_lit)) - 1), \
.text = (u8 *)(cstr_lit) \
}
#endif
#define STR(cstr_lit) CPPFRIENDLY_INITLIST_TYPE(struct string) { (sizeof((cstr_lit)) - 1), (u8 *)(cstr_lit) }
/* Same as `STR`, but works with static variable initialization */
#define STR_NOCAST(cstr_lit) { \
.len = (sizeof((cstr_lit)) - 1), \
.text = (u8 *)(cstr_lit) \
}
#define STR_NOCAST(cstr_lit) { .len = (sizeof((cstr_lit)) - 1), .text = (u8 *)(cstr_lit) }
#define STRING_FROM_BUFFER(buff) ((struct string) { buff.size, buff.data })
#define STRING_FROM_BUFFER(buff) (CPPFRIENDLY_INITLIST_TYPE(struct string) { buff.size, buff.data })
#define STRING_FROM_ARRAY(a) STRING_FROM_BUFFER(BUFFER_FROM_ARRAY(a))
@ -537,7 +624,9 @@ INLINE f64 clamp_f64(f64 v, f64 min, f64 max) { return v < min ? min : v > max ?
#define PROFILING_CAPTURE_FRAME_IMAGE 1
/* Clang/GCC cleanup macros */
#if COMPILER_CLANG || COMPILER_GCC
#if COMPILER_MSVC
# error "MSVC not supported for profiling (cleanup attributes are required for profiling markup)"
#else
# ifdef TRACY_NO_CALLSTACK
# define __prof static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; __attribute((cleanup(__prof_zone_cleanup_func))) TracyCZoneCtx __tracy_ctx = ___tracy_emit_zone_begin( &CAT(__tracy_source_location,__LINE__), true );
# define __profscope(name) static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, #name, __FILE__, (uint32_t)__LINE__, 0 }; __attribute((cleanup(__prof_zone_cleanup_func))) TracyCZoneCtx __tracy_ctx = ___tracy_emit_zone_begin( &CAT(__tracy_source_location,__LINE__), true );

View File

@ -3,9 +3,9 @@
/* Accessed via entity_nil() */
READONLY struct entity _g_entity_nil = {
.rel_xform = XFORM_IDENT,
.world_xform = XFORM_IDENT,
.sprite_quad_xform = XFORM_IDENT,
.rel_xform = XFORM_IDENT_NOCAST,
.world_xform = XFORM_IDENT_NOCAST,
.sprite_quad_xform = XFORM_IDENT_NOCAST,
.sprite_tint = COLOR_WHITE
};

View File

@ -262,7 +262,7 @@ INTERNAL void game_update(void)
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));;
e->sprite_span_name = STR("UNARMED");
e->sprite_tint = RGBA_F(0.5, 0.5, 0, 1);
e->sprite_tint = RGBA_32_F(0.5, 0.5, 0, 1);
//entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
//e->player_max_speed = 5.f;
@ -311,7 +311,7 @@ INTERNAL void game_update(void)
e->sprite_quad_xform = xform_with_scale(XFORM_IDENT, sprite_size);
e->sprite = sprite_tag_from_path(STR("res/graphics/sound.ase"));;
e->sprite_tint = RGBA_F(1, 1, 0, 1);
e->sprite_tint = RGBA_32_F(1, 1, 0, 1);
entity_enable_prop(e, ENTITY_PROP_TEST_SOUND_EMITTER);
e->sound_name = STR("res/sounds/test.mp3");

91
src/incbin.c Normal file
View File

@ -0,0 +1,91 @@
#if COMPILER_MSVC
/* ========================== *
* Msvc RC file lookup
* ========================== */
#include "incbin.h"
#include "scratch.h"
#include "string.h"
#include "atomic.h"
#include "intrinsics.h"
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <Windows.h>
struct rc_search_params {
/* In */
struct string16 name;
/* Out */
b32 found;
struct buffer data;
};
/* Find first resource with `type` and return the data in `udata`. */
INTERNAL BOOL CALLBACK enum_func(HMODULE module, LPCWSTR type, LPCWSTR wstr_entry_name, LONG_PTR udata)
{
struct rc_search_params *params = (struct rc_search_params *)udata;
struct string16 entry_name = string16_from_wstr((LPWSTR)wstr_entry_name);
u64 cmp_size = min_u64(entry_name.len, params->name.len) * 2;
b32 match = MEMCMP(entry_name.text, params->name.text, cmp_size) == 0;
if (match) {
HRSRC hres = FindResourceW(module, wstr_entry_name, type);
if (hres) {
HGLOBAL hg = LoadResource(module, hres);
if (hg) {
params->found = true;
params->data.size = SizeofResource(module, hres);
params->data.data = LockResource(hg);
return true;
}
}
}
params->found = false;
params->data = BUFFER(0, 0);
return false;
}
struct buffer _incbin_get(struct _incbin_rc_resource *inc)
{
enum inc_state state = atomic_i32_eval(&inc->state);
if (state == INCBIN_STATE_SEARCHED) {
return inc->data;
}
if (state == INCBIN_STATE_UNSEARCHED) {
enum inc_state v = atomic_i32_eval_compare_exchange(&inc->state, state, INCBIN_STATE_SEARCHING) == state;
if (v == state) {
struct temp_arena scratch = scratch_begin_no_conflict();
{
/* Search */
struct string16 name16 = string16_from_string(scratch.arena, inc->rc_name);
struct rc_search_params params = { .name = name16 };
EnumResourceNamesW(NULL, RT_RCDATA, &enum_func, (LONG_PTR)&params);
if (!params.found) {
sys_panic(string_format(scratch.arena,
STR("INCBIN include not found in RC file: \"%F\""),
FMT_STR(inc->rc_name)));
}
inc->data = params.data;
state = INCBIN_STATE_SEARCHED;
atomic_i32_eval_exchange(&inc->state, state);
}
scratch_end(scratch);
} else {
state = v;
}
}
/* Spin while another thread is searching */
while (state != INCBIN_STATE_SEARCHED) {
ix_pause();
state = atomic_i32_eval(&inc->state);
}
return inc->data;
}
#endif

View File

@ -1,12 +1,47 @@
#ifndef INCBIN_H
#define INCBIN_H
#if COMPILER_MSVC
/* ========================== *
* Msvc RC file incbin
*
* NOTE: Msvc doesn't have an inline assembler that can include binary data.
* So instead these macros will trigger a lookup into the embedded RC file for
* entries matched by name (requires the build system to generate and link RC
* file).
* ========================== */
#define INCBIN_INCLUDE(var, _rc_name) static struct _incbin_rc_resource _incbin_ ## var = { .rc_name = STR_NOCAST((_rc_name)) }
#define INCBIN_GET(var) _incbin_get(&_incbin_ ## var)
enum _incbin_state {
INCBIN_STATE_UNSEARCHED,
INCBIN_STATE_SEARCHING,
INCBIN_STATE_SEARCHED
};
struct _incbin_rc_resource {
struct atomic_i32 state;
struct string rc_name;
struct buffer data;
};
struct buffer _incbin_get(struct _incbin_rc_resource *inc);
#else
/* ========================== *
* Clang incbin
* ========================== */
#define INCBINSTR2(x) #x
#define INCBINSTR(x) INCBINSTR2(x)
#if OS_WINDOWS
#if PLATFORM_WINDOWS
# define INCBIN_SECTION ".rdata, \"dr\""
#elif OS_MAC
#elif PLATFORM_MAC
# define INCBIN_SECTION "__TEXT,__const"
#else
# define INCBIN_SECTION ".rodata"
@ -14,21 +49,23 @@
/* Includes raw binary data into the executable. */
/* https://gist.github.com/mmozeiko/ed9655cf50341553d282 */
#define INCBIN_INCLUDE(name, file) \
#define INCBIN_INCLUDE(var, filename) \
__asm__(".section " INCBIN_SECTION "\n" \
".global _incbin_" INCBINSTR(name) "_start\n" \
".global _incbin_" INCBINSTR(var) "_start\n" \
".balign 16\n" \
"_incbin_" INCBINSTR(name) "_start:\n" \
".incbin \"" file "\"\n" \
"_incbin_" INCBINSTR(var) "_start:\n" \
".incbin \"" filename "\"\n" \
\
".global _incbin_" INCBINSTR(name) "_end\n" \
".global _incbin_" INCBINSTR(var) "_end\n" \
".balign 1\n" \
"_incbin_" INCBINSTR(name) "_end:\n" \
"_incbin_" INCBINSTR(var) "_end:\n" \
); \
extern __attribute((aligned(16))) const char _incbin_ ## name ## _start[]; \
extern const char _incbin_ ## name ## _end[]
extern __attribute((aligned(16))) const char _incbin_ ## var ## _start[]; \
extern const char _incbin_ ## var ## _end[]
/* Retrieve a buffer for included data using the name supplied to INCBIN_INCLUDE */
#define INCBIN_GET(name) BUFFER_FROM_POINTERS(_incbin_ ## name ## _start, _incbin_ ## name ## _end)
/* Retrieve a buffer for included data using the variable supplied to INCBIN_INCLUDE */
#define INCBIN_GET(var) BUFFER_FROM_POINTERS(_incbin_ ## var ## _start, _incbin_ ## var ## _end)
#endif
#endif

View File

@ -70,9 +70,9 @@ enum lex_number_state {
};
GLOBAL READONLY struct string g_keyword_strings[] = {
['t'] = STR("true"),
['f'] = STR("false"),
['n'] = STR("null")
['t'] = STR_NOCAST("true"),
['f'] = STR_NOCAST("false"),
['n'] = STR_NOCAST("null")
};
GLOBAL READONLY enum token_type g_keyword_types[] = {

View File

@ -59,10 +59,10 @@ void log_register_callback(log_event_callback_func *func);
#if LOG_LEVEL(LOG_LEVEL_CRITICAL)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_critical(msg) _log(LOG_LEVEL_CRITICAL, STR(__FILE__), __LINE__, msg)
# define logf_critical(fmt, ...) _logf(LOG_LEVEL_CRITICAL, STR(__FILE__), __LINE__, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_critical(fmt, ...) _logf(LOG_LEVEL_CRITICAL, STR(__FILE__), __LINE__, STR(fmt) , ## __VA_ARGS__, FMT_END)
# else
# define log_critical(msg) _log(LOG_LEVEL_CRITICAL, msg)
# define logf_critical(fmt, ...) _logf(LOG_LEVEL_CRITICAL, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_critical(fmt, ...) _logf(LOG_LEVEL_CRITICAL, STR(fmt) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_critical(msg)
@ -72,10 +72,10 @@ void log_register_callback(log_event_callback_func *func);
#if LOG_LEVEL(LOG_LEVEL_ERROR)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_error(msg) _log(LOG_LEVEL_ERROR, STR(__FILE__), __LINE__, msg)
# define logf_error(fmt, ...) _logf(LOG_LEVEL_ERROR, STR(__FILE__), __LINE__, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_error(fmt, ...) _logf(LOG_LEVEL_ERROR, STR(__FILE__), __LINE__, STR(fmt) , ## __VA_ARGS__, FMT_END)
# else
# define log_error(msg) _log(LOG_LEVEL_ERROR, msg)
# define logf_error(fmt, ...) _logf(LOG_LEVEL_ERROR, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_error(fmt, ...) _logf(LOG_LEVEL_ERROR, STR(fmt) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_error(msg)
@ -85,10 +85,10 @@ void log_register_callback(log_event_callback_func *func);
#if LOG_LEVEL(LOG_LEVEL_WARNING)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_warning(msg) _log(LOG_LEVEL_WARNING, STR(__FILE__), __LINE__, msg)
# define logf_warning(fmt, ...) _logf(LOG_LEVEL_WARNING, STR(__FILE__), __LINE__, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_warning(fmt, ...) _logf(LOG_LEVEL_WARNING, STR(__FILE__), __LINE__, STR(fmt) , ## __VA_ARGS__, FMT_END)
# else
# define log_warning(msg) _log(LOG_LEVEL_WARNING, msg)
# define logf_warning(fmt, ...) _logf(LOG_LEVEL_WARNING, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_warning(fmt, ...) _logf(LOG_LEVEL_WARNING, STR(fmt) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_warning(msg)
@ -98,10 +98,10 @@ void log_register_callback(log_event_callback_func *func);
#if LOG_LEVEL(LOG_LEVEL_DEBUG)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_debug(msg) _log(LOG_LEVEL_DEBUG, STR(__FILE__), __LINE__, msg)
# define logf_debug(fmt, ...) _logf(LOG_LEVEL_DEBUG, STR(__FILE__), __LINE__, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_debug(fmt, ...) _logf(LOG_LEVEL_DEBUG, STR(__FILE__), __LINE__, STR(fmt) , ## __VA_ARGS__, FMT_END)
# else
# define log_debug(msg) _log(LOG_LEVEL_DEBUG, msg)
# define logf_debug(fmt, ...) _logf(LOG_LEVEL_DEBUG, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_debug(fmt, ...) _logf(LOG_LEVEL_DEBUG, STR(fmt) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_debug(msg)
@ -112,10 +112,10 @@ void log_register_callback(log_event_callback_func *func);
#if LOG_LEVEL(LOG_LEVEL_INFO)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_info(msg) _log(LOG_LEVEL_INFO, STR(__FILE__), __LINE__, msg)
# define logf_info(fmt, ...) _logf(LOG_LEVEL_INFO, STR(__FILE__), __LINE__, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_info(fmt, ...) _logf(LOG_LEVEL_INFO, STR(__FILE__), __LINE__, STR(fmt) , ## __VA_ARGS__, FMT_END)
# else
# define log_info(msg) _log(LOG_LEVEL_INFO, msg)
# define logf_info(fmt, ...) _logf(LOG_LEVEL_INFO, STR(fmt), __VA_ARGS__, FMT_END)
# define logf_info(fmt, ...) _logf(LOG_LEVEL_INFO, STR(fmt) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_info(msg)

View File

@ -714,8 +714,9 @@ INLINE struct mat4x4 mat4x4_mul(struct mat4x4 m1, struct mat4x4 m2)
/* Construct identity xform */
#define XFORM_IDENT ((struct xform) { .bx.x = 1, .by.y = 1 })
#define XFORM_IDENT_NOCAST { .bx.x = 1, .by.y = 1 }
#define XFORM_POS(p) ((struct xform) { .bx.x = 1, .by.y = 1, .og = p })
#define XFORM_POS(p) ((struct xform) { .bx.x = 1, .by.y = 1, .og = (p) })
/* Takes a translation, rotation, and scale as optional parameters for constructing an xform */
#define XFORM_TRS(...) xform_from_trs((struct trs) { .t = V2(0,0), .s = V2(1, 1), .r = 0, __VA_ARGS__ })

View File

@ -8,6 +8,7 @@
#define COBJMACROS
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <Windows.h>
#include <uuids.h>
#include <mfapi.h>

View File

@ -14,6 +14,7 @@
#define COBJMACROS
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <Windows.h>
#include <initguid.h>
#include <objbase.h>

View File

@ -26,11 +26,11 @@ struct texture_shader_parameters {
struct sprite_tag sprite;
};
struct texture_shader_vertex {
PACK(struct texture_shader_vertex {
struct v2 pos;
struct v2 uv;
u32 color;
} PACKED;
});
/* ========================== *

View File

@ -9,6 +9,7 @@
#include "tar.h"
#include "sprite.h"
#define UNICODE
#include <Windows.h>
#define CINTERFACE
#define COBJMACROS

View File

@ -59,7 +59,7 @@ INLINE struct temp_arena _scratch_begin(struct arena *potential_conflict)
/* Use `scratch_begin_no_conflict` if no conflicts are present */
ASSERT(potential_conflict != NULL);
struct scratch_ctx *ctx = thread_local_var_eval(&tl_scratch_ctx);
struct scratch_ctx *ctx = (struct scratch_ctx *)thread_local_var_eval(&tl_scratch_ctx);
struct arena *scratch_arena = &ctx->arenas[0];
if (potential_conflict && scratch_arena->base == potential_conflict->base) {
scratch_arena = &ctx->arenas[1];
@ -83,7 +83,7 @@ INLINE struct temp_arena _scratch_begin(struct arena *potential_conflict)
INLINE struct temp_arena _scratch_begin_no_conflict(void)
{
struct scratch_ctx *ctx = thread_local_var_eval(&tl_scratch_ctx);
struct scratch_ctx *ctx = (struct scratch_ctx *)thread_local_var_eval(&tl_scratch_ctx);
struct arena *scratch_arena = &ctx->arenas[0];
struct temp_arena temp = arena_temp_begin(scratch_arena);
scratch_dbg_push(ctx, &temp);
@ -97,7 +97,7 @@ INLINE struct temp_arena _scratch_begin_no_conflict(void)
INLINE void scratch_end(struct temp_arena scratch_temp)
{
#if RTC
struct scratch_ctx *ctx = thread_local_var_eval(&tl_scratch_ctx);
struct scratch_ctx *ctx = (struct scratch_ctx *)thread_local_var_eval(&tl_scratch_ctx);
if (ctx->scratch_id_stack_count > 0) {
u64 scratch_id = scratch_temp.scratch_id;
u64 expected_id = ctx->scratch_id_stack[--ctx->scratch_id_stack_count];

View File

@ -321,12 +321,12 @@ struct sprite_tag sprite_tag_from_path(struct string path)
b32 sprite_tag_is_nil(struct sprite_tag tag)
{
return tag.hash == 0;
return u128_eq(tag.hash, U128(0, 0));
}
b32 sprite_tag_eq(struct sprite_tag t1, struct sprite_tag t2)
{
return t1.hash == t2.hash;
return u128_eq(t1.hash, t2.hash);
}
INTERNAL struct cache_node_hash cache_node_hash_from_tag_hash(u128 tag_hash, enum cache_node_kind kind)
@ -602,7 +602,7 @@ INTERNAL struct cache_node *node_lookup_touch(struct sprite_scope *scope, struct
struct cache_node **nonmatching_next = NULL;
struct cache_node_hash hash = cache_node_hash_from_tag_hash(tag.hash, kind);
u64 cache_bucket_index = hash.v % CACHE_BUCKETS_COUNT;
u64 cache_bucket_index = U128_LO64(hash.v) % CACHE_BUCKETS_COUNT;
struct cache_bucket *bucket = &G.cache.buckets[cache_bucket_index];
/* Lookup */
@ -612,7 +612,7 @@ INTERNAL struct cache_node *node_lookup_touch(struct sprite_scope *scope, struct
nonmatching_next = &bucket->first;
n = *nonmatching_next;
while (n) {
if (n->hash.v == hash.v) {
if (u128_eq(n->hash.v, hash.v)) {
scope_ensure_reference(scope, n, cache_bucket_index);
break;
} else {

View File

@ -24,7 +24,7 @@
#define TAR_TYPE_PAX_HEADER_X 'x'
#define TAR_TYPE_PAX_HEADER_G 'g'
struct tar_header {
PACK(struct tar_header {
/* Pre-posix */
u8 file_name[100];
u8 file_mode[8];
@ -47,7 +47,7 @@ struct tar_header {
u8 device_minor_number[8];
u8 file_name_prefix[155];
u8 padding[12];
} PACKED;
});
INTERNAL u64 str_oct_to_u64(struct string str)
{

View File

@ -10,14 +10,14 @@
#define MAX_THREAD_LOCAL_VARS 256
GLOBAL struct {
struct atomic_i64 metas_lock_flag;
struct atomic_i32 metas_lock_flag;
u64 metas_count;
struct thread_local_var_meta metas[MAX_THREAD_LOCAL_VARS];
} G = { 0 }, DEBUG_ALIAS(G, G_thread_local);
INTERNAL void metas_lock(void)
{
while (atomic_i64_eval_compare_exchange(&G.metas_lock_flag, 0, 1) == 0) {
while (atomic_i32_eval_compare_exchange(&G.metas_lock_flag, 0, 1) == 0) {
/* Spinlock */
ix_pause();
}
@ -25,7 +25,7 @@ INTERNAL void metas_lock(void)
INTERNAL void metas_unlock(void)
{
atomic_i64_eval_exchange(&G.metas_lock_flag, 0);
atomic_i32_eval_exchange(&G.metas_lock_flag, 0);
}
struct thread_local_store thread_local_store_alloc(void)

View File

@ -45,7 +45,7 @@ struct thread_local_var_meta {
#define THREAD_LOCAL_VAR_DECL_EXTERN(var_name, type) struct __thread_local_struct##var_name { struct thread_local_var_meta meta; type *_t; }; extern struct __thread_local_struct##var_name var_name;
#define THREAD_LOCAL_VAR_DEF_EXTERN(var_name, type, alloc_func, release_func) \
typeof(var_name) var_name = { \
struct __thread_local_struct##var_name var_name = { \
.meta = { \
.size = sizeof(type), \
.align = alignof(type), \
@ -54,7 +54,12 @@ struct thread_local_var_meta {
} \
}
#define thread_local_var_eval(var_ptr) (typeof((var_ptr)->_t))(_thread_local_var_eval(&(var_ptr)->meta));
#if TYPEOF_DEFINED
# define thread_local_var_eval(var_ptr) (typeof((var_ptr)->_t))(_thread_local_var_eval(&(var_ptr)->meta));
#else
# define thread_local_var_eval(var_ptr) (void *)(_thread_local_var_eval(&(var_ptr)->meta));
#endif
void *_thread_local_var_eval(struct thread_local_var_meta *meta);
#endif

View File

@ -53,25 +53,29 @@ struct ttf_startup_receipt ttf_startup(void)
* 10? Need to verify. Maybe should just use a custom loader. (We're only
* using a factory5 since I think WriteInMemoryFileLoader wasn't
* implemented until then) */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wlanguage-extension-token" /* for __uuidof */
#if COMPILER_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wlanguage-extension-token" /* for __uuidof */
#endif
HRESULT error = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory5),
(IUnknown **)&G.factory
);
#pragma clang diagnostic pop
#if COMPILER_CLANG
# pragma clang diagnostic pop
#endif
if (error) {
sys_panic(STR("Error creating DWrite factory"));
}
return (struct ttf_startup_receipt) { 0 };
return { 0 };
}
struct ttf_decode_result ttf_decode(struct arena *arena, struct buffer encoded, f32 point_size, u32 *cache_codes, u32 cache_codes_count)
{
COLORREF bg_color = RGB(0,0,0);
COLORREF fg_color = RGB(255,255,255);
COLORREF bg_color = RGB_32(0,0,0);
COLORREF fg_color = RGB_32(255,255,255);
IDWriteFactory5 *factory = G.factory;
@ -251,7 +255,7 @@ struct ttf_decode_result ttf_decode(struct arena *arena, struct buffer encoded,
u64 in_x = bounding_box.left + x;
u32 *out_pixel = out_data + (out_x + (out_y * atlas_w));
u32 *in_pixel = in_data + (in_x + (in_y * in_pitch));
*out_pixel = RGBA(0xFF, 0xFF, 0xFF, *in_pixel & 0xFF);
*out_pixel = RGBA_32(0xFF, 0xFF, 0xFF, *in_pixel & 0xFF);
}
}
out_offset_x += tex_w;

View File

@ -350,9 +350,9 @@ INTERNAL void debug_draw_xform(struct xform xf)
{
f32 thickness = 2.f;
f32 arrowhead_len = 15.f;
u32 color = RGBA_F(0, 1, 1, 0.3);
u32 color_x = RGBA_F(1, 0, 0, 0.3);
u32 color_y = RGBA_F(0, 1, 0, 0.3);
u32 color = RGBA_32_F(0, 1, 1, 0.3);
u32 color_x = RGBA_32_F(1, 0, 0, 0.3);
u32 color_y = RGBA_32_F(0, 1, 0, 0.3);
struct v2 pos = xform_mul_v2(G.world_view, xf.og);
struct v2 x_ray = xform_basis_mul_v2(G.world_view, xform_get_right(xf));
@ -372,8 +372,8 @@ INTERNAL void debug_draw_movement(struct entity *ent)
f32 thickness = 2.f;
f32 arrow_len = 15.f;
u32 color_vel = RGBA_F(1, 0.5, 0, 1);
u32 color_acc = RGBA_F(1, 1, 0.5, 1);
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
u32 color_acc = RGBA_32_F(1, 1, 0.5, 1);
struct v2 pos = xform_mul_v2(G.world_view, ent->world_xform.og);
struct v2 vel_ray = xform_basis_mul_v2(G.world_view, ent->velocity);
@ -698,7 +698,7 @@ INTERNAL void user_update(void)
* ========================== */
{
u32 color = RGBA_F(0.2f, 0.2f, 0.2f, 1.f);
u32 color = RGBA_32_F(0.2f, 0.2f, 0.2f, 1.f);
draw_solid_rect(G.viewport_bg_canvas, RECT(0, 0, G.viewport_size.x, G.viewport_size.y), color);
}
@ -708,9 +708,9 @@ INTERNAL void user_update(void)
{
f32 thickness = 3.f;
u32 color = RGBA(0x3f, 0x3f, 0x3f, 0xFF);
u32 x_color = RGBA(0x3f, 0, 0, 0xFF);
u32 y_color = RGBA(0, 0x3f, 0, 0xFF);
u32 color = RGBA_32(0x3f, 0x3f, 0x3f, 0xFF);
u32 x_color = RGBA_32(0x3f, 0, 0, 0xFF);
u32 y_color = RGBA_32(0, 0x3f, 0, 0xFF);
i64 startx = -10;
i64 starty = -10;
@ -802,7 +802,7 @@ INTERNAL void user_update(void)
/* Debug draw sprite quad */
{
f32 thickness = 2.f;
u32 color = RGBA_F(1, 1, 0, 0.25);
u32 color = RGBA_32_F(1, 1, 0, 0.25);
draw_solid_quad_line(G.world_canvas, quad, (thickness / PIXELS_PER_UNIT / G.world_view.zoom), color);
}
@ -813,7 +813,7 @@ INTERNAL void user_update(void)
/* Debug draw sprite pivot */
{
u32 color = RGBA_F(1, 0, 0, 1);
u32 color = RGBA_32_F(1, 0, 0, 1);
draw_solid_circle(G.world_canvas, ent->world_xform.og, 0.02, color, 20);
}
}
@ -870,7 +870,7 @@ INTERNAL void user_update(void)
/* Draw hierarchy */
struct entity *parent = entity_from_handle(&G.world.entity_store, ent->parent);
if (parent->valid) {
u32 color = RGBA_F(0.6, 0.6, 1, 0.75);
u32 color = RGBA_32_F(0.6, 0.6, 1, 0.75);
f32 thickness = 5;
f32 arrow_height = 15;
@ -881,7 +881,7 @@ INTERNAL void user_update(void)
/* Draw aim */
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
u32 color = RGBA_F(0.75, 0, 0.75, 0.5);
u32 color = RGBA_32_F(0.75, 0, 0.75, 0.5);
f32 thickness = 3;
f32 arrow_height = 10;
struct v2 pos = xform_mul_v2(G.world_view, ent->world_xform.og);
@ -891,7 +891,7 @@ INTERNAL void user_update(void)
/* Draw camera rect */
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
u32 color = ent == active_camera ? RGBA_F(1, 1, 1, 0.5) : RGBA_F(0, 0.75, 0, 0.5);
u32 color = ent == active_camera ? RGBA_32_F(1, 1, 1, 0.5) : RGBA_32_F(0, 0.75, 0, 0.5);
f32 thickness = 3;
@ -909,7 +909,7 @@ INTERNAL void user_update(void)
/* Draw crosshair or show cursor */
if (!G.debug_camera) {
struct v2 crosshair_pos = G.viewport_cursor;
u32 tint = RGBA_F(1, 1, 1, 1);
u32 tint = RGBA_32_F(1, 1, 1, 1);
struct sprite_tag crosshair_tag = sprite_tag_from_path(STR("res/graphics/crosshair.ase"));
struct sprite_texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair_tag);

View File

@ -34,8 +34,8 @@ INLINE u128 hash_fnv128(u128 seed, struct buffer buff)
u128 hash = seed;
for (u64 i = 0; i < buff.size; ++i) {
u8 c = (u8)buff.data[i];
hash ^= c;
hash *= U128(0x1000000, 0x000000000000013B);
hash = u128_xor_u8(hash, c);
hash = u128_mul(hash, U128(0x1000000, 0x000000000000013B));
}
return hash;
}