mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-22 20:51:31 +00:00
Merge pull request #795 from DanielGibson/MSVC-upd
Support building with Visual Studio (via CMake)
This commit is contained in:
commit
9654ed5562
17 changed files with 327 additions and 72 deletions
161
CMakeLists.txt
161
CMakeLists.txt
|
@ -28,6 +28,16 @@ endif()
|
||||||
# Add extended path for FreeBSD and Homebrew on OS X.
|
# Add extended path for FreeBSD and Homebrew on OS X.
|
||||||
list(APPEND CMAKE_PREFIX_PATH /usr/local)
|
list(APPEND CMAKE_PREFIX_PATH /usr/local)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
add_compile_options(/MP) # parallel build (use all cores, or as many as configured in VS)
|
||||||
|
|
||||||
|
# ignore some compiler warnings
|
||||||
|
add_compile_options(/wd4244 /wd4305) # possible loss of data/truncation (double to float etc; ignore)
|
||||||
|
add_compile_options(/wd4018) # signed/unsigned missmatch
|
||||||
|
add_compile_options(/wd4996) # 'function': was declared deprecated (like all that secure CRT stuff)
|
||||||
|
# don't show me warnings for system headers, why the fuck isn't this default
|
||||||
|
add_compile_options(/experimental:external /external:W0)
|
||||||
|
else() # GCC/clang/mingw
|
||||||
# Enforce compiler flags:
|
# Enforce compiler flags:
|
||||||
# -Wall -> More warnings
|
# -Wall -> More warnings
|
||||||
# -fno-strict-aliasing -> Quake 2 is far away from strict aliasing
|
# -fno-strict-aliasing -> Quake 2 is far away from strict aliasing
|
||||||
|
@ -35,7 +45,11 @@ list(APPEND CMAKE_PREFIX_PATH /usr/local)
|
||||||
# -fvisibility=hidden -> Force defaultsymbol visibility to hidden
|
# -fvisibility=hidden -> Force defaultsymbol visibility to hidden
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -fno-strict-aliasing -fwrapv -fvisibility=hidden")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -fno-strict-aliasing -fwrapv -fvisibility=hidden")
|
||||||
|
|
||||||
# Switch of some annoying warnings
|
# Use -O2 as maximum optimization level. -O3 has it's problems with yquake2.
|
||||||
|
string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||||
|
endif() # MSVC'S else-case
|
||||||
|
|
||||||
|
# Switch off some annoying warnings
|
||||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
|
if (${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
||||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU")
|
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU")
|
||||||
|
@ -44,9 +58,6 @@ elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Use -O2 as maximum optimization level. -O3 has it's problems with yquake2.
|
|
||||||
string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
|
||||||
|
|
||||||
# Compilation time options.
|
# Compilation time options.
|
||||||
option(CURL_SUPPORT "cURL support" ON)
|
option(CURL_SUPPORT "cURL support" ON)
|
||||||
option(OPENAL_SUPPORT "OpenAL support" ON)
|
option(OPENAL_SUPPORT "OpenAL support" ON)
|
||||||
|
@ -76,13 +87,82 @@ set(REF_SRC_DIR ${SOURCE_DIR}/client/refresh)
|
||||||
set(YQ2OSTYPE "${CMAKE_SYSTEM_NAME}" CACHE STRING "Override operation system type")
|
set(YQ2OSTYPE "${CMAKE_SYSTEM_NAME}" CACHE STRING "Override operation system type")
|
||||||
add_definitions(-DYQ2OSTYPE="${YQ2OSTYPE}")
|
add_definitions(-DYQ2OSTYPE="${YQ2OSTYPE}")
|
||||||
|
|
||||||
# Architecture string.
|
# Architecture string
|
||||||
set(YQ2ARCH "${CMAKE_SYSTEM_PROCESSOR}" CACHE STRING "Override CPU architecture")
|
# work around CMake's useless/broken CMAKE_SYSTEM_PROCESSOR (taken from dhewm3)
|
||||||
string(REGEX REPLACE "amd64" "x86_64" ARCH "${YQ2ARCH}")
|
|
||||||
string(REGEX REPLACE "i.86" "i386" ARCH "${ARCH}")
|
set(cpu ${CMAKE_SYSTEM_PROCESSOR})
|
||||||
string(REGEX REPLACE "^arm.*" "arm" ARCH "${ARCH}")
|
|
||||||
|
# Originally, ${CMAKE_SYSTEM_PROCESSOR} was supposed to contain the *target* CPU, according to CMake's documentation.
|
||||||
|
# As far as I can tell this has always been broken (always returns host CPU) at least on Windows
|
||||||
|
# (see e.g. https://cmake.org/pipermail/cmake-developers/2014-September/011405.html) and wasn't reliable on
|
||||||
|
# other systems either, for example on Linux with 32bit userland but 64bit kernel it returned the kernel CPU type
|
||||||
|
# (e.g. x86_64 instead of i686). Instead of fixing this, CMake eventually updated their documentation in 3.20,
|
||||||
|
# now it's officially the same as CMAKE_HOST_SYSTEM_PROCESSOR except when cross-compiling (where it's explicitly set)
|
||||||
|
# So we gotta figure out the actual target CPU type ourselves..
|
||||||
|
if(NOT (CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR))
|
||||||
|
# special case: cross-compiling, here CMAKE_SYSTEM_PROCESSOR should be correct, hopefully
|
||||||
|
# (just leave cpu at ${CMAKE_SYSTEM_PROCESSOR})
|
||||||
|
elseif(MSVC)
|
||||||
|
message(DEBUG "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}")
|
||||||
|
if(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
|
||||||
|
set(cpu "i386")
|
||||||
|
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x64")
|
||||||
|
set(cpu "x86_64")
|
||||||
|
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
|
||||||
|
# at least on RPi 32bit, gcc -dumpmachine outputs "arm-linux-gnueabihf",
|
||||||
|
# so we'll use "arm" there => use the same for 32bit ARM on MSVC
|
||||||
|
set(cpu "arm")
|
||||||
|
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
|
||||||
|
set(cpu "arm64")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unknown Target CPU/platform ${CMAKE_GENERATOR_PLATFORM}")
|
||||||
|
endif()
|
||||||
|
message(DEBUG " => CPU architecture extracted from that: \"${cpu}\"")
|
||||||
|
else() # not MSVC and not cross-compiling, assume GCC or clang (-compatible), seems to work for MinGW as well
|
||||||
|
execute_process(COMMAND ${CMAKE_C_COMPILER} "-dumpmachine"
|
||||||
|
RESULT_VARIABLE cc_dumpmachine_res
|
||||||
|
OUTPUT_VARIABLE cc_dumpmachine_out)
|
||||||
|
if(cc_dumpmachine_res EQUAL 0)
|
||||||
|
string(STRIP ${cc_dumpmachine_out} cc_dumpmachine_out) # get rid of trailing newline
|
||||||
|
message(DEBUG "`${CMAKE_C_COMPILER} -dumpmachine` says: \"${cc_dumpmachine_out}\"")
|
||||||
|
# gcc -dumpmachine and clang -dumpmachine seem to print something like "x86_64-linux-gnu" (gcc)
|
||||||
|
# or "x64_64-pc-linux-gnu" (clang) or "i686-w64-mingw32" (32bit mingw-w64) i.e. starting with the CPU,
|
||||||
|
# then "-" and then OS or whatever - so use everything up to first "-"
|
||||||
|
string(REGEX MATCH "^[^-]+" cpu ${cc_dumpmachine_out})
|
||||||
|
message(DEBUG " => CPU architecture extracted from that: \"${cpu}\"")
|
||||||
|
else()
|
||||||
|
message(WARNING "${CMAKE_C_COMPILER} -dumpmachine failed with error (code) ${cc_dumpmachine_res}")
|
||||||
|
message(WARNING "will use the (sometimes incorrect) CMAKE_SYSTEM_PROCESSOR (${cpu}) to determine YQ2ARCH")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(cpu STREQUAL "powerpc")
|
||||||
|
set(cpu "ppc")
|
||||||
|
elseif(cpu STREQUAL "aarch64")
|
||||||
|
# "arm64" is more obvious, and some operating systems (like macOS) use it instead of "aarch64"
|
||||||
|
set(cpu "arm64")
|
||||||
|
elseif(cpu MATCHES "i.86" OR cpu MATCHES "[xX]86")
|
||||||
|
set(cpu "i386")
|
||||||
|
elseif(cpu MATCHES "[aA][mM][dD]64" OR cpu MATCHES "[xX]64")
|
||||||
|
set(cpu "x86_64")
|
||||||
|
elseif(cpu MATCHES "[aA][rR][mM].*") # some kind of arm..
|
||||||
|
# On 32bit Raspbian gcc -dumpmachine returns sth starting with "arm-",
|
||||||
|
# while clang -dumpmachine says "arm6k-..." - try to unify that to "arm"
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # sizeof(void*) == 8 => must be arm64
|
||||||
|
set(cpu "arm64")
|
||||||
|
else() # should be 32bit arm then (probably "armv7l" "armv6k" or sth like that)
|
||||||
|
set(cpu "arm")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ARCH "${cpu}")
|
||||||
|
|
||||||
|
# END OF workarounds for CMake's poor choices regarding CPU architecture detection
|
||||||
|
|
||||||
add_definitions(-DYQ2ARCH="${ARCH}")
|
add_definitions(-DYQ2ARCH="${ARCH}")
|
||||||
|
|
||||||
|
message(STATUS "Setting YQ2OSTYPE to \"${YQ2OSTYPE}\" and YQ2ARCH to \"${ARCH}\".")
|
||||||
|
|
||||||
# Systemwide installation of game assets.
|
# Systemwide installation of game assets.
|
||||||
if(${SYSTEMWIDE_SUPPORT})
|
if(${SYSTEMWIDE_SUPPORT})
|
||||||
add_definitions(-DSYSTEMWIDE)
|
add_definitions(-DSYSTEMWIDE)
|
||||||
|
@ -91,7 +171,7 @@ endif()
|
||||||
# We need to pass some options to minizip / unzip.
|
# We need to pass some options to minizip / unzip.
|
||||||
add_definitions(-DNOUNCRYPT)
|
add_definitions(-DNOUNCRYPT)
|
||||||
|
|
||||||
if(NOT CMAKE_SYSTEM_NAME MATCHES "Linux" OR NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
|
if(NOT (CMAKE_SYSTEM_NAME MATCHES "Linux") AND NOT (CMAKE_SYSTEM_NAME MATCHES "Windows"))
|
||||||
add_definitions(-DIOAPI_NO_64)
|
add_definitions(-DIOAPI_NO_64)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -152,11 +232,15 @@ if(${OPENAL_SUPPORT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# General linker flags.
|
# General linker flags.
|
||||||
list(APPEND yquake2LinkerFlags "-lm")
|
if(!MSVC)
|
||||||
|
list(APPEND yquake2LinkerFlags "-lm")
|
||||||
|
endif()
|
||||||
list(APPEND yquake2LinkerFlags ${CMAKE_DL_LIBS})
|
list(APPEND yquake2LinkerFlags ${CMAKE_DL_LIBS})
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
list(APPEND yquake2LinkerFlags "-lws2_32 -lwinmm -static-libgcc")
|
if(!MSVC)
|
||||||
|
list(APPEND yquake2LinkerFlags "-static-libgcc")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
||||||
list(APPEND yquake2LinkerFlags "-rdynamic")
|
list(APPEND yquake2LinkerFlags "-rdynamic")
|
||||||
|
@ -169,10 +253,8 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT WIN32)
|
||||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
|
list(APPEND yquake2LinkerFlags "-Wl,--no-undefined")
|
||||||
list(APPEND yquake2LinkerFlags "-Wl,--no-undefined")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# With all of those libraries and user defined paths
|
# With all of those libraries and user defined paths
|
||||||
|
@ -578,30 +660,31 @@ set(SOFT-Header
|
||||||
${COMMON_SRC_DIR}/header/shared.h
|
${COMMON_SRC_DIR}/header/shared.h
|
||||||
)
|
)
|
||||||
|
|
||||||
# Wrapper for the Windows binary
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
|
||||||
set(Wrapper-Source
|
|
||||||
src/win-wrapper/wrapper.c
|
|
||||||
${BACKENDS_SRC_DIR}/windows/icon.rc
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Main Quake 2 executable
|
# Main Quake 2 executable
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
add_executable(yquake2 ${Client-Source} ${Client-Header} ${Platform-Specific-Source}
|
add_executable(yquake2 WIN32 ${Client-Source} ${Client-Header} ${Platform-Specific-Source}
|
||||||
${Backends-Generic-Source})
|
${Backends-Generic-Source})
|
||||||
set_target_properties(yquake2 PROPERTIES
|
set_target_properties(yquake2 PROPERTIES
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
C_STANDARD 11
|
||||||
)
|
)
|
||||||
target_link_libraries(yquake2 ${yquake2LinkerFlags} ${yquake2ClientLinkerFlags}
|
target_link_libraries(yquake2 ${yquake2LinkerFlags} ${yquake2ClientLinkerFlags}
|
||||||
${yquake2SDLLinkerFlags} ${yquake2ZLibLinkerFlags} ws2_32 winmm)
|
${yquake2SDLLinkerFlags} ${yquake2ZLibLinkerFlags} ws2_32 winmm)
|
||||||
|
|
||||||
|
if(MSVC AND CMAKE_MAJOR_VERSION GREATER 3 OR ( CMAKE_MAJOR_VERSION EQUAL 3 AND CMAKE_MINOR_VERSION GREATER_EQUAL 6 ))
|
||||||
|
# CMake >= 3.6 supports setting the default project started for debugging (instead of trying to launch ALL_BUILD ...)
|
||||||
|
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT yquake2)
|
||||||
|
set_target_properties(yquake2 PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/release)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Wrapper for the Windows binary
|
# Wrapper for the Windows binary
|
||||||
add_executable(quake2 ${Wrapper-Source})
|
set(Wrapper-Source
|
||||||
set_target_properties(quake2 PROPERTIES
|
src/win-wrapper/wrapper.c
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
${BACKENDS_SRC_DIR}/windows/icon.rc
|
||||||
)
|
)
|
||||||
|
add_executable(quake2 WIN32 ${Wrapper-Source})
|
||||||
|
set_target_properties(quake2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release)
|
||||||
else()
|
else()
|
||||||
add_executable(quake2 ${Client-Source} ${Client-Header} ${Platform-Specific-Source}
|
add_executable(quake2 ${Client-Source} ${Client-Header} ${Platform-Specific-Source}
|
||||||
${Backends-Generic-Source})
|
${Backends-Generic-Source})
|
||||||
|
@ -618,6 +701,7 @@ add_executable(q2ded ${Server-Source} ${Server-Header} ${Platform-Specific-Sourc
|
||||||
set_target_properties(q2ded PROPERTIES
|
set_target_properties(q2ded PROPERTIES
|
||||||
COMPILE_DEFINITIONS "DEDICATED_ONLY"
|
COMPILE_DEFINITIONS "DEDICATED_ONLY"
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
C_STANDARD 11
|
||||||
)
|
)
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
target_link_libraries(q2ded ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags} ${yquake2ZLibLinkerFlags} ws2_32 winmm)
|
target_link_libraries(q2ded ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags} ${yquake2ZLibLinkerFlags} ws2_32 winmm)
|
||||||
|
@ -627,12 +711,26 @@ endif()
|
||||||
|
|
||||||
# Build the game dynamic library
|
# Build the game dynamic library
|
||||||
add_library(game MODULE ${Game-Source} ${Game-Header})
|
add_library(game MODULE ${Game-Source} ${Game-Header})
|
||||||
|
|
||||||
set_target_properties(game PROPERTIES
|
set_target_properties(game PROPERTIES
|
||||||
PREFIX ""
|
PREFIX ""
|
||||||
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
C_STANDARD 11
|
||||||
|
)
|
||||||
|
|
||||||
|
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
if(isMultiConfig) # multi-config, like Visual Studio solution
|
||||||
|
set_target_properties(game PROPERTIES
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release/$<CONFIG>/baseq2
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release/$<CONFIG>/baseq2
|
||||||
|
)
|
||||||
|
else() # single-config, like normal Makefiles
|
||||||
|
set_target_properties(game PROPERTIES
|
||||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release/baseq2
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release/baseq2
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release/baseq2
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release/baseq2
|
||||||
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(game ${yquake2LinkerFlags})
|
target_link_libraries(game ${yquake2LinkerFlags})
|
||||||
|
|
||||||
# Build the GL1 dynamic library
|
# Build the GL1 dynamic library
|
||||||
|
@ -642,6 +740,7 @@ set_target_properties(ref_gl1 PROPERTIES
|
||||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
C_STANDARD 11
|
||||||
)
|
)
|
||||||
target_link_libraries(ref_gl1 ${yquake2LinkerFlags} ${yquake2OpenGLLinkerFlags} ${yquake2SDLLinkerFlags})
|
target_link_libraries(ref_gl1 ${yquake2LinkerFlags} ${yquake2OpenGLLinkerFlags} ${yquake2SDLLinkerFlags})
|
||||||
|
|
||||||
|
@ -652,6 +751,7 @@ set_target_properties(ref_gl3 PROPERTIES
|
||||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
C_STANDARD 11
|
||||||
)
|
)
|
||||||
target_link_libraries(ref_gl3 ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
target_link_libraries(ref_gl3 ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
||||||
|
|
||||||
|
@ -662,5 +762,6 @@ set_target_properties(ref_soft PROPERTIES
|
||||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
C_STANDARD 11
|
||||||
)
|
)
|
||||||
target_link_libraries(ref_soft ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
target_link_libraries(ref_soft ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
||||||
|
|
|
@ -97,14 +97,14 @@ Sys_Quit(void)
|
||||||
FreeConsole();
|
FreeConsole();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf( "------------------------------------\n" );
|
||||||
|
|
||||||
/* Close stdout and stderr */
|
/* Close stdout and stderr */
|
||||||
#ifndef DEDICATED_ONLY
|
#ifndef DEDICATED_ONLY
|
||||||
fclose(stdout);
|
fclose(stdout);
|
||||||
fclose(stderr);
|
fclose(stderr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printf("------------------------------------\n");
|
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ Sys_Realpath(const char *in, char *out, size_t size)
|
||||||
WCHAR win[MAX_OSPATH] = {0};
|
WCHAR win[MAX_OSPATH] = {0};
|
||||||
WCHAR wconverted[MAX_OSPATH] = {0};
|
WCHAR wconverted[MAX_OSPATH] = {0};
|
||||||
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, in, -1, win, sizeof(win));
|
MultiByteToWideChar(CP_UTF8, 0, in, -1, win, sizeof(win)/sizeof(win[0]));
|
||||||
_wfullpath(wconverted, win, size);
|
_wfullpath(wconverted, win, size);
|
||||||
|
|
||||||
if (wconverted == NULL)
|
if (wconverted == NULL)
|
||||||
|
@ -684,7 +684,7 @@ Sys_GetWorkDir(char *buffer, size_t len)
|
||||||
{
|
{
|
||||||
WCHAR wbuffer[MAX_OSPATH];
|
WCHAR wbuffer[MAX_OSPATH];
|
||||||
|
|
||||||
if (GetCurrentDirectoryW(sizeof(wbuffer), wbuffer) != 0)
|
if (GetCurrentDirectoryW(sizeof(wbuffer)/sizeof(wbuffer[0]), wbuffer) != 0)
|
||||||
{
|
{
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, len, NULL, NULL);
|
WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, len, NULL, NULL);
|
||||||
return;
|
return;
|
||||||
|
@ -698,7 +698,7 @@ Sys_SetWorkDir(char *path)
|
||||||
{
|
{
|
||||||
WCHAR wpath[MAX_OSPATH];
|
WCHAR wpath[MAX_OSPATH];
|
||||||
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, sizeof(wpath));
|
MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, sizeof(wpath)/sizeof(wpath[0]));
|
||||||
|
|
||||||
if (SetCurrentDirectoryW(wpath) != 0)
|
if (SetCurrentDirectoryW(wpath) != 0)
|
||||||
{
|
{
|
||||||
|
@ -738,8 +738,8 @@ Sys_RedirectStdout(void)
|
||||||
snprintf(path_stdout, sizeof(path_stdout), "%s/%s", dir, "stdout.txt");
|
snprintf(path_stdout, sizeof(path_stdout), "%s/%s", dir, "stdout.txt");
|
||||||
snprintf(path_stderr, sizeof(path_stderr), "%s/%s", dir, "stderr.txt");
|
snprintf(path_stderr, sizeof(path_stderr), "%s/%s", dir, "stderr.txt");
|
||||||
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, path_stdout, -1, wpath_stdout, sizeof(wpath_stdout));
|
MultiByteToWideChar(CP_UTF8, 0, path_stdout, -1, wpath_stdout, sizeof(wpath_stdout)/sizeof(wpath_stdout[0]));
|
||||||
MultiByteToWideChar(CP_UTF8, 0, path_stderr, -1, wpath_stderr, sizeof(wpath_stderr));
|
MultiByteToWideChar(CP_UTF8, 0, path_stderr, -1, wpath_stderr, sizeof(wpath_stderr)/sizeof( wpath_stderr[0] ) );
|
||||||
|
|
||||||
_wfreopen(wpath_stdout, L"w", stdout);
|
_wfreopen(wpath_stdout, L"w", stdout);
|
||||||
_wfreopen(wpath_stderr, L"w", stderr);
|
_wfreopen(wpath_stderr, L"w", stderr);
|
||||||
|
|
|
@ -427,9 +427,10 @@ R_DrawParticles2(int num_particles, const particle_t particles[],
|
||||||
float scale;
|
float scale;
|
||||||
YQ2_ALIGNAS_TYPE(unsigned) byte color[4];
|
YQ2_ALIGNAS_TYPE(unsigned) byte color[4];
|
||||||
|
|
||||||
GLfloat vtx[3*num_particles*3];
|
YQ2_VLA(GLfloat, vtx, 3 * num_particles * 3);
|
||||||
GLfloat tex[2*num_particles*3];
|
YQ2_VLA(GLfloat, tex, 2 * num_particles * 3);
|
||||||
GLfloat clr[4*num_particles*3];
|
YQ2_VLA(GLfloat, clr, 4 * num_particles * 3);
|
||||||
|
|
||||||
unsigned int index_vtx = 0;
|
unsigned int index_vtx = 0;
|
||||||
unsigned int index_tex = 0;
|
unsigned int index_tex = 0;
|
||||||
unsigned int index_clr = 0;
|
unsigned int index_clr = 0;
|
||||||
|
@ -511,6 +512,10 @@ R_DrawParticles2(int num_particles, const particle_t particles[],
|
||||||
glColor4f(1, 1, 1, 1);
|
glColor4f(1, 1, 1, 1);
|
||||||
glDepthMask(1); /* back to normal Z buffering */
|
glDepthMask(1); /* back to normal Z buffering */
|
||||||
R_TexEnv(GL_REPLACE);
|
R_TexEnv(GL_REPLACE);
|
||||||
|
|
||||||
|
YQ2_VLAFREE(vtx);
|
||||||
|
YQ2_VLAFREE(tex);
|
||||||
|
YQ2_VLAFREE(clr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -524,9 +529,10 @@ R_DrawParticles(void)
|
||||||
int i;
|
int i;
|
||||||
YQ2_ALIGNAS_TYPE(unsigned) byte color[4];
|
YQ2_ALIGNAS_TYPE(unsigned) byte color[4];
|
||||||
const particle_t *p;
|
const particle_t *p;
|
||||||
|
|
||||||
|
YQ2_VLA(GLfloat, vtx, 3 * r_newrefdef.num_particles);
|
||||||
|
YQ2_VLA(GLfloat, clr, 4*r_newrefdef.num_particles);
|
||||||
|
|
||||||
GLfloat vtx[3*r_newrefdef.num_particles];
|
|
||||||
GLfloat clr[4*r_newrefdef.num_particles];
|
|
||||||
unsigned int index_vtx = 0;
|
unsigned int index_vtx = 0;
|
||||||
unsigned int index_clr = 0;
|
unsigned int index_clr = 0;
|
||||||
|
|
||||||
|
@ -564,6 +570,9 @@ R_DrawParticles(void)
|
||||||
glColor4f( 1, 1, 1, 1 );
|
glColor4f( 1, 1, 1, 1 );
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
YQ2_VLAFREE(vtx);
|
||||||
|
YQ2_VLAFREE(clr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1380,7 +1389,7 @@ R_SetMode(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean
|
qboolean
|
||||||
RI_Init()
|
RI_Init(void)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
extern float r_turbsin[256];
|
extern float r_turbsin[256];
|
||||||
|
|
|
@ -154,6 +154,27 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
|
||||||
|
|
||||||
R_LerpVerts(currententity, paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv);
|
R_LerpVerts(currententity, paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv);
|
||||||
|
|
||||||
|
#ifdef _MSC_VER // workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
|
||||||
|
int maxCount = 0;
|
||||||
|
const int* tmpOrder = order;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int c = *tmpOrder++;
|
||||||
|
if (!c)
|
||||||
|
break;
|
||||||
|
if ( c < 0 )
|
||||||
|
c = -c;
|
||||||
|
if ( c > maxCount )
|
||||||
|
maxCount = c;
|
||||||
|
|
||||||
|
tmpOrder += 3 * c;
|
||||||
|
}
|
||||||
|
|
||||||
|
YQ2_VLA( GLfloat, vtx, 3 * maxCount );
|
||||||
|
YQ2_VLA( GLfloat, tex, 2 * maxCount );
|
||||||
|
YQ2_VLA( GLfloat, clr, 4 * maxCount );
|
||||||
|
#endif
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* get the vertex count and primitive type */
|
/* get the vertex count and primitive type */
|
||||||
|
@ -176,9 +197,12 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
|
||||||
}
|
}
|
||||||
|
|
||||||
total = count;
|
total = count;
|
||||||
GLfloat vtx[3*total];
|
|
||||||
GLfloat tex[2*total];
|
#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop
|
||||||
GLfloat clr[4 * total];
|
YQ2_VLA(GLfloat, vtx, 3*total);
|
||||||
|
YQ2_VLA(GLfloat, tex, 2*total);
|
||||||
|
YQ2_VLA(GLfloat, clr, 4*total);
|
||||||
|
#endif
|
||||||
unsigned int index_vtx = 0;
|
unsigned int index_vtx = 0;
|
||||||
unsigned int index_tex = 0;
|
unsigned int index_tex = 0;
|
||||||
unsigned int index_clr = 0;
|
unsigned int index_clr = 0;
|
||||||
|
@ -242,6 +266,10 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
YQ2_VLAFREE( vtx );
|
||||||
|
YQ2_VLAFREE( tex );
|
||||||
|
YQ2_VLAFREE( clr )
|
||||||
|
|
||||||
if (currententity->flags &
|
if (currententity->flags &
|
||||||
(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE |
|
(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE |
|
||||||
RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM))
|
RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM))
|
||||||
|
@ -272,6 +300,25 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER // workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
|
||||||
|
int maxCount = 0;
|
||||||
|
const int* tmpOrder = order;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int c = *tmpOrder++;
|
||||||
|
if (!c)
|
||||||
|
break;
|
||||||
|
if (c < 0)
|
||||||
|
c = -c;
|
||||||
|
if (c > maxCount)
|
||||||
|
maxCount = c;
|
||||||
|
|
||||||
|
tmpOrder += 3 * c;
|
||||||
|
}
|
||||||
|
|
||||||
|
YQ2_VLA(GLfloat, vtx, 3 * maxCount);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* get the vertex count and primitive type */
|
/* get the vertex count and primitive type */
|
||||||
|
@ -294,7 +341,10 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
|
||||||
}
|
}
|
||||||
|
|
||||||
total = count;
|
total = count;
|
||||||
GLfloat vtx[3*total];
|
|
||||||
|
#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop
|
||||||
|
YQ2_VLA(GLfloat, vtx, 3*total);
|
||||||
|
#endif
|
||||||
unsigned int index_vtx = 0;
|
unsigned int index_vtx = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -321,6 +371,7 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
|
||||||
|
|
||||||
glDisableClientState( GL_VERTEX_ARRAY );
|
glDisableClientState( GL_VERTEX_ARRAY );
|
||||||
}
|
}
|
||||||
|
YQ2_VLAFREE(vtx);
|
||||||
|
|
||||||
/* stencilbuffer shadows */
|
/* stencilbuffer shadows */
|
||||||
if (gl_state.stencil && gl1_stencilshadow->value)
|
if (gl_state.stencil && gl1_stencilshadow->value)
|
||||||
|
|
|
@ -137,7 +137,7 @@ R_ScreenShot(void)
|
||||||
// so swap bottom rows with top rows
|
// so swap bottom rows with top rows
|
||||||
{
|
{
|
||||||
size_t bytesPerRow = 3*w;
|
size_t bytesPerRow = 3*w;
|
||||||
byte rowBuffer[bytesPerRow];
|
YQ2_VLA(byte, rowBuffer, bytesPerRow);
|
||||||
byte *curRowL = buffer; // first byte of first row
|
byte *curRowL = buffer; // first byte of first row
|
||||||
byte *curRowH = buffer + bytesPerRow*(h-1); // first byte of last row
|
byte *curRowH = buffer + bytesPerRow*(h-1); // first byte of last row
|
||||||
while(curRowL < curRowH)
|
while(curRowL < curRowH)
|
||||||
|
@ -149,6 +149,7 @@ R_ScreenShot(void)
|
||||||
curRowL += bytesPerRow;
|
curRowL += bytesPerRow;
|
||||||
curRowH -= bytesPerRow;
|
curRowH -= bytesPerRow;
|
||||||
}
|
}
|
||||||
|
YQ2_VLAFREE(rowBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ri.Vid_WriteScreenshot(w, h, 3, buffer);
|
ri.Vid_WriteScreenshot(w, h, 3, buffer);
|
||||||
|
|
|
@ -101,7 +101,7 @@ R_DrawGLFlowingPoly(msurface_t *fa)
|
||||||
scroll = -64.0;
|
scroll = -64.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLfloat tex[2*p->numverts];
|
YQ2_VLA(GLfloat, tex, 2*p->numverts);
|
||||||
unsigned int index_tex = 0;
|
unsigned int index_tex = 0;
|
||||||
|
|
||||||
v = p->verts [ 0 ];
|
v = p->verts [ 0 ];
|
||||||
|
@ -122,6 +122,8 @@ R_DrawGLFlowingPoly(msurface_t *fa)
|
||||||
|
|
||||||
glDisableClientState( GL_VERTEX_ARRAY );
|
glDisableClientState( GL_VERTEX_ARRAY );
|
||||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||||
|
|
||||||
|
YQ2_VLAFREE(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -203,14 +205,28 @@ R_DrawGLPolyChain(glpoly_t *p, float soffset, float toffset)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
int maxNumVerts = 0;
|
||||||
|
for (glpoly_t* tmp = p; tmp; tmp = tmp->chain)
|
||||||
|
{
|
||||||
|
if ( tmp->numverts > maxNumVerts )
|
||||||
|
maxNumVerts = tmp->numverts;
|
||||||
|
}
|
||||||
|
|
||||||
|
YQ2_VLA( GLfloat, tex, 2 * maxNumVerts );
|
||||||
|
#endif
|
||||||
|
|
||||||
for ( ; p != 0; p = p->chain)
|
for ( ; p != 0; p = p->chain)
|
||||||
{
|
{
|
||||||
float *v;
|
float *v;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
v = p->verts[0];
|
v = p->verts[0];
|
||||||
|
#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop
|
||||||
|
YQ2_VLA(GLfloat, tex, 2*p->numverts);
|
||||||
|
#endif
|
||||||
|
|
||||||
GLfloat tex[2*p->numverts];
|
|
||||||
unsigned int index_tex = 0;
|
unsigned int index_tex = 0;
|
||||||
|
|
||||||
for ( j = 0; j < p->numverts; j++, v += VERTEXSIZE )
|
for ( j = 0; j < p->numverts; j++, v += VERTEXSIZE )
|
||||||
|
@ -231,6 +247,8 @@ R_DrawGLPolyChain(glpoly_t *p, float soffset, float toffset)
|
||||||
glDisableClientState( GL_VERTEX_ARRAY );
|
glDisableClientState( GL_VERTEX_ARRAY );
|
||||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
YQ2_VLAFREE( tex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -297,11 +297,24 @@ R_EmitWaterPolys(msurface_t *fa)
|
||||||
scroll = 0;
|
scroll = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
int maxNumVerts = 0;
|
||||||
|
for ( glpoly_t* tmp = fa->polys; tmp; tmp = tmp->next )
|
||||||
|
{
|
||||||
|
if (tmp->numverts > maxNumVerts)
|
||||||
|
maxNumVerts = tmp->numverts;
|
||||||
|
}
|
||||||
|
|
||||||
|
YQ2_VLA( GLfloat, tex, 2 * maxNumVerts );
|
||||||
|
#endif
|
||||||
|
|
||||||
for (bp = fa->polys; bp; bp = bp->next)
|
for (bp = fa->polys; bp; bp = bp->next)
|
||||||
{
|
{
|
||||||
p = bp;
|
p = bp;
|
||||||
|
#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop
|
||||||
GLfloat tex[2*p->numverts];
|
YQ2_VLA(GLfloat, tex, 2*p->numverts);
|
||||||
|
#endif
|
||||||
unsigned int index_tex = 0;
|
unsigned int index_tex = 0;
|
||||||
|
|
||||||
for ( i = 0, v = p->verts [ 0 ]; i < p->numverts; i++, v += VERTEXSIZE )
|
for ( i = 0, v = p->verts [ 0 ]; i < p->numverts; i++, v += VERTEXSIZE )
|
||||||
|
@ -329,6 +342,8 @@ R_EmitWaterPolys(msurface_t *fa)
|
||||||
glDisableClientState( GL_VERTEX_ARRAY );
|
glDisableClientState( GL_VERTEX_ARRAY );
|
||||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
YQ2_VLAFREE( tex );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -925,7 +925,7 @@ GL3_DrawParticles(void)
|
||||||
} part_vtx;
|
} part_vtx;
|
||||||
assert(sizeof(part_vtx)==9*sizeof(float)); // remember to update GL3_SurfInit() if this changes!
|
assert(sizeof(part_vtx)==9*sizeof(float)); // remember to update GL3_SurfInit() if this changes!
|
||||||
|
|
||||||
part_vtx buf[numParticles];
|
YQ2_VLA(part_vtx, buf, numParticles);
|
||||||
|
|
||||||
// TODO: viewOrg could be in UBO
|
// TODO: viewOrg could be in UBO
|
||||||
vec3_t viewOrg;
|
vec3_t viewOrg;
|
||||||
|
@ -962,6 +962,8 @@ GL3_DrawParticles(void)
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
|
||||||
|
YQ2_VLAFREE(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ GL3_ScreenShot(void)
|
||||||
// so swap bottom rows with top rows
|
// so swap bottom rows with top rows
|
||||||
{
|
{
|
||||||
size_t bytesPerRow = 3*w;
|
size_t bytesPerRow = 3*w;
|
||||||
byte rowBuffer[bytesPerRow];
|
YQ2_VLA(byte, rowBuffer, bytesPerRow);
|
||||||
byte *curRowL = buffer; // first byte of first row
|
byte *curRowL = buffer; // first byte of first row
|
||||||
byte *curRowH = buffer + bytesPerRow*(h-1); // first byte of last row
|
byte *curRowH = buffer + bytesPerRow*(h-1); // first byte of last row
|
||||||
while(curRowL < curRowH)
|
while(curRowL < curRowH)
|
||||||
|
@ -143,6 +143,7 @@ GL3_ScreenShot(void)
|
||||||
curRowL += bytesPerRow;
|
curRowL += bytesPerRow;
|
||||||
curRowH -= bytesPerRow;
|
curRowH -= bytesPerRow;
|
||||||
}
|
}
|
||||||
|
YQ2_VLAFREE(rowBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ri.Vid_WriteScreenshot(w, h, 3, buffer);
|
ri.Vid_WriteScreenshot(w, h, 3, buffer);
|
||||||
|
|
|
@ -29,6 +29,23 @@
|
||||||
|
|
||||||
#include "../vid/header/ref.h"
|
#include "../vid/header/ref.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#define YQ2_VLA(TYPE, VARNAME, NUMELEMS) \
|
||||||
|
TYPE * VARNAME = (TYPE *) _malloca(sizeof(TYPE) * NUMELEMS)
|
||||||
|
#define YQ2_VLAFREE(VARNAME) \
|
||||||
|
_freea(VARNAME); VARNAME=NULL;
|
||||||
|
|
||||||
|
#else // other compilers hopefully support C99 VLAs (gcc/mingw and clang do)
|
||||||
|
|
||||||
|
#define YQ2_VLA(TYPE, VARNAME, NUMELEMS) \
|
||||||
|
TYPE VARNAME[NUMELEMS]
|
||||||
|
#define YQ2_VLAFREE(VARNAME)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* skins will be outline flood filled and mip mapped
|
* skins will be outline flood filled and mip mapped
|
||||||
* pics and sprites with alpha will be outline flood filled
|
* pics and sprites with alpha will be outline flood filled
|
||||||
|
@ -58,7 +75,7 @@ typedef enum
|
||||||
|
|
||||||
#define MAX_LBM_HEIGHT 480
|
#define MAX_LBM_HEIGHT 480
|
||||||
|
|
||||||
extern void R_Printf(int level, const char* msg, ...) __attribute__ ((format (printf, 2, 3)));
|
extern void R_Printf(int level, const char* msg, ...) PRINTF_ATTR(2, 3);
|
||||||
|
|
||||||
extern void LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height);
|
extern void LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height);
|
||||||
extern void GetPCXInfo(char *filename, int *width, int *height);
|
extern void GetPCXInfo(char *filename, int *width, int *height);
|
||||||
|
|
|
@ -163,7 +163,7 @@ static qboolean
|
||||||
S_IsSilencedMuzzleFlash(const wavinfo_t* info, const void* raw_data, const char* name)
|
S_IsSilencedMuzzleFlash(const wavinfo_t* info, const void* raw_data, const char* name)
|
||||||
{
|
{
|
||||||
/* Skip the prefix. */
|
/* Skip the prefix. */
|
||||||
static const size_t base_sound_string_length = strlen("sound/");
|
static const size_t base_sound_string_length = 6; //strlen("sound/");
|
||||||
const char* base_name = name + base_sound_string_length;
|
const char* base_name = name + base_sound_string_length;
|
||||||
|
|
||||||
/* Match to well-known muzzle flash sound names. */
|
/* Match to well-known muzzle flash sound names. */
|
||||||
|
|
|
@ -135,7 +135,7 @@ CreateSDLWindow(int flags, int w, int h)
|
||||||
Com_Printf("Likely SDL bug #4700, trying to work around it\n");
|
Com_Printf("Likely SDL bug #4700, trying to work around it\n");
|
||||||
|
|
||||||
/* Mkay, try to hack around that. */
|
/* Mkay, try to hack around that. */
|
||||||
SDL_DisplayMode wanted_mode = {};
|
SDL_DisplayMode wanted_mode = {0};
|
||||||
|
|
||||||
wanted_mode.w = w;
|
wanted_mode.w = w;
|
||||||
wanted_mode.h = h;
|
wanted_mode.h = h;
|
||||||
|
|
|
@ -207,7 +207,7 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
YQ2_ATTR_NORETURN_FUNCPTR void (IMPORT *Sys_Error) (int err_level, char *str, ...) __attribute__ ((format (printf, 2, 3)));
|
YQ2_ATTR_NORETURN_FUNCPTR void (IMPORT *Sys_Error) (int err_level, char *str, ...) PRINTF_ATTR(2, 3);
|
||||||
|
|
||||||
void (IMPORT *Cmd_AddCommand) (char *name, void(*cmd)(void));
|
void (IMPORT *Cmd_AddCommand) (char *name, void(*cmd)(void));
|
||||||
void (IMPORT *Cmd_RemoveCommand) (char *name);
|
void (IMPORT *Cmd_RemoveCommand) (char *name);
|
||||||
|
|
|
@ -25,7 +25,9 @@
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "header/common.h"
|
#include "header/common.h"
|
||||||
#include "header/glob.h"
|
#include "header/glob.h"
|
||||||
|
@ -380,7 +382,7 @@ FS_FOpenFile(const char *rawname, fileHandle_t *f, qboolean gamedir_only)
|
||||||
// Remove self references and empty dirs from the requested path.
|
// Remove self references and empty dirs from the requested path.
|
||||||
// ZIPs and PAKs don't support them, but they may be hardcoded in
|
// ZIPs and PAKs don't support them, but they may be hardcoded in
|
||||||
// some custom maps or models.
|
// some custom maps or models.
|
||||||
char name[MAX_QPATH] = {};
|
char name[MAX_QPATH] = {0};
|
||||||
size_t namelen = strlen(rawname);
|
size_t namelen = strlen(rawname);
|
||||||
for (int input = 0, output = 0; input < namelen; input++)
|
for (int input = 0, output = 0; input < namelen; input++)
|
||||||
{
|
{
|
||||||
|
@ -1614,6 +1616,25 @@ FS_GetNextRawPath(const char* lastRawPath)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER // looks like MSVC/the Windows CRT doesn't have basename()
|
||||||
|
// returns the last part of the given pathname, after last (back)slash
|
||||||
|
// if the last character is a (back)slash, it's removed (set to '\0')
|
||||||
|
static char* basename( char* n )
|
||||||
|
{
|
||||||
|
size_t l = strlen(n);
|
||||||
|
while (n[l - 1] == '\\' || n[l - 1] == '/') // cut off trailing (back)slashes, if any
|
||||||
|
{
|
||||||
|
--l;
|
||||||
|
n[l] = '\0';
|
||||||
|
}
|
||||||
|
char* r1 = strrchr(n, '\\');
|
||||||
|
char* r2 = strrchr(n, '/');
|
||||||
|
if (r1 != NULL)
|
||||||
|
return (r2 == NULL || r1 > r2) ? (r1 + 1) : (r2 + 1);
|
||||||
|
return (r2 != NULL) ? (r2 + 1) : n;
|
||||||
|
}
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
void
|
void
|
||||||
FS_AddDirToSearchPath(char *dir, qboolean create) {
|
FS_AddDirToSearchPath(char *dir, qboolean create) {
|
||||||
char *file;
|
char *file;
|
||||||
|
@ -1629,13 +1650,10 @@ FS_AddDirToSearchPath(char *dir, qboolean create) {
|
||||||
|
|
||||||
// The directory must not end with an /. It would
|
// The directory must not end with an /. It would
|
||||||
// f*ck up the logic in other parts of the game...
|
// f*ck up the logic in other parts of the game...
|
||||||
if (dir[len - 1] == '/')
|
if (dir[len - 1] == '/' || dir[len - 1] == '\\')
|
||||||
{
|
{
|
||||||
dir[len - 1] = '\0';
|
dir[len - 1] = '\0';
|
||||||
}
|
}
|
||||||
else if (dir[len - 1] == '\\') {
|
|
||||||
dir[len - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the current directory as game directory. This
|
// Set the current directory as game directory. This
|
||||||
// is somewhat fragile since the game directory MUST
|
// is somewhat fragile since the game directory MUST
|
||||||
|
@ -1971,7 +1989,7 @@ static void FS_AddDirToRawPath (const char *rawdir, qboolean create, qboolean re
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the dir doesn't end with a slash.
|
// Make sure that the dir doesn't end with a slash.
|
||||||
for (size_t s = strlen(dir) - 1; s >= 0; s--)
|
for (size_t s = strlen(dir) - 1; s > 0; s--)
|
||||||
{
|
{
|
||||||
if (dir[s] == '/')
|
if (dir[s] == '/')
|
||||||
{
|
{
|
||||||
|
|
|
@ -711,11 +711,11 @@ void FS_CreatePath(char *path);
|
||||||
|
|
||||||
void Com_BeginRedirect(int target, char *buffer, int buffersize, void (*flush)(int, char *));
|
void Com_BeginRedirect(int target, char *buffer, int buffersize, void (*flush)(int, char *));
|
||||||
void Com_EndRedirect(void);
|
void Com_EndRedirect(void);
|
||||||
void Com_Printf(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
void Com_Printf(char *fmt, ...) PRINTF_ATTR(1, 2);
|
||||||
void Com_DPrintf(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
void Com_DPrintf(char *fmt, ...) PRINTF_ATTR(1, 2);
|
||||||
void Com_VPrintf(int print_level, const char *fmt, va_list argptr); /* print_level is PRINT_ALL or PRINT_DEVELOPER */
|
void Com_VPrintf(int print_level, const char *fmt, va_list argptr); /* print_level is PRINT_ALL or PRINT_DEVELOPER */
|
||||||
void Com_MDPrintf(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
void Com_MDPrintf(char *fmt, ...) PRINTF_ATTR(1, 2);
|
||||||
YQ2_ATTR_NORETURN void Com_Error(int code, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
YQ2_ATTR_NORETURN void Com_Error(int code, char *fmt, ...) PRINTF_ATTR(2, 3);
|
||||||
YQ2_ATTR_NORETURN void Com_Quit(void);
|
YQ2_ATTR_NORETURN void Com_Quit(void);
|
||||||
|
|
||||||
/* Ugly work around for unsupported
|
/* Ugly work around for unsupported
|
||||||
|
|
|
@ -54,7 +54,7 @@ typedef unsigned char byte;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// stuff to align variables/arrays and for noreturn
|
// stuff to align variables/arrays and for noreturn
|
||||||
#if __STDC_VERSION__ >= 201112L // C11 or newer
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L // C11 or newer
|
||||||
#define YQ2_ALIGNAS_SIZE(SIZE) _Alignas(SIZE)
|
#define YQ2_ALIGNAS_SIZE(SIZE) _Alignas(SIZE)
|
||||||
#define YQ2_ALIGNAS_TYPE(TYPE) _Alignas(TYPE)
|
#define YQ2_ALIGNAS_TYPE(TYPE) _Alignas(TYPE)
|
||||||
// must be used as prefix (YQ2_ATTR_NORETURN void bla();)!
|
// must be used as prefix (YQ2_ATTR_NORETURN void bla();)!
|
||||||
|
@ -65,12 +65,24 @@ typedef unsigned char byte;
|
||||||
// must be used as prefix (YQ2_ATTR_NORETURN void bla();)!
|
// must be used as prefix (YQ2_ATTR_NORETURN void bla();)!
|
||||||
#define YQ2_ATTR_NORETURN __attribute__ ((noreturn))
|
#define YQ2_ATTR_NORETURN __attribute__ ((noreturn))
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#define YQ2_ALIGNAS_SIZE(SIZE) __declspec( align(SIZE) )
|
// Note: We prefer VS2019 16.8 or newer in C11 mode (/std:c11),
|
||||||
#define YQ2_ALIGNAS_TYPE(TYPE) __declspec( align( __alignof(TYPE) ) )
|
// then the __STDC_VERSION__ >= 201112L case above is used
|
||||||
|
|
||||||
|
#define YQ2_ALIGNAS_SIZE(SIZE) __declspec(align(SIZE))
|
||||||
|
// FIXME: for some reason, the following line doesn't work
|
||||||
|
//#define YQ2_ALIGNAS_TYPE( TYPE ) __declspec(align(__alignof(TYPE)))
|
||||||
|
|
||||||
|
#ifdef _WIN64 // (hopefully) good enough workaround
|
||||||
|
#define YQ2_ALIGNAS_TYPE(TYPE) __declspec(align(8))
|
||||||
|
#else // 32bit
|
||||||
|
#define YQ2_ALIGNAS_TYPE(TYPE) __declspec(align(4))
|
||||||
|
#endif // _WIN64
|
||||||
|
|
||||||
// must be used as prefix (YQ2_ATTR_NORETURN void bla();)!
|
// must be used as prefix (YQ2_ATTR_NORETURN void bla();)!
|
||||||
#define YQ2_ATTR_NORETURN __declspec(noreturn)
|
#define YQ2_ATTR_NORETURN __declspec(noreturn)
|
||||||
#else
|
#else
|
||||||
#warning "Please add a case for your compiler here to align correctly"
|
#warning "Please add a case for your compiler here to align correctly"
|
||||||
|
#define YQ2_ALIGNAS_SIZE(SIZE)
|
||||||
#define YQ2_ALIGNAS_TYPE(TYPE)
|
#define YQ2_ALIGNAS_TYPE(TYPE)
|
||||||
#define YQ2_ATTR_NORETURN
|
#define YQ2_ATTR_NORETURN
|
||||||
#endif
|
#endif
|
||||||
|
@ -133,6 +145,12 @@ typedef unsigned char byte;
|
||||||
#define Q2_DLL_EXPORTED __attribute__((__visibility__("default")))
|
#define Q2_DLL_EXPORTED __attribute__((__visibility__("default")))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define PRINTF_ATTR(FMT, VARGS)
|
||||||
|
#else // at least GCC/mingw and clang support this
|
||||||
|
#define PRINTF_ATTR(FMT, VARGS) __attribute__((format(printf, FMT , VARGS )));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* per-level limits */
|
/* per-level limits */
|
||||||
#define MAX_CLIENTS 256 /* absolute limit */
|
#define MAX_CLIENTS 256 /* absolute limit */
|
||||||
#define MAX_EDICTS 1024 /* must change protocol to increase more */
|
#define MAX_EDICTS 1024 /* must change protocol to increase more */
|
||||||
|
@ -310,7 +328,7 @@ float BigFloat(float l);
|
||||||
float LittleFloat(float l);
|
float LittleFloat(float l);
|
||||||
|
|
||||||
void Swap_Init(void);
|
void Swap_Init(void);
|
||||||
char *va(char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
char *va(char *format, ...) PRINTF_ATTR(1, 2);
|
||||||
|
|
||||||
/* ============================================= */
|
/* ============================================= */
|
||||||
|
|
||||||
|
|
|
@ -1034,7 +1034,11 @@ Com_PageInMemory(byte *buffer, int size)
|
||||||
int
|
int
|
||||||
Q_stricmp(const char *s1, const char *s2)
|
Q_stricmp(const char *s1, const char *s2)
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
return stricmp(s1, s2);
|
||||||
|
#else
|
||||||
return strcasecmp(s1, s2);
|
return strcasecmp(s1, s2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in a new issue