mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-21 11:21:52 +00:00
Merge remote-tracking branch 'yquake2/master'
This commit is contained in:
commit
4bd19bf982
21 changed files with 4572 additions and 52 deletions
830
CMakeLists.txt
Normal file
830
CMakeLists.txt
Normal file
|
@ -0,0 +1,830 @@
|
||||||
|
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
|
||||||
|
|
||||||
|
# Print a message that using the Makefiles is recommended.
|
||||||
|
message(NOTICE: " The CMakeLists.txt is unmaintained. Use the Makefile if possible.")
|
||||||
|
|
||||||
|
# Enforce "Debug" as standard build type.
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# CMake project configuration.
|
||||||
|
project(yquake2 C)
|
||||||
|
|
||||||
|
# Cmake module search path.
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/stuff/cmake/modules ${CMAKE_MODULE_PATH})
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED OFF)
|
||||||
|
|
||||||
|
if(YQUAKE2LIBS)
|
||||||
|
if(CMAKE_CROSSCOMPILING)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH ${YQUAKE2LIBS})
|
||||||
|
else()
|
||||||
|
set(ENV{CMAKE_PREFIX_PATH} ${YQUAKE2LIBS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ENV{OPENALDIR} ${YQUAKE2LIBS})
|
||||||
|
set(ENV{SDL2DIR} ${YQUAKE2LIBS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add extended path for FreeBSD and Homebrew on OS X.
|
||||||
|
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 mismatch
|
||||||
|
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:
|
||||||
|
# -Wall -> More warnings
|
||||||
|
# -fno-strict-aliasing -> Quake 2 is far away from strict aliasing
|
||||||
|
# -fwrapv -> Make signed integer overflows defined
|
||||||
|
# -fvisibility=hidden -> Force defaultsymbol visibility to hidden
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fno-strict-aliasing -fwrapv -fvisibility=hidden")
|
||||||
|
|
||||||
|
# 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")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
||||||
|
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU")
|
||||||
|
if (CMAKE_C_COMPILER_VERSION GREATER 7.99)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format-truncation -Wno-format-overflow")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Compilation time options.
|
||||||
|
option(CURL_SUPPORT "cURL support" ON)
|
||||||
|
option(OPENAL_SUPPORT "OpenAL support" ON)
|
||||||
|
option(SYSTEMWIDE_SUPPORT "Enable systemwide installation of game assets" OFF)
|
||||||
|
option(SDL3_SUPPORT "Build against SDL 3 instead of SDL2" OFF)
|
||||||
|
|
||||||
|
set(SYSTEMDIR "" CACHE STRING "Override the system default directory")
|
||||||
|
|
||||||
|
# These variables will act as our list of include folders and linker flags.
|
||||||
|
set(yquake2IncludeDirectories)
|
||||||
|
set(yquake2LinkerDirectories)
|
||||||
|
set(yquake2LinkerFlags)
|
||||||
|
set(yquake2ClientLinkerFlags)
|
||||||
|
set(yquake2ServerLinkerFlags)
|
||||||
|
set(yquake2OpenGLLinkerFlags)
|
||||||
|
set(yquake2VulkanLinkerFlags)
|
||||||
|
set(yquake2SDLLinkerFlags)
|
||||||
|
set(yquake2ZLibLinkerFlags)
|
||||||
|
|
||||||
|
# Set directory locations (allowing us to move directories easily)
|
||||||
|
set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/src)
|
||||||
|
set(BACKENDS_SRC_DIR ${SOURCE_DIR}/backends)
|
||||||
|
set(COMMON_SRC_DIR ${SOURCE_DIR}/common)
|
||||||
|
set(GAME_SRC_DIR ${SOURCE_DIR}/game)
|
||||||
|
set(SERVER_SRC_DIR ${SOURCE_DIR}/server)
|
||||||
|
set(CLIENT_SRC_DIR ${SOURCE_DIR}/client)
|
||||||
|
set(REF_SRC_DIR ${SOURCE_DIR}/client/refresh)
|
||||||
|
|
||||||
|
# Operating system.
|
||||||
|
set(YQ2OSTYPE "${CMAKE_SYSTEM_NAME}" CACHE STRING "Override operation system type")
|
||||||
|
add_definitions(-DYQ2OSTYPE="${YQ2OSTYPE}")
|
||||||
|
|
||||||
|
# Architecture string
|
||||||
|
# work around CMake's useless/broken CMAKE_SYSTEM_PROCESSOR (taken from dhewm3)
|
||||||
|
|
||||||
|
set(cpu ${CMAKE_SYSTEM_PROCESSOR})
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
# because all this wasn't ugly enough, it turned out that, unlike standalone CMake, Visual Studio's
|
||||||
|
# integrated CMake doesn't set CMAKE_GENERATOR_PLATFORM, so I gave up on guessing the CPU arch here
|
||||||
|
# and moved the CPU detection to MSVC-specific code in neo/sys/platform.h
|
||||||
|
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 "[aA][mM][dD]64" OR cpu MATCHES "[xX].*64")
|
||||||
|
set(cpu "x86_64")
|
||||||
|
elseif(cpu MATCHES "i.86" OR cpu MATCHES "[xX]86")
|
||||||
|
set(cpu "i386")
|
||||||
|
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()
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
# for MSVC YQ2ARCH is set in code (in src/common/header/common.h)
|
||||||
|
message(STATUS "Setting YQ2OSTYPE to \"${YQ2OSTYPE}\" - NOT setting YQ2ARCH, because we're targeting MSVC (VisualC++)")
|
||||||
|
else()
|
||||||
|
set(ARCH "${cpu}")
|
||||||
|
add_definitions(-DYQ2ARCH="${ARCH}")
|
||||||
|
message(STATUS "Setting YQ2OSTYPE to \"${YQ2OSTYPE}\" and YQ2ARCH to \"${ARCH}\".")
|
||||||
|
endif()
|
||||||
|
# make sure that ${cpu} isn't used below - if at all use ${ARCH}, but not when compiling with MSVC!
|
||||||
|
unset(cpu)
|
||||||
|
|
||||||
|
# END OF workarounds for CMake's poor choices regarding CPU architecture detection
|
||||||
|
|
||||||
|
|
||||||
|
# Systemwide installation of game assets.
|
||||||
|
if(${SYSTEMWIDE_SUPPORT})
|
||||||
|
add_definitions(-DSYSTEMWIDE)
|
||||||
|
if(NOT ${SYSTEMDIR} STREQUAL "")
|
||||||
|
add_definitions(-DSYSTEMDIR="${SYSTEMDIR}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# We need to pass some options to minizip / unzip.
|
||||||
|
add_definitions(-DNOUNCRYPT)
|
||||||
|
|
||||||
|
if(NOT (CMAKE_SYSTEM_NAME MATCHES "Linux") AND NOT (CMAKE_SYSTEM_NAME MATCHES "Windows"))
|
||||||
|
add_definitions(-DIOAPI_NO_64)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Required libraries to build the different components of the binaries. Find
|
||||||
|
# them and add the include/linker directories and flags (in case the package
|
||||||
|
# manager find it in a weird place).
|
||||||
|
if (SDL3_SUPPORT)
|
||||||
|
find_package(SDL3 REQUIRED)
|
||||||
|
add_definitions(-DUSE_SDL3)
|
||||||
|
else()
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
|
list(APPEND yquake2IncludeDirectories "${SDL2_INCLUDE_DIR}/..")
|
||||||
|
list(APPEND yquake2SDLLinkerFlags ${SDL2_LIBRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# We need an OpenGL implementation.
|
||||||
|
set(OpenGL_GL_PREFERENCE GLVND)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
list(APPEND yquake2IncludeDirectories ${OPENGL_INCLUDE_DIR})
|
||||||
|
list(APPEND yquake2OpenGLLinkerFlags ${OPENGL_LIBRARIES})
|
||||||
|
|
||||||
|
# backtrace lookup
|
||||||
|
# Some systems like Linux has it within the libc some like the BSD, Haiku ...
|
||||||
|
# into an external libexecinfo library
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
include(CheckLibraryExists)
|
||||||
|
check_function_exists(backtrace HAVE_EXECINFO_SYS)
|
||||||
|
IF (NOT HAVE_EXECINFO_SYS)
|
||||||
|
check_library_exists(execinfo backtrace "" HAVE_EXECINFO_LIB)
|
||||||
|
if (HAVE_EXECINFO_LIB)
|
||||||
|
list(APPEND yquake2ClientLinkerFlags execinfo)
|
||||||
|
list(APPEND yquake2ServerLinkerFlags execinfo)
|
||||||
|
add_definitions(-DHAVE_EXECINFO)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
add_definitions(-DHAVE_EXECINFO)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# cURL support.
|
||||||
|
if (${CURL_SUPPORT})
|
||||||
|
find_package(CURL REQUIRED)
|
||||||
|
add_definitions(-DUSE_CURL)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# OpenAL support.
|
||||||
|
if(${OPENAL_SUPPORT})
|
||||||
|
find_package(OpenAL)
|
||||||
|
|
||||||
|
if(${OPENAL_FOUND})
|
||||||
|
list(APPEND yquake2IncludeDirectories "${OPENAL_INCLUDE_DIR}")
|
||||||
|
list(APPEND yquake2ClientLinkerFlags ${OPENAL_LIBRARY})
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
|
add_definitions(-DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER="openal32.dll")
|
||||||
|
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
|
add_definitions(-DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER="libopenal.dylib")
|
||||||
|
elseif((${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") OR (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD"))
|
||||||
|
add_definitions(-DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER="libopenal.so")
|
||||||
|
else()
|
||||||
|
add_definitions(-DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER="libopenal.so.1")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# General linker flags.
|
||||||
|
if(NOT MSVC)
|
||||||
|
list(APPEND yquake2LinkerFlags m)
|
||||||
|
endif()
|
||||||
|
list(APPEND yquake2LinkerFlags ${CMAKE_DL_LIBS})
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
|
if(!MSVC)
|
||||||
|
list(APPEND yquake2LinkerFlags "-static-libgcc")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
||||||
|
list(APPEND yquake2LinkerFlags "-rdynamic")
|
||||||
|
else()
|
||||||
|
list(APPEND yquake2LinkerFlags "-lnetwork")
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
endif()
|
||||||
|
if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||||
|
list(APPEND yquake2LinkerFlags "-lsocket -lnsl")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT WIN32)
|
||||||
|
list(APPEND yquake2LinkerFlags "-Wl,--no-undefined")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# With all of those libraries and user defined paths
|
||||||
|
# added, lets give them to the compiler and linker.
|
||||||
|
include_directories(${yquake2IncludeDirectories})
|
||||||
|
link_directories(${yquake2LinkerDirectories})
|
||||||
|
|
||||||
|
# these settings only work for GCC and clang
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
|
# If we're building with gcc for i386 let's define -ffloat-store.
|
||||||
|
# This helps the old and crappy x87 FPU to produce correct values.
|
||||||
|
# Would be nice if Clang had something comparable.
|
||||||
|
if ("${ARCH}" STREQUAL "i386" AND ${CMAKE_C_COMPILER_ID} STREQUAL "GNU")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffloat-store")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Force SSE math on x86_64. All sane compilers should do this
|
||||||
|
# anyway, just to protect us from broken Linux distros.
|
||||||
|
if ("${ARCH}" STREQUAL "x86_64")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if ("${ARCH}" STREQUAL "arm")
|
||||||
|
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv6k")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(Backends-Generic-Source
|
||||||
|
${BACKENDS_SRC_DIR}/generic/misc.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Backends-Unix-Source
|
||||||
|
${BACKENDS_SRC_DIR}/unix/main.c
|
||||||
|
${BACKENDS_SRC_DIR}/unix/network.c
|
||||||
|
${BACKENDS_SRC_DIR}/unix/signalhandler.c
|
||||||
|
${BACKENDS_SRC_DIR}/unix/system.c
|
||||||
|
${BACKENDS_SRC_DIR}/unix/shared/hunk.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Backends-Windows-Source
|
||||||
|
${BACKENDS_SRC_DIR}/windows/icon.rc
|
||||||
|
${BACKENDS_SRC_DIR}/windows/main.c
|
||||||
|
${BACKENDS_SRC_DIR}/windows/network.c
|
||||||
|
${BACKENDS_SRC_DIR}/windows/system.c
|
||||||
|
${BACKENDS_SRC_DIR}/windows/shared/hunk.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Backends-Windows-Header
|
||||||
|
${BACKENDS_SRC_DIR}/windows/header/resource.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(REF-Windows-Source
|
||||||
|
${BACKENDS_SRC_DIR}/windows/shared/hunk.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(REF-Unix-Source
|
||||||
|
${BACKENDS_SRC_DIR}/unix/shared/hunk.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set the nessesary platform specific source
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
|
set(Platform-Specific-Source ${Backends-Windows-Source} ${Backends-Windows-Header})
|
||||||
|
set(REF-Platform-Specific-Source ${REF-Windows-Source})
|
||||||
|
else()
|
||||||
|
set(Platform-Specific-Source ${Backends-Unix-Source})
|
||||||
|
set(REF-Platform-Specific-Source ${REF-Unix-Source})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(Game-Source
|
||||||
|
${COMMON_SRC_DIR}/shared/flash.c
|
||||||
|
${COMMON_SRC_DIR}/shared/rand.c
|
||||||
|
${COMMON_SRC_DIR}/shared/shared.c
|
||||||
|
${GAME_SRC_DIR}/g_ai.c
|
||||||
|
${GAME_SRC_DIR}/g_chase.c
|
||||||
|
${GAME_SRC_DIR}/g_cmds.c
|
||||||
|
${GAME_SRC_DIR}/g_combat.c
|
||||||
|
${GAME_SRC_DIR}/g_func.c
|
||||||
|
${GAME_SRC_DIR}/g_items.c
|
||||||
|
${GAME_SRC_DIR}/g_main.c
|
||||||
|
${GAME_SRC_DIR}/g_misc.c
|
||||||
|
${GAME_SRC_DIR}/g_monster.c
|
||||||
|
${GAME_SRC_DIR}/g_phys.c
|
||||||
|
${GAME_SRC_DIR}/g_spawn.c
|
||||||
|
${GAME_SRC_DIR}/g_svcmds.c
|
||||||
|
${GAME_SRC_DIR}/g_target.c
|
||||||
|
${GAME_SRC_DIR}/g_trigger.c
|
||||||
|
${GAME_SRC_DIR}/g_turret.c
|
||||||
|
${GAME_SRC_DIR}/g_utils.c
|
||||||
|
${GAME_SRC_DIR}/g_weapon.c
|
||||||
|
${GAME_SRC_DIR}/monster/berserker/berserker.c
|
||||||
|
${GAME_SRC_DIR}/monster/boss2/boss2.c
|
||||||
|
${GAME_SRC_DIR}/monster/boss3/boss3.c
|
||||||
|
${GAME_SRC_DIR}/monster/boss3/boss31.c
|
||||||
|
${GAME_SRC_DIR}/monster/boss3/boss32.c
|
||||||
|
${GAME_SRC_DIR}/monster/brain/brain.c
|
||||||
|
${GAME_SRC_DIR}/monster/chick/chick.c
|
||||||
|
${GAME_SRC_DIR}/monster/flipper/flipper.c
|
||||||
|
${GAME_SRC_DIR}/monster/float/float.c
|
||||||
|
${GAME_SRC_DIR}/monster/flyer/flyer.c
|
||||||
|
${GAME_SRC_DIR}/monster/gladiator/gladiator.c
|
||||||
|
${GAME_SRC_DIR}/monster/gunner/gunner.c
|
||||||
|
${GAME_SRC_DIR}/monster/hover/hover.c
|
||||||
|
${GAME_SRC_DIR}/monster/infantry/infantry.c
|
||||||
|
${GAME_SRC_DIR}/monster/insane/insane.c
|
||||||
|
${GAME_SRC_DIR}/monster/medic/medic.c
|
||||||
|
${GAME_SRC_DIR}/monster/misc/move.c
|
||||||
|
${GAME_SRC_DIR}/monster/mutant/mutant.c
|
||||||
|
${GAME_SRC_DIR}/monster/parasite/parasite.c
|
||||||
|
${GAME_SRC_DIR}/monster/soldier/soldier.c
|
||||||
|
${GAME_SRC_DIR}/monster/supertank/supertank.c
|
||||||
|
${GAME_SRC_DIR}/monster/tank/tank.c
|
||||||
|
${GAME_SRC_DIR}/player/client.c
|
||||||
|
${GAME_SRC_DIR}/player/hud.c
|
||||||
|
${GAME_SRC_DIR}/player/trail.c
|
||||||
|
${GAME_SRC_DIR}/player/view.c
|
||||||
|
${GAME_SRC_DIR}/player/weapon.c
|
||||||
|
${GAME_SRC_DIR}/savegame/savegame.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Game-Header
|
||||||
|
${GAME_SRC_DIR}/header/game.h
|
||||||
|
${GAME_SRC_DIR}/header/local.h
|
||||||
|
${GAME_SRC_DIR}/monster/berserker/berserker.h
|
||||||
|
${GAME_SRC_DIR}/monster/boss2/boss2.h
|
||||||
|
${GAME_SRC_DIR}/monster/boss3/boss31.h
|
||||||
|
${GAME_SRC_DIR}/monster/boss3/boss32.h
|
||||||
|
${GAME_SRC_DIR}/monster/brain/brain.h
|
||||||
|
${GAME_SRC_DIR}/monster/chick/chick.h
|
||||||
|
${GAME_SRC_DIR}/monster/flipper/flipper.h
|
||||||
|
${GAME_SRC_DIR}/monster/float/float.h
|
||||||
|
${GAME_SRC_DIR}/monster/flyer/flyer.h
|
||||||
|
${GAME_SRC_DIR}/monster/gladiator/gladiator.h
|
||||||
|
${GAME_SRC_DIR}/monster/gunner/gunner.h
|
||||||
|
${GAME_SRC_DIR}/monster/hover/hover.h
|
||||||
|
${GAME_SRC_DIR}/monster/infantry/infantry.h
|
||||||
|
${GAME_SRC_DIR}/monster/insane/insane.h
|
||||||
|
${GAME_SRC_DIR}/monster/medic/medic.h
|
||||||
|
${GAME_SRC_DIR}/monster/misc/player.h
|
||||||
|
${GAME_SRC_DIR}/monster/mutant/mutant.h
|
||||||
|
${GAME_SRC_DIR}/monster/parasite/parasite.h
|
||||||
|
${GAME_SRC_DIR}/monster/soldier/soldier.h
|
||||||
|
${GAME_SRC_DIR}/monster/supertank/supertank.h
|
||||||
|
${GAME_SRC_DIR}/monster/tank/tank.h
|
||||||
|
${GAME_SRC_DIR}/savegame/tables/clientfields.h
|
||||||
|
${GAME_SRC_DIR}/savegame/tables/fields.h
|
||||||
|
${GAME_SRC_DIR}/savegame/tables/gamefunc_decs.h
|
||||||
|
${GAME_SRC_DIR}/savegame/tables/gamefunc_list.h
|
||||||
|
${GAME_SRC_DIR}/savegame/tables/gamemmove_decs.h
|
||||||
|
${GAME_SRC_DIR}/savegame/tables/gamemmove_list.h
|
||||||
|
${GAME_SRC_DIR}/savegame/tables/levelfields.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Client-Source
|
||||||
|
${CLIENT_SRC_DIR}/cl_cin.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_console.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_download.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_effects.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_entities.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_input.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_inventory.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_keyboard.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_lights.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_main.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_network.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_parse.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_particles.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_prediction.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_screen.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_tempentities.c
|
||||||
|
${CLIENT_SRC_DIR}/cl_view.c
|
||||||
|
${CLIENT_SRC_DIR}/curl/download.c
|
||||||
|
${CLIENT_SRC_DIR}/curl/qcurl.c
|
||||||
|
${CLIENT_SRC_DIR}/menu/menu.c
|
||||||
|
${CLIENT_SRC_DIR}/menu/qmenu.c
|
||||||
|
${CLIENT_SRC_DIR}/menu/videomenu.c
|
||||||
|
${CLIENT_SRC_DIR}/sound/ogg.c
|
||||||
|
${CLIENT_SRC_DIR}/sound/openal.c
|
||||||
|
${CLIENT_SRC_DIR}/sound/qal.c
|
||||||
|
${CLIENT_SRC_DIR}/sound/sdl.c
|
||||||
|
${CLIENT_SRC_DIR}/sound/sound.c
|
||||||
|
${CLIENT_SRC_DIR}/sound/wave.c
|
||||||
|
${CLIENT_SRC_DIR}/vid/vid.c
|
||||||
|
${COMMON_SRC_DIR}/argproc.c
|
||||||
|
${COMMON_SRC_DIR}/clientserver.c
|
||||||
|
${COMMON_SRC_DIR}/collision.c
|
||||||
|
${COMMON_SRC_DIR}/crc.c
|
||||||
|
${COMMON_SRC_DIR}/cmdparser.c
|
||||||
|
${COMMON_SRC_DIR}/cvar.c
|
||||||
|
${COMMON_SRC_DIR}/filesystem.c
|
||||||
|
${COMMON_SRC_DIR}/glob.c
|
||||||
|
${COMMON_SRC_DIR}/md4.c
|
||||||
|
${COMMON_SRC_DIR}/movemsg.c
|
||||||
|
${COMMON_SRC_DIR}/frame.c
|
||||||
|
${COMMON_SRC_DIR}/netchan.c
|
||||||
|
${COMMON_SRC_DIR}/pmove.c
|
||||||
|
${COMMON_SRC_DIR}/szone.c
|
||||||
|
${COMMON_SRC_DIR}/zone.c
|
||||||
|
${COMMON_SRC_DIR}/shared/flash.c
|
||||||
|
${COMMON_SRC_DIR}/shared/rand.c
|
||||||
|
${COMMON_SRC_DIR}/shared/shared.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/ioapi.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/unzip.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz_tdef.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz_tinfl.c
|
||||||
|
${SERVER_SRC_DIR}/sv_cmd.c
|
||||||
|
${SERVER_SRC_DIR}/sv_conless.c
|
||||||
|
${SERVER_SRC_DIR}/sv_entities.c
|
||||||
|
${SERVER_SRC_DIR}/sv_game.c
|
||||||
|
${SERVER_SRC_DIR}/sv_init.c
|
||||||
|
${SERVER_SRC_DIR}/sv_main.c
|
||||||
|
${SERVER_SRC_DIR}/sv_save.c
|
||||||
|
${SERVER_SRC_DIR}/sv_send.c
|
||||||
|
${SERVER_SRC_DIR}/sv_user.c
|
||||||
|
${SERVER_SRC_DIR}/sv_world.c
|
||||||
|
)
|
||||||
|
|
||||||
|
if(SDL3_SUPPORT)
|
||||||
|
set(Client-SDL-Source
|
||||||
|
${CLIENT_SRC_DIR}/input/sdl3.c
|
||||||
|
${CLIENT_SRC_DIR}/vid/glimp_sdl3.c
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(Client-SDL-Source
|
||||||
|
${CLIENT_SRC_DIR}/input/sdl2.c
|
||||||
|
${CLIENT_SRC_DIR}/vid/glimp_sdl2.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(Client-Header
|
||||||
|
${CLIENT_SRC_DIR}/header/client.h
|
||||||
|
${CLIENT_SRC_DIR}/header/console.h
|
||||||
|
${CLIENT_SRC_DIR}/header/keyboard.h
|
||||||
|
${CLIENT_SRC_DIR}/header/screen.h
|
||||||
|
${CLIENT_SRC_DIR}/curl/header/download.h
|
||||||
|
${CLIENT_SRC_DIR}/curl/header/qcurl.h
|
||||||
|
${CLIENT_SRC_DIR}/input/header/input.h
|
||||||
|
${CLIENT_SRC_DIR}/menu/header/qmenu.h
|
||||||
|
${CLIENT_SRC_DIR}/sound/header/local.h
|
||||||
|
${CLIENT_SRC_DIR}/sound/header/qal.h
|
||||||
|
${CLIENT_SRC_DIR}/sound/header/sound.h
|
||||||
|
${CLIENT_SRC_DIR}/sound/header/stb_vorbis.h
|
||||||
|
${CLIENT_SRC_DIR}/sound/header/vorbis.h
|
||||||
|
${CLIENT_SRC_DIR}/vid/header/ref.h
|
||||||
|
${CLIENT_SRC_DIR}/vid/header/stb_image_write.h
|
||||||
|
${CLIENT_SRC_DIR}/vid/header/vid.h
|
||||||
|
${COMMON_SRC_DIR}/header/common.h
|
||||||
|
${COMMON_SRC_DIR}/header/crc.h
|
||||||
|
${COMMON_SRC_DIR}/header/files.h
|
||||||
|
${COMMON_SRC_DIR}/header/glob.h
|
||||||
|
${COMMON_SRC_DIR}/header/shared.h
|
||||||
|
${COMMON_SRC_DIR}/header/zone.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/ioapi.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/unzip.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz_tdef.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz_tinfl.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/minizconf.h
|
||||||
|
${SERVER_SRC_DIR}/header/server.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Server-Source
|
||||||
|
${COMMON_SRC_DIR}/argproc.c
|
||||||
|
${COMMON_SRC_DIR}/clientserver.c
|
||||||
|
${COMMON_SRC_DIR}/collision.c
|
||||||
|
${COMMON_SRC_DIR}/crc.c
|
||||||
|
${COMMON_SRC_DIR}/cmdparser.c
|
||||||
|
${COMMON_SRC_DIR}/cvar.c
|
||||||
|
${COMMON_SRC_DIR}/filesystem.c
|
||||||
|
${COMMON_SRC_DIR}/glob.c
|
||||||
|
${COMMON_SRC_DIR}/md4.c
|
||||||
|
${COMMON_SRC_DIR}/frame.c
|
||||||
|
${COMMON_SRC_DIR}/movemsg.c
|
||||||
|
${COMMON_SRC_DIR}/netchan.c
|
||||||
|
${COMMON_SRC_DIR}/pmove.c
|
||||||
|
${COMMON_SRC_DIR}/szone.c
|
||||||
|
${COMMON_SRC_DIR}/zone.c
|
||||||
|
${COMMON_SRC_DIR}/shared/rand.c
|
||||||
|
${COMMON_SRC_DIR}/shared/shared.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/ioapi.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/unzip.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz_tdef.c
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz_tinfl.c
|
||||||
|
${SERVER_SRC_DIR}/sv_cmd.c
|
||||||
|
${SERVER_SRC_DIR}/sv_conless.c
|
||||||
|
${SERVER_SRC_DIR}/sv_entities.c
|
||||||
|
${SERVER_SRC_DIR}/sv_game.c
|
||||||
|
${SERVER_SRC_DIR}/sv_init.c
|
||||||
|
${SERVER_SRC_DIR}/sv_main.c
|
||||||
|
${SERVER_SRC_DIR}/sv_save.c
|
||||||
|
${SERVER_SRC_DIR}/sv_send.c
|
||||||
|
${SERVER_SRC_DIR}/sv_user.c
|
||||||
|
${SERVER_SRC_DIR}/sv_world.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Server-Header
|
||||||
|
${COMMON_SRC_DIR}/header/common.h
|
||||||
|
${COMMON_SRC_DIR}/header/crc.h
|
||||||
|
${COMMON_SRC_DIR}/header/files.h
|
||||||
|
${COMMON_SRC_DIR}/header/glob.h
|
||||||
|
${COMMON_SRC_DIR}/header/shared.h
|
||||||
|
${COMMON_SRC_DIR}/header/zone.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/ioapi.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/unzip.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz_tdef.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/miniz_tinfl.h
|
||||||
|
${COMMON_SRC_DIR}/unzip/miniz/minizconf.h
|
||||||
|
${SERVER_SRC_DIR}/header/server.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(GL1-Source
|
||||||
|
${REF_SRC_DIR}/gl1/qgl.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_draw.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_image.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_light.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_lightmap.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_main.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_mesh.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_misc.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_model.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_scrap.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_surf.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_warp.c
|
||||||
|
${REF_SRC_DIR}/gl1/gl1_sdl.c
|
||||||
|
${REF_SRC_DIR}/files/models.c
|
||||||
|
${REF_SRC_DIR}/files/pcx.c
|
||||||
|
${REF_SRC_DIR}/files/stb.c
|
||||||
|
${REF_SRC_DIR}/files/surf.c
|
||||||
|
${REF_SRC_DIR}/files/wal.c
|
||||||
|
${REF_SRC_DIR}/files/pvs.c
|
||||||
|
${COMMON_SRC_DIR}/shared/shared.c
|
||||||
|
${COMMON_SRC_DIR}/md4.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(GL1-Header
|
||||||
|
${REF_SRC_DIR}/ref_shared.h
|
||||||
|
${REF_SRC_DIR}/constants/anorms.h
|
||||||
|
${REF_SRC_DIR}/constants/anormtab.h
|
||||||
|
${REF_SRC_DIR}/constants/warpsin.h
|
||||||
|
${REF_SRC_DIR}/files/stb_image.h
|
||||||
|
${REF_SRC_DIR}/files/surf.c
|
||||||
|
${REF_SRC_DIR}/gl1/header/local.h
|
||||||
|
${REF_SRC_DIR}/gl1/header/model.h
|
||||||
|
${REF_SRC_DIR}/gl1/header/qgl.h
|
||||||
|
${COMMON_SRC_DIR}/header/shared.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(GL3-Source
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_draw.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_image.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_light.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_lightmap.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_main.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_mesh.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_misc.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_model.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_sdl.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_surf.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_warp.c
|
||||||
|
${REF_SRC_DIR}/gl3/gl3_shaders.c
|
||||||
|
${REF_SRC_DIR}/files/models.c
|
||||||
|
${REF_SRC_DIR}/files/pcx.c
|
||||||
|
${REF_SRC_DIR}/files/stb.c
|
||||||
|
${REF_SRC_DIR}/files/surf.c
|
||||||
|
${REF_SRC_DIR}/files/wal.c
|
||||||
|
${REF_SRC_DIR}/files/pvs.c
|
||||||
|
${COMMON_SRC_DIR}/shared/shared.c
|
||||||
|
${COMMON_SRC_DIR}/md4.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Glad-GL3-Source ${REF_SRC_DIR}/gl3/glad/src/glad.c)
|
||||||
|
set(Glad-GLES3-Source ${REF_SRC_DIR}/gl3/glad-gles3/src/glad.c)
|
||||||
|
|
||||||
|
set(GL3-Header
|
||||||
|
${REF_SRC_DIR}/ref_shared.h
|
||||||
|
${REF_SRC_DIR}/constants/anorms.h
|
||||||
|
${REF_SRC_DIR}/constants/anormtab.h
|
||||||
|
${REF_SRC_DIR}/constants/warpsin.h
|
||||||
|
${REF_SRC_DIR}/files/stb_image.h
|
||||||
|
${REF_SRC_DIR}/gl3/header/DG_dynarr.h
|
||||||
|
${REF_SRC_DIR}/gl3/header/HandmadeMath.h
|
||||||
|
${REF_SRC_DIR}/gl3/header/local.h
|
||||||
|
${REF_SRC_DIR}/gl3/header/model.h
|
||||||
|
${COMMON_SRC_DIR}/header/shared.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Glad-GL3-Header
|
||||||
|
${REF_SRC_DIR}/gl3/glad/include/glad/glad.h
|
||||||
|
${REF_SRC_DIR}/gl3/glad/include/KHR/khrplatform.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Glad-GLES3-Header
|
||||||
|
${REF_SRC_DIR}/gl3/glad-gles3/include/glad/glad.h
|
||||||
|
${REF_SRC_DIR}/gl3/glad-gles3/include/KHR/khrplatform.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOFT-Source
|
||||||
|
${REF_SRC_DIR}/soft/sw_aclip.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_alias.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_bsp.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_draw.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_edge.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_image.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_light.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_main.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_misc.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_model.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_part.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_poly.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_polyset.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_rast.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_scan.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_sprite.c
|
||||||
|
${REF_SRC_DIR}/soft/sw_surf.c
|
||||||
|
${REF_SRC_DIR}/files/models.c
|
||||||
|
${REF_SRC_DIR}/files/pcx.c
|
||||||
|
${REF_SRC_DIR}/files/stb.c
|
||||||
|
${REF_SRC_DIR}/files/surf.c
|
||||||
|
${REF_SRC_DIR}/files/wal.c
|
||||||
|
${REF_SRC_DIR}/files/pvs.c
|
||||||
|
${COMMON_SRC_DIR}/shared/shared.c
|
||||||
|
${COMMON_SRC_DIR}/md4.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOFT-Header
|
||||||
|
${REF_SRC_DIR}/ref_shared.h
|
||||||
|
${REF_SRC_DIR}/files/stb_image.h
|
||||||
|
${REF_SRC_DIR}/files/stb_image_resize.h
|
||||||
|
${REF_SRC_DIR}/soft/header/local.h
|
||||||
|
${REF_SRC_DIR}/soft/header/model.h
|
||||||
|
${COMMON_SRC_DIR}/header/shared.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# Main Quake 2 executable
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
|
add_executable(yquake2 WIN32 ${Client-Source} ${Client-SDL-Source} ${Client-Header}
|
||||||
|
${Platform-Specific-Source} ${Backends-Generic-Source})
|
||||||
|
set_target_properties(yquake2 PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
)
|
||||||
|
target_link_libraries(yquake2 ${yquake2LinkerFlags} ${yquake2ClientLinkerFlags}
|
||||||
|
${yquake2SDLLinkerFlags} ${yquake2ZLibLinkerFlags} ws2_32 winmm)
|
||||||
|
if(SDL3_SUPPORT)
|
||||||
|
target_link_libraries(yquake2 SDL3::SDL3)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
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
|
||||||
|
set(Wrapper-Source
|
||||||
|
src/win-wrapper/wrapper.c
|
||||||
|
${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()
|
||||||
|
add_executable(quake2 ${Client-Source} ${Client-SDL-Source} ${Client-Header}
|
||||||
|
${Platform-Specific-Source} ${Backends-Generic-Source})
|
||||||
|
set_target_properties(quake2 PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
)
|
||||||
|
target_link_libraries(quake2 ${yquake2LinkerFlags} ${yquake2ClientLinkerFlags}
|
||||||
|
${yquake2SDLLinkerFlags} ${yquake2ZLibLinkerFlags})
|
||||||
|
if(SDL3_SUPPORT)
|
||||||
|
target_link_libraries(quake2 SDL3::SDL3)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Quake 2 Dedicated Server
|
||||||
|
add_executable(q2ded ${Server-Source} ${Server-Header} ${Platform-Specific-Source}
|
||||||
|
${Backends-Generic-Source})
|
||||||
|
set_target_properties(q2ded PROPERTIES
|
||||||
|
COMPILE_DEFINITIONS "DEDICATED_ONLY"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
)
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
|
target_link_libraries(q2ded ${yquake2LinkerFlags})
|
||||||
|
else()
|
||||||
|
target_link_libraries(q2ded ${yquake2LinkerFlags} ${yquake2ServerLinkerFlags} ${yquake2ZLibLinkerFlags})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Build the game dynamic library
|
||||||
|
add_library(game MODULE ${Game-Source} ${Game-Header})
|
||||||
|
set_target_properties(game PROPERTIES
|
||||||
|
PREFIX ""
|
||||||
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
)
|
||||||
|
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
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release/baseq2
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(game ${yquake2LinkerFlags})
|
||||||
|
|
||||||
|
# Build the GL1 dynamic library
|
||||||
|
add_library(ref_gl1 MODULE ${GL1-Source} ${GL1-Header} ${REF-Platform-Specific-Source})
|
||||||
|
set_target_properties(ref_gl1 PROPERTIES
|
||||||
|
PREFIX ""
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
)
|
||||||
|
target_link_libraries(ref_gl1 ${yquake2LinkerFlags} ${yquake2OpenGLLinkerFlags}
|
||||||
|
${yquake2SDLLinkerFlags})
|
||||||
|
if(SDL3_SUPPORT)
|
||||||
|
target_link_libraries(ref_gl1 SDL3::SDL3)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Build the GL3 dynamic library
|
||||||
|
add_library(ref_gl3 MODULE ${GL3-Source} ${Glad-GL3-Source} ${GL3-Header} ${Glad-GL3-Header} ${REF-Platform-Specific-Source})
|
||||||
|
set_target_properties(ref_gl3 PROPERTIES
|
||||||
|
PREFIX ""
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
)
|
||||||
|
target_include_directories(ref_gl3 PRIVATE ${CMAKE_SOURCE_DIR}/src/client/refresh/gl3/glad/include)
|
||||||
|
target_link_libraries(ref_gl3 ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
||||||
|
if(SDL3_SUPPORT)
|
||||||
|
target_link_libraries(ref_gl3 SDL3::SDL3)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Build the GLES3 dynamic library
|
||||||
|
add_library(ref_gles3 MODULE ${GL3-Source} ${Glad-GLES3-Source} ${GL3-Header} ${Glad-GLES3-Header} ${REF-Platform-Specific-Source})
|
||||||
|
set_target_properties(ref_gles3 PROPERTIES
|
||||||
|
PREFIX ""
|
||||||
|
#COMPILE_DEFINITIONS "YQ2_GL3_GLES3=1;YQ2_GL3_GLES=1"
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
)
|
||||||
|
target_include_directories(ref_gles3 PRIVATE ${CMAKE_SOURCE_DIR}/src/client/refresh/gl3/glad-gles3/include)
|
||||||
|
target_compile_definitions(ref_gles3 PRIVATE YQ2_GL3_GLES3=1 YQ2_GL3_GLES=1)
|
||||||
|
target_link_libraries(ref_gles3 ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
||||||
|
if(SDL3_SUPPORT)
|
||||||
|
target_link_libraries(ref_gles3 SDL3::SDL3)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Build the soft renderer dynamic library
|
||||||
|
add_library(ref_soft MODULE ${SOFT-Source} ${SOFT-Header} ${REF-Platform-Specific-Source})
|
||||||
|
set_target_properties(ref_soft PROPERTIES
|
||||||
|
PREFIX ""
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||||
|
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||||
|
)
|
||||||
|
target_link_libraries(ref_soft ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
||||||
|
if(SDL3_SUPPORT)
|
||||||
|
target_link_libraries(ref_soft SDL3::SDL3)
|
||||||
|
endif()
|
39
Makefile
39
Makefile
|
@ -8,7 +8,7 @@
|
||||||
# - Renderer libraries (gl1, gl3, soft) #
|
# - Renderer libraries (gl1, gl3, soft) #
|
||||||
# #
|
# #
|
||||||
# Base dependencies: #
|
# Base dependencies: #
|
||||||
# - SDL 2.0 #
|
# - SDL 2 or SDL 3 #
|
||||||
# - libGL #
|
# - libGL #
|
||||||
# - Vulkan headers #
|
# - Vulkan headers #
|
||||||
# #
|
# #
|
||||||
|
@ -56,6 +56,9 @@ WITH_AVCODEC:=yes
|
||||||
# or libopenal.so. Not supported on Windows.
|
# or libopenal.so. Not supported on Windows.
|
||||||
WITH_RPATH:=yes
|
WITH_RPATH:=yes
|
||||||
|
|
||||||
|
# Builds with SDL 3 instead of SDL 2.
|
||||||
|
WITH_SDL3:=no
|
||||||
|
|
||||||
# Enable systemwide installation of game assets.
|
# Enable systemwide installation of game assets.
|
||||||
WITH_SYSTEMWIDE:=no
|
WITH_SYSTEMWIDE:=no
|
||||||
|
|
||||||
|
@ -279,7 +282,12 @@ endif
|
||||||
# ----------
|
# ----------
|
||||||
|
|
||||||
# Extra CFLAGS for SDL.
|
# Extra CFLAGS for SDL.
|
||||||
|
ifeq ($(WITH_SDL3),yes)
|
||||||
|
SDLCFLAGS := $(shell pkgconf --cflags sdl3)
|
||||||
|
SDLCFLAGS += -DUSE_SDL3
|
||||||
|
else
|
||||||
SDLCFLAGS := $(shell sdl2-config --cflags)
|
SDLCFLAGS := $(shell sdl2-config --cflags)
|
||||||
|
endif
|
||||||
|
|
||||||
# ----------
|
# ----------
|
||||||
|
|
||||||
|
@ -356,11 +364,19 @@ endif
|
||||||
# ----------
|
# ----------
|
||||||
|
|
||||||
# Extra LDFLAGS for SDL
|
# Extra LDFLAGS for SDL
|
||||||
|
ifeq ($(WITH_SDL3),yes)
|
||||||
|
ifeq ($(YQ2_OSTYPE), Darwin)
|
||||||
|
SDLLDFLAGS := -lSDL3
|
||||||
|
else
|
||||||
|
SDLLDFLAGS := $(shell pkgconf --libs sdl3)
|
||||||
|
endif
|
||||||
|
else
|
||||||
ifeq ($(YQ2_OSTYPE), Darwin)
|
ifeq ($(YQ2_OSTYPE), Darwin)
|
||||||
SDLLDFLAGS := -lSDL2
|
SDLLDFLAGS := -lSDL2
|
||||||
else # not Darwin
|
else
|
||||||
SDLLDFLAGS := $(shell sdl2-config --libs)
|
SDLLDFLAGS := $(shell sdl2-config --libs)
|
||||||
endif # Darwin
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
# The renderer libs don't need libSDL2main, libmingw32 or -mwindows.
|
# The renderer libs don't need libSDL2main, libmingw32 or -mwindows.
|
||||||
ifeq ($(YQ2_OSTYPE), Windows)
|
ifeq ($(YQ2_OSTYPE), Windows)
|
||||||
|
@ -398,6 +414,7 @@ config:
|
||||||
@echo "WITH_OPENAL = $(WITH_OPENAL)"
|
@echo "WITH_OPENAL = $(WITH_OPENAL)"
|
||||||
@echo "WITH_AVCODEC = $(WITH_AVCODEC)"
|
@echo "WITH_AVCODEC = $(WITH_AVCODEC)"
|
||||||
@echo "WITH_RPATH = $(WITH_RPATH)"
|
@echo "WITH_RPATH = $(WITH_RPATH)"
|
||||||
|
@echo "WITH_SDL3 = $(WITH_SDL3)"
|
||||||
@echo "WITH_SYSTEMWIDE = $(WITH_SYSTEMWIDE)"
|
@echo "WITH_SYSTEMWIDE = $(WITH_SYSTEMWIDE)"
|
||||||
@echo "WITH_SYSTEMDIR = $(WITH_SYSTEMDIR)"
|
@echo "WITH_SYSTEMDIR = $(WITH_SYSTEMDIR)"
|
||||||
@echo "============================"
|
@echo "============================"
|
||||||
|
@ -971,17 +988,15 @@ CLIENT_OBJS_ := \
|
||||||
src/client/cl_view.o \
|
src/client/cl_view.o \
|
||||||
src/client/curl/download.o \
|
src/client/curl/download.o \
|
||||||
src/client/curl/qcurl.o \
|
src/client/curl/qcurl.o \
|
||||||
src/client/input/sdl.o \
|
|
||||||
src/client/menu/menu.o \
|
src/client/menu/menu.o \
|
||||||
src/client/menu/qmenu.o \
|
src/client/menu/qmenu.o \
|
||||||
src/client/menu/videomenu.o \
|
src/client/menu/videomenu.o \
|
||||||
src/client/sound/sdl.o \
|
|
||||||
src/client/sound/ogg.o \
|
src/client/sound/ogg.o \
|
||||||
src/client/sound/openal.o \
|
src/client/sound/openal.o \
|
||||||
src/client/sound/qal.o \
|
src/client/sound/qal.o \
|
||||||
|
src/client/sound/sdl.o \
|
||||||
src/client/sound/sound.o \
|
src/client/sound/sound.o \
|
||||||
src/client/sound/wave.o \
|
src/client/sound/wave.o \
|
||||||
src/client/vid/glimp_sdl.o \
|
|
||||||
src/client/vid/vid.o \
|
src/client/vid/vid.o \
|
||||||
src/common/argproc.o \
|
src/common/argproc.o \
|
||||||
src/common/clientserver.o \
|
src/common/clientserver.o \
|
||||||
|
@ -1020,6 +1035,16 @@ CLIENT_OBJS_ := \
|
||||||
src/server/sv_user.o \
|
src/server/sv_user.o \
|
||||||
src/server/sv_world.o
|
src/server/sv_world.o
|
||||||
|
|
||||||
|
ifeq ($(WITH_SDL3),yes)
|
||||||
|
CLIENT_OBJS_ += \
|
||||||
|
src/client/input/sdl3.o \
|
||||||
|
src/client/vid/glimp_sdl3.o
|
||||||
|
else
|
||||||
|
CLIENT_OBJS_ += \
|
||||||
|
src/client/input/sdl2.o \
|
||||||
|
src/client/vid/glimp_sdl2.o
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(YQ2_OSTYPE), Windows)
|
ifeq ($(YQ2_OSTYPE), Windows)
|
||||||
CLIENT_OBJS_ += \
|
CLIENT_OBJS_ += \
|
||||||
src/backends/windows/main.o \
|
src/backends/windows/main.o \
|
||||||
|
@ -1368,7 +1393,7 @@ endif
|
||||||
ifeq ($(YQ2_OSTYPE), Windows)
|
ifeq ($(YQ2_OSTYPE), Windows)
|
||||||
release/q2ded.exe : $(SERVER_OBJS) icon
|
release/q2ded.exe : $(SERVER_OBJS) icon
|
||||||
@echo "===> LD $@"
|
@echo "===> LD $@"
|
||||||
${Q}$(CC) $(LDFLAGS) build/icon/icon.res $(SERVER_OBJS) $(LDLIBS) $(SDLLDFLAGS) -o $@
|
${Q}$(CC) $(LDFLAGS) build/icon/icon.res $(SERVER_OBJS) $(LDLIBS) -o $@
|
||||||
$(Q)strip $@
|
$(Q)strip $@
|
||||||
else
|
else
|
||||||
release/q2ded : $(SERVER_OBJS)
|
release/q2ded : $(SERVER_OBJS)
|
||||||
|
|
|
@ -408,12 +408,14 @@ Set `0` by default.
|
||||||
has 59.95hz.
|
has 59.95hz.
|
||||||
|
|
||||||
* **vid_gamma**: The value used for gamma correction. Higher values look
|
* **vid_gamma**: The value used for gamma correction. Higher values look
|
||||||
brighter. The OpenGL 1.4 and software renderers use "Hardware Gamma",
|
brighter. The OpenGL 3.2 OpenGL ES3 and Vulkan renderers apply this to
|
||||||
setting the Gamma of the whole screen to this value in realtime
|
the window in realtime via shaders (on all platforms). When the game
|
||||||
(except on MacOS where it's applied to textures on load and thus needs
|
is build against SDL2, the OpenGL 1.4 renderer uses "hardware gamma"
|
||||||
a `vid_restart` after changing). The OpenGL 3.2 and Vulkan renderers
|
when available, increasing the brightness of the whole screen. On
|
||||||
apply this to the window in realtime via shaders (on all platforms).
|
MacOS the gamma is applied only at renderer start, so a `vid_restart`
|
||||||
This is also set by the brightness slider in the video menu.
|
is required. When the game is build against SDL3, the OpenGL 1.4
|
||||||
|
renderer doesn't support gamma. Have a look at `gl1_overbrightbits`
|
||||||
|
instead. This is also set by the brightness slider in the video menu.
|
||||||
|
|
||||||
* **vid_fullscreen**: Sets the fullscreen mode. When set to `0` (the
|
* **vid_fullscreen**: Sets the fullscreen mode. When set to `0` (the
|
||||||
default) the game runs in window mode. When set to `1` the games
|
default) the game runs in window mode. When set to `1` the games
|
||||||
|
@ -428,10 +430,12 @@ Set `0` by default.
|
||||||
scaling factor of the underlying display. Example: The displays
|
scaling factor of the underlying display. Example: The displays
|
||||||
scaling factor is 1.25 and the user requests 1920x1080. The client
|
scaling factor is 1.25 and the user requests 1920x1080. The client
|
||||||
will render at 1920\*1.25x1080\*1.25=2400x1350.
|
will render at 1920\*1.25x1080\*1.25=2400x1350.
|
||||||
When set to `0` (the default) the client leaves the decision if the
|
When set to `0` the client leaves the decision if the window should
|
||||||
window should be scaled to the underlying compositor. Scaling applied
|
be scaled to the underlying compositor. Scaling applied by the
|
||||||
by the compositor may introduce blur and sluggishness.
|
compositor may introduce blur and sluggishness.
|
||||||
Currently high dpi awareness is only supported under Wayland.
|
Currently high dpi awareness is only supported under Wayland.
|
||||||
|
Defaults to `0` when build against SDL2 and to `1` when build against
|
||||||
|
SDL3.
|
||||||
|
|
||||||
* **vid_maxfps**: The maximum framerate. *Note* that vsync (`r_vsync`)
|
* **vid_maxfps**: The maximum framerate. *Note* that vsync (`r_vsync`)
|
||||||
also restricts the framerate to the monitor refresh rate, so if vsync
|
also restricts the framerate to the monitor refresh rate, so if vsync
|
||||||
|
@ -444,9 +448,9 @@ Set `0` by default.
|
||||||
game can be paused, e.g. not in multiplayer games. Defaults to `0`.
|
game can be paused, e.g. not in multiplayer games. Defaults to `0`.
|
||||||
|
|
||||||
* **vid_renderer**: Selects the renderer library. Possible options are
|
* **vid_renderer**: Selects the renderer library. Possible options are
|
||||||
`gl1` (the default) for the old OpenGL 1.4 renderer, `gl3` for the
|
`gl3` (the default) for the OpenGL 3.2 renderer, `gles3` for the
|
||||||
OpenGL 3.2 renderer, `gles3` for the OpenGL ES3 renderer
|
OpenGL ES3 renderer, gl1 for the original OpenGL 1.4 renderer and
|
||||||
and `soft` for the software renderer.
|
`soft` for the software renderer.
|
||||||
|
|
||||||
* **r_dynamic**: Enamble dynamic light in gl1 and vk renders.
|
* **r_dynamic**: Enamble dynamic light in gl1 and vk renders.
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifndef DEDICATED_ONLY
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3/SDL_main.h>
|
||||||
|
#else
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_main.h>
|
#include <SDL2/SDL_main.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../../common/header/common.h"
|
#include "../../common/header/common.h"
|
||||||
|
|
||||||
|
|
|
@ -701,7 +701,7 @@ IN_Update(void)
|
||||||
{
|
{
|
||||||
// make sure GLimp_GetRefreshRate() will query from SDL again - the window might
|
// make sure GLimp_GetRefreshRate() will query from SDL again - the window might
|
||||||
// be on another display now!
|
// be on another display now!
|
||||||
glimp_refreshRate = -1;
|
glimp_refreshRate = -1.0f;
|
||||||
}
|
}
|
||||||
else if (event.window.event == SDL_WINDOWEVENT_SHOWN)
|
else if (event.window.event == SDL_WINDOWEVENT_SHOWN)
|
||||||
{
|
{
|
2389
src/client/input/sdl3.c
Normal file
2389
src/client/input/sdl3.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1920,6 +1920,7 @@ GetRefAPI(refimport_t imp)
|
||||||
ri = imp;
|
ri = imp;
|
||||||
|
|
||||||
refexport.api_version = API_VERSION;
|
refexport.api_version = API_VERSION;
|
||||||
|
refexport.framework_version = RI_GetSDLVersion();
|
||||||
|
|
||||||
refexport.Init = RI_Init;
|
refexport.Init = RI_Init;
|
||||||
refexport.Shutdown = RI_Shutdown;
|
refexport.Shutdown = RI_Shutdown;
|
||||||
|
|
|
@ -27,7 +27,11 @@
|
||||||
|
|
||||||
#include "header/local.h"
|
#include "header/local.h"
|
||||||
|
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#else
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <OpenGL/gl.h>
|
#include <OpenGL/gl.h>
|
||||||
|
@ -155,7 +159,20 @@ void RI_SetVsync(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
int vsyncState;
|
||||||
|
if (SDL_GL_GetSwapInterval(&vsyncState) != 0)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "Failed to get vsync state, assuming vsync inactive.\n");
|
||||||
|
vsyncActive = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vsyncActive = vsyncState ? true : false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
vsyncActive = SDL_GL_GetSwapInterval() != 0;
|
vsyncActive = SDL_GL_GetSwapInterval() != 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -164,6 +181,10 @@ void RI_SetVsync(void)
|
||||||
void
|
void
|
||||||
RI_UpdateGamma(void)
|
RI_UpdateGamma(void)
|
||||||
{
|
{
|
||||||
|
// TODO SDL3: Hardware gamma / gamma ramps are no longer supported with
|
||||||
|
// SDL3. There's no replacement and sdl2-compat won't support it either.
|
||||||
|
// See https://github.com/libsdl-org/SDL/pull/6617 for the rational.
|
||||||
|
#ifndef USE_SDL3
|
||||||
float gamma = (vid_gamma->value);
|
float gamma = (vid_gamma->value);
|
||||||
|
|
||||||
Uint16 ramp[256];
|
Uint16 ramp[256];
|
||||||
|
@ -173,6 +194,7 @@ RI_UpdateGamma(void)
|
||||||
{
|
{
|
||||||
R_Printf(PRINT_ALL, "Setting gamma failed: %s\n", SDL_GetError());
|
R_Printf(PRINT_ALL, "Setting gamma failed: %s\n", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -251,7 +273,11 @@ int RI_InitContext(void* win)
|
||||||
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
||||||
// Figure out if we are high dpi aware.
|
// Figure out if we are high dpi aware.
|
||||||
int flags = SDL_GetWindowFlags(win);
|
int flags = SDL_GetWindowFlags(win);
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
IsHighDPIaware = (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) ? true : false;
|
||||||
|
#else
|
||||||
IsHighDPIaware = (flags & SDL_WINDOW_ALLOW_HIGHDPI) ? true : false;
|
IsHighDPIaware = (flags & SDL_WINDOW_ALLOW_HIGHDPI) ? true : false;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -262,7 +288,11 @@ int RI_InitContext(void* win)
|
||||||
*/
|
*/
|
||||||
void RI_GetDrawableSize(int* width, int* height)
|
void RI_GetDrawableSize(int* width, int* height)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
SDL_GetWindowSizeInPixels(window, width, height);
|
||||||
|
#else
|
||||||
SDL_GL_GetDrawableSize(window, width, height);
|
SDL_GL_GetDrawableSize(window, width, height);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -280,3 +310,21 @@ RI_ShutdownContext(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the SDL major version. Implemented
|
||||||
|
* here to not polute gl1_main.c with the SDL
|
||||||
|
* headers.
|
||||||
|
*/
|
||||||
|
int RI_GetSDLVersion()
|
||||||
|
{
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
SDL_Version ver;
|
||||||
|
#else
|
||||||
|
SDL_version ver;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_VERSION(&ver);
|
||||||
|
|
||||||
|
return ver.major;
|
||||||
|
}
|
||||||
|
|
|
@ -426,6 +426,13 @@ void *RI_GetProcAddress (const char* proc);
|
||||||
*/
|
*/
|
||||||
void RI_GetDrawableSize(int* width, int* height);
|
void RI_GetDrawableSize(int* width, int* height);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the SDL major version. Implemented
|
||||||
|
* here to not polute gl1_main.c with the SDL
|
||||||
|
* headers.
|
||||||
|
*/
|
||||||
|
int RI_GetSDLVersion();
|
||||||
|
|
||||||
/* g11_draw */
|
/* g11_draw */
|
||||||
extern image_t * RDraw_FindPic(const char *name);
|
extern image_t * RDraw_FindPic(const char *name);
|
||||||
extern void RDraw_GetPicSize(int *w, int *h, const char *pic);
|
extern void RDraw_GetPicSize(int *w, int *h, const char *pic);
|
||||||
|
|
|
@ -1995,6 +1995,7 @@ GetRefAPI(refimport_t imp)
|
||||||
ri = imp;
|
ri = imp;
|
||||||
|
|
||||||
re.api_version = API_VERSION;
|
re.api_version = API_VERSION;
|
||||||
|
re.framework_version = GL3_GetSDLVersion();
|
||||||
|
|
||||||
re.Init = GL3_Init;
|
re.Init = GL3_Init;
|
||||||
re.Shutdown = GL3_Shutdown;
|
re.Shutdown = GL3_Shutdown;
|
||||||
|
|
|
@ -29,7 +29,11 @@
|
||||||
|
|
||||||
#include "header/local.h"
|
#include "header/local.h"
|
||||||
|
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#else
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static SDL_Window* window = NULL;
|
static SDL_Window* window = NULL;
|
||||||
static SDL_GLContext context = NULL;
|
static SDL_GLContext context = NULL;
|
||||||
|
@ -162,7 +166,20 @@ void GL3_SetVsync(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
int vsyncState;
|
||||||
|
if (SDL_GL_GetSwapInterval(&vsyncState) != 0)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "Failed to get vsync state, assuming vsync inactive.\n");
|
||||||
|
vsyncActive = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vsyncActive = vsyncState ? true : false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
vsyncActive = SDL_GL_GetSwapInterval() != 0;
|
vsyncActive = SDL_GL_GetSwapInterval() != 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -345,9 +362,9 @@ int GL3_InitContext(void* win)
|
||||||
|
|
||||||
// Load GL pointers through GLAD and check context.
|
// Load GL pointers through GLAD and check context.
|
||||||
#ifdef YQ2_GL3_GLES
|
#ifdef YQ2_GL3_GLES
|
||||||
if( !gladLoadGLES2Loader(SDL_GL_GetProcAddress))
|
if( !gladLoadGLES2Loader((void *)SDL_GL_GetProcAddress))
|
||||||
#else // Desktop GL
|
#else // Desktop GL
|
||||||
if( !gladLoadGLLoader(SDL_GL_GetProcAddress))
|
if( !gladLoadGLLoader((void *)SDL_GL_GetProcAddress))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
R_Printf(PRINT_ALL, "GL3_InitContext(): ERROR: loading OpenGL function pointers failed!\n");
|
R_Printf(PRINT_ALL, "GL3_InitContext(): ERROR: loading OpenGL function pointers failed!\n");
|
||||||
|
@ -406,7 +423,11 @@ int GL3_InitContext(void* win)
|
||||||
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
||||||
// Figure out if we are high dpi aware.
|
// Figure out if we are high dpi aware.
|
||||||
int flags = SDL_GetWindowFlags(win);
|
int flags = SDL_GetWindowFlags(win);
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
IsHighDPIaware = (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) ? true : false;
|
||||||
|
#else
|
||||||
IsHighDPIaware = (flags & SDL_WINDOW_ALLOW_HIGHDPI) ? true : false;
|
IsHighDPIaware = (flags & SDL_WINDOW_ALLOW_HIGHDPI) ? true : false;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -417,7 +438,11 @@ int GL3_InitContext(void* win)
|
||||||
*/
|
*/
|
||||||
void GL3_GetDrawableSize(int* width, int* height)
|
void GL3_GetDrawableSize(int* width, int* height)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
SDL_GetWindowSizeInPixels(window, width, height);
|
||||||
|
#else
|
||||||
SDL_GL_GetDrawableSize(window, width, height);
|
SDL_GL_GetDrawableSize(window, width, height);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -434,3 +459,21 @@ void GL3_ShutdownContext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the SDL major version. Implemented
|
||||||
|
* here to not polute gl3_main.c with the SDL
|
||||||
|
* headers.
|
||||||
|
*/
|
||||||
|
int GL3_GetSDLVersion()
|
||||||
|
{
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
SDL_Version ver;
|
||||||
|
#else
|
||||||
|
SDL_version ver;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_VERSION(&ver);
|
||||||
|
|
||||||
|
return ver.major;
|
||||||
|
}
|
||||||
|
|
|
@ -393,6 +393,7 @@ extern qboolean GL3_IsVsyncActive(void);
|
||||||
extern void GL3_EndFrame(void);
|
extern void GL3_EndFrame(void);
|
||||||
extern void GL3_SetVsync(void);
|
extern void GL3_SetVsync(void);
|
||||||
extern void GL3_ShutdownContext(void);
|
extern void GL3_ShutdownContext(void);
|
||||||
|
extern int GL3_GetSDLVersion(void);
|
||||||
|
|
||||||
// gl3_misc.c
|
// gl3_misc.c
|
||||||
extern void GL3_InitParticleTexture(void);
|
extern void GL3_InitParticleTexture(void);
|
||||||
|
|
|
@ -22,8 +22,12 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#else
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_video.h>
|
#include <SDL2/SDL_video.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "header/local.h"
|
#include "header/local.h"
|
||||||
|
|
||||||
|
@ -1802,10 +1806,19 @@ GetRefAPI(refimport_t imp)
|
||||||
// used different variable name for prevent confusion and cppcheck warnings
|
// used different variable name for prevent confusion and cppcheck warnings
|
||||||
refexport_t refexport;
|
refexport_t refexport;
|
||||||
|
|
||||||
|
// Need to communicate the SDL major version to the client.
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
SDL_Version ver;
|
||||||
|
#else
|
||||||
|
SDL_version ver;
|
||||||
|
#endif
|
||||||
|
SDL_VERSION(&ver);
|
||||||
|
|
||||||
memset(&refexport, 0, sizeof(refexport_t));
|
memset(&refexport, 0, sizeof(refexport_t));
|
||||||
ri = imp;
|
ri = imp;
|
||||||
|
|
||||||
refexport.api_version = API_VERSION;
|
refexport.api_version = API_VERSION;
|
||||||
|
refexport.framework_version = ver.major;
|
||||||
|
|
||||||
refexport.BeginRegistration = RE_BeginRegistration;
|
refexport.BeginRegistration = RE_BeginRegistration;
|
||||||
refexport.RegisterModel = RE_RegisterModel;
|
refexport.RegisterModel = RE_RegisterModel;
|
||||||
|
@ -1890,11 +1903,19 @@ RE_InitContext(void *win)
|
||||||
|
|
||||||
if (r_vsync->value)
|
if (r_vsync->value)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
#else
|
||||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_ACCELERATED);
|
||||||
|
#else
|
||||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select the color for drawing. It is set to black here. */
|
/* Select the color for drawing. It is set to black here. */
|
||||||
|
@ -1910,7 +1931,11 @@ RE_InitContext(void *win)
|
||||||
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
||||||
// Figure out if we are high dpi aware.
|
// Figure out if we are high dpi aware.
|
||||||
int flags = SDL_GetWindowFlags(win);
|
int flags = SDL_GetWindowFlags(win);
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
IsHighDPIaware = (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) ? true : false;
|
||||||
|
#else
|
||||||
IsHighDPIaware = (flags & SDL_WINDOW_ALLOW_HIGHDPI) ? true : false;
|
IsHighDPIaware = (flags & SDL_WINDOW_ALLOW_HIGHDPI) ? true : false;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We can't rely on vid, because the context is created
|
/* We can't rely on vid, because the context is created
|
||||||
|
@ -1949,7 +1974,11 @@ RE_InitContext(void *win)
|
||||||
*/
|
*/
|
||||||
void RE_GetDrawableSize(int* width, int* height)
|
void RE_GetDrawableSize(int* width, int* height)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
SDL_GetCurrentRenderOutputSize(renderer, width, height);
|
||||||
|
#else
|
||||||
SDL_GetRendererOutputSize(renderer, width, height);
|
SDL_GetRendererOutputSize(renderer, width, height);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2225,7 +2254,12 @@ RE_FlushFrame(int vmin, int vmax)
|
||||||
|
|
||||||
SDL_UnlockTexture(texture);
|
SDL_UnlockTexture(texture);
|
||||||
|
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
SDL_RenderTexture(renderer, texture, NULL, NULL);
|
||||||
|
#else
|
||||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
|
|
||||||
// replace use next buffer
|
// replace use next buffer
|
||||||
|
|
|
@ -19,7 +19,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#else
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "header/local.h"
|
#include "header/local.h"
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* SDL includes */
|
/* SDL includes */
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#else
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Local includes */
|
/* Local includes */
|
||||||
#include "../../client/header/client.h"
|
#include "../../client/header/client.h"
|
||||||
|
@ -811,7 +815,9 @@ SDL_ClearBuffer(void)
|
||||||
clear = 0;
|
clear = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_SDL3
|
||||||
SDL_LockAudio();
|
SDL_LockAudio();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sound.buffer)
|
if (sound.buffer)
|
||||||
{
|
{
|
||||||
|
@ -827,7 +833,9 @@ SDL_ClearBuffer(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_SDL3
|
||||||
SDL_UnlockAudio();
|
SDL_UnlockAudio();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1191,7 +1199,9 @@ SDL_Update(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mix the samples */
|
/* Mix the samples */
|
||||||
|
#ifndef USE_SDL3
|
||||||
SDL_LockAudio();
|
SDL_LockAudio();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Updates SDL time */
|
/* Updates SDL time */
|
||||||
SDL_UpdateSoundtime();
|
SDL_UpdateSoundtime();
|
||||||
|
@ -1221,7 +1231,9 @@ SDL_Update(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_PaintChannels(endtime);
|
SDL_PaintChannels(endtime);
|
||||||
|
#ifndef USE_SDL3
|
||||||
SDL_UnlockAudio();
|
SDL_UnlockAudio();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
@ -1297,6 +1309,193 @@ SDL_Callback(void *data, Uint8 *stream, int length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SDL3
|
||||||
|
/* Global stream handle. */
|
||||||
|
static SDL_AudioStream *stream;
|
||||||
|
|
||||||
|
/* Wrapper function, ties the old existing callback logic
|
||||||
|
* from the SDL 1.2 days and later fiddled into SDL 2 to
|
||||||
|
* a SDL 3 compatible callback...
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
SDL_SDL3Callback(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount)
|
||||||
|
{
|
||||||
|
if (additional_amount > 0) {
|
||||||
|
Uint8 *data = SDL_stack_alloc(Uint8, additional_amount);
|
||||||
|
if (data) {
|
||||||
|
SDL_Callback(userdata, data, additional_amount);
|
||||||
|
SDL_PutAudioStreamData(stream, data, additional_amount);
|
||||||
|
SDL_stack_free(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializes the SDL sound
|
||||||
|
* backend and sets up SDL.
|
||||||
|
*/
|
||||||
|
qboolean
|
||||||
|
SDL_BackendInit(void)
|
||||||
|
{
|
||||||
|
char reqdriver[128];
|
||||||
|
SDL_AudioSpec spec;
|
||||||
|
int samples, tmp, val;
|
||||||
|
|
||||||
|
/* This should never happen,
|
||||||
|
but this is Quake 2 ... */
|
||||||
|
if (snd_inited)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sndbits = (Cvar_Get("sndbits", "16", CVAR_ARCHIVE))->value;
|
||||||
|
int sndfreq = (Cvar_Get("s_khz", "44", CVAR_ARCHIVE))->value;
|
||||||
|
int sndchans = (Cvar_Get("sndchannels", "2", CVAR_ARCHIVE))->value;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
s_sdldriver = (Cvar_Get("s_sdldriver", "directsound", CVAR_ARCHIVE));
|
||||||
|
#elif __linux__
|
||||||
|
s_sdldriver = (Cvar_Get("s_sdldriver", "alsa", CVAR_ARCHIVE));
|
||||||
|
#elif __APPLE__
|
||||||
|
s_sdldriver = (Cvar_Get("s_sdldriver", "CoreAudio", CVAR_ARCHIVE));
|
||||||
|
#else
|
||||||
|
s_sdldriver = (Cvar_Get("s_sdldriver", "dsp", CVAR_ARCHIVE));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
snprintf(reqdriver, sizeof(reqdriver), "%s=%s", "SDL_AUDIODRIVER", s_sdldriver->string);
|
||||||
|
putenv(reqdriver);
|
||||||
|
|
||||||
|
Com_Printf("Starting SDL audio callback.\n");
|
||||||
|
|
||||||
|
if (!SDL_WasInit(SDL_INIT_AUDIO))
|
||||||
|
{
|
||||||
|
if (SDL_Init(SDL_INIT_AUDIO) == -1)
|
||||||
|
{
|
||||||
|
Com_Printf ("Couldn't init SDL audio: %s.\n", SDL_GetError ());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char* drivername = SDL_GetCurrentAudioDriver();
|
||||||
|
if(drivername == NULL)
|
||||||
|
{
|
||||||
|
drivername = "(UNKNOWN)";
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf("SDL audio driver is \"%s\".\n", drivername);
|
||||||
|
|
||||||
|
memset(&samples, '\0', sizeof(samples));
|
||||||
|
|
||||||
|
/* Users are stupid */
|
||||||
|
if ((sndbits != 16) && (sndbits != 8))
|
||||||
|
{
|
||||||
|
sndbits = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sndfreq == 48)
|
||||||
|
{
|
||||||
|
spec.freq = 48000;
|
||||||
|
}
|
||||||
|
else if (sndfreq == 44)
|
||||||
|
{
|
||||||
|
spec.freq = 44100;
|
||||||
|
}
|
||||||
|
else if (sndfreq == 22)
|
||||||
|
{
|
||||||
|
spec.freq = 22050;
|
||||||
|
}
|
||||||
|
else if (sndfreq == 11)
|
||||||
|
{
|
||||||
|
spec.freq = 11025;
|
||||||
|
}
|
||||||
|
|
||||||
|
spec.format = ((sndbits == 16) ? SDL_AUDIO_S16 : SDL_AUDIO_U8);
|
||||||
|
|
||||||
|
if (spec.freq <= 11025)
|
||||||
|
{
|
||||||
|
samples = 256;
|
||||||
|
}
|
||||||
|
else if (spec.freq <= 22050)
|
||||||
|
{
|
||||||
|
samples = 512;
|
||||||
|
}
|
||||||
|
else if (spec.freq <= 44100)
|
||||||
|
{
|
||||||
|
samples = 1024;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
samples = 2048;
|
||||||
|
}
|
||||||
|
|
||||||
|
spec.channels = sndchans;
|
||||||
|
|
||||||
|
/* Okay, let's try our luck */
|
||||||
|
stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec, SDL_SDL3Callback, NULL);
|
||||||
|
if (stream == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("SDL_OpenAudio() failed: %s\n", SDL_GetError());
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This points to the frontend */
|
||||||
|
backend = &sound;
|
||||||
|
|
||||||
|
playpos = 0;
|
||||||
|
backend->samplebits = spec.format & 0xFF;
|
||||||
|
backend->channels = spec.channels;
|
||||||
|
|
||||||
|
tmp = (samples * spec.channels) * 10;
|
||||||
|
|
||||||
|
if (tmp & (tmp - 1))
|
||||||
|
{ /* make it a power of two */
|
||||||
|
val = 1;
|
||||||
|
while (val < tmp)
|
||||||
|
val <<= 1;
|
||||||
|
|
||||||
|
tmp = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
backend->samples = tmp;
|
||||||
|
|
||||||
|
backend->submission_chunk = 1;
|
||||||
|
backend->speed = spec.freq;
|
||||||
|
samplesize = (backend->samples * (backend->samplebits / 8));
|
||||||
|
backend->buffer = calloc(1, samplesize);
|
||||||
|
s_numchannels = MAX_CHANNELS;
|
||||||
|
|
||||||
|
s_underwater->modified = true;
|
||||||
|
s_underwater_gain_hf->modified = true;
|
||||||
|
lpf_initialize(&lpf_context, lpf_default_gain_hf, backend->speed);
|
||||||
|
|
||||||
|
SDL_UpdateScaletable();
|
||||||
|
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||||
|
|
||||||
|
Com_Printf("SDL audio initialized.\n");
|
||||||
|
|
||||||
|
soundtime = 0;
|
||||||
|
snd_inited = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shuts the SDL backend down.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SDL_BackendShutdown(void)
|
||||||
|
{
|
||||||
|
Com_Printf("Closing SDL audio device...\n");
|
||||||
|
SDL_PauseAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||||
|
SDL_DestroyAudioStream(stream);
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
|
free(backend->buffer);
|
||||||
|
backend->buffer = NULL;
|
||||||
|
playpos = samplesize = 0;
|
||||||
|
snd_inited = 0;
|
||||||
|
Com_Printf("SDL audio device shut down.\n");
|
||||||
|
}
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* Initializes the SDL sound
|
* Initializes the SDL sound
|
||||||
* backend and sets up SDL.
|
* backend and sets up SDL.
|
||||||
|
@ -1464,4 +1663,4 @@ SDL_BackendShutdown(void)
|
||||||
snd_inited = 0;
|
snd_inited = 0;
|
||||||
Com_Printf("SDL audio device shut down.\n");
|
Com_Printf("SDL audio device shut down.\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
35
src/client/vid/glimp_sdl.c → src/client/vid/glimp_sdl2.c
Executable file → Normal file
35
src/client/vid/glimp_sdl.c → src/client/vid/glimp_sdl2.c
Executable file → Normal file
|
@ -33,7 +33,7 @@
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_video.h>
|
#include <SDL2/SDL_video.h>
|
||||||
|
|
||||||
int glimp_refreshRate = -1;
|
float glimp_refreshRate = -1.0f;
|
||||||
|
|
||||||
static cvar_t *vid_displayrefreshrate;
|
static cvar_t *vid_displayrefreshrate;
|
||||||
static cvar_t *vid_displayindex;
|
static cvar_t *vid_displayindex;
|
||||||
|
@ -733,35 +733,19 @@ GLimp_GrabInput(qboolean grab)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the current display refresh rate. There're 2 limitations:
|
* Returns the current display refresh rate.
|
||||||
*
|
|
||||||
* * The timing code in frame.c only understands full integers, so
|
|
||||||
* values given by vid_displayrefreshrate are always round up. For
|
|
||||||
* example 59.95 become 60. Rounding up is the better choice for
|
|
||||||
* most users because assuming a too high display refresh rate
|
|
||||||
* avoids micro stuttering caused by missed frames if the vsync
|
|
||||||
* is enabled. The price are small and hard to notice timing
|
|
||||||
* problems.
|
|
||||||
*
|
|
||||||
* * SDL returns only full integers. In most cases they're rounded
|
|
||||||
* up, but in some cases - likely depending on the GPU driver -
|
|
||||||
* they're rounded down. If the value is rounded up, we'll see
|
|
||||||
* some small and nard to notice timing problems. If the value
|
|
||||||
* is rounded down frames will be missed. Both is only relevant
|
|
||||||
* if the vsync is enabled.
|
|
||||||
*/
|
*/
|
||||||
int
|
float
|
||||||
GLimp_GetRefreshRate(void)
|
GLimp_GetRefreshRate(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (vid_displayrefreshrate->value > -1 ||
|
if (vid_displayrefreshrate->value > -1 ||
|
||||||
vid_displayrefreshrate->modified)
|
vid_displayrefreshrate->modified)
|
||||||
{
|
{
|
||||||
glimp_refreshRate = ceil(vid_displayrefreshrate->value);
|
glimp_refreshRate = vid_displayrefreshrate->value;
|
||||||
vid_displayrefreshrate->modified = false;
|
vid_displayrefreshrate->modified = false;
|
||||||
}
|
}
|
||||||
|
else if (glimp_refreshRate == -1)
|
||||||
if (glimp_refreshRate == -1)
|
|
||||||
{
|
{
|
||||||
SDL_DisplayMode mode;
|
SDL_DisplayMode mode;
|
||||||
|
|
||||||
|
@ -835,3 +819,12 @@ GLimp_GetWindowDisplayIndex(void)
|
||||||
{
|
{
|
||||||
return last_display;
|
return last_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
GLimp_GetFrameworkVersion(void)
|
||||||
|
{
|
||||||
|
SDL_version ver;
|
||||||
|
SDL_VERSION(&ver);
|
||||||
|
|
||||||
|
return ver.major;
|
||||||
|
}
|
913
src/client/vid/glimp_sdl3.c
Normal file
913
src/client/vid/glimp_sdl3.c
Normal file
|
@ -0,0 +1,913 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Yamagi Burmeister
|
||||||
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*
|
||||||
|
* This is the client side of the render backend, implemented trough SDL.
|
||||||
|
* The SDL window and related functrion (mouse grap, fullscreen switch)
|
||||||
|
* are implemented here, everything else is in the renderers.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TODO SDL3:
|
||||||
|
* * Bump copyright.
|
||||||
|
* * Do we need to request High DPI modes when vid_highdpiaware > 0?
|
||||||
|
* * `fullscreen` should be an enum to make the code more readable.
|
||||||
|
* * Debug fullscreen handling, maybe refactor it further.
|
||||||
|
* * Check if window size handling is correct.
|
||||||
|
* * Check pointers returned by SDL functions for memory leaks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../../common/header/common.h"
|
||||||
|
#include "header/ref.h"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
float glimp_refreshRate = -1.0f;
|
||||||
|
|
||||||
|
static cvar_t *vid_displayrefreshrate;
|
||||||
|
static cvar_t *vid_displayindex;
|
||||||
|
static cvar_t *vid_highdpiaware;
|
||||||
|
static cvar_t *vid_rate;
|
||||||
|
|
||||||
|
static int last_flags = 0;
|
||||||
|
static int last_display = 0;
|
||||||
|
static int last_position_x = SDL_WINDOWPOS_UNDEFINED;
|
||||||
|
static int last_position_y = SDL_WINDOWPOS_UNDEFINED;
|
||||||
|
static SDL_Window* window = NULL;
|
||||||
|
static qboolean initSuccessful = false;
|
||||||
|
static char **displayindices = NULL;
|
||||||
|
static int num_displays = 0;
|
||||||
|
|
||||||
|
/* Fullscreen modes */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FULLSCREEN_OFF = 0,
|
||||||
|
FULLSCREEN_EXCLUSIVE = 1,
|
||||||
|
FULLSCREEN_DESKTOP = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resets the display index Cvar if out of bounds
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ClampDisplayIndexCvar(void)
|
||||||
|
{
|
||||||
|
if (!vid_displayindex)
|
||||||
|
{
|
||||||
|
// uninitialized render?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vid_displayindex->value < 0 || vid_displayindex->value >= num_displays)
|
||||||
|
{
|
||||||
|
Cvar_SetValue("vid_displayindex", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ClearDisplayIndices(void)
|
||||||
|
{
|
||||||
|
if ( displayindices )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < num_displays; i++ )
|
||||||
|
{
|
||||||
|
free( displayindices[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( displayindices );
|
||||||
|
displayindices = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static qboolean
|
||||||
|
CreateSDLWindow(int flags, int fullscreen, int w, int h)
|
||||||
|
{
|
||||||
|
if (SDL_WINDOWPOS_ISUNDEFINED(last_position_x) || SDL_WINDOWPOS_ISUNDEFINED(last_position_y) || last_position_x < 0 ||last_position_y < 24)
|
||||||
|
{
|
||||||
|
last_position_x = last_position_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY((int)vid_displayindex->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Force the window to minimize when focus is lost. This was the
|
||||||
|
* default behavior until SDL 2.0.12 and changed with 2.0.14.
|
||||||
|
* The windows staying maximized has some odd implications for
|
||||||
|
* window ordering under Windows and some X11 window managers
|
||||||
|
* like kwin. See:
|
||||||
|
* * https://github.com/libsdl-org/SDL/issues/4039
|
||||||
|
* * https://github.com/libsdl-org/SDL/issues/3656 */
|
||||||
|
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "1");
|
||||||
|
|
||||||
|
SDL_PropertiesID props = SDL_CreateProperties();
|
||||||
|
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, "Yamagi Quake II");
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, last_position_x);
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, last_position_y);
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, w);
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, h);
|
||||||
|
SDL_SetNumberProperty(props, "flags", flags);
|
||||||
|
|
||||||
|
window = SDL_CreateWindowWithProperties(props);
|
||||||
|
SDL_DestroyProperties(props);
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
/* save current display as default */
|
||||||
|
if ((last_display = SDL_GetDisplayForWindow(window)) == 0)
|
||||||
|
{
|
||||||
|
/* There are some obscure setups were SDL is
|
||||||
|
unable to get the current display,one X11
|
||||||
|
server with several screen is one of these,
|
||||||
|
so add a fallback to the first display. */
|
||||||
|
last_display = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set requested fullscreen mode. */
|
||||||
|
if (flags & SDL_WINDOW_FULLSCREEN)
|
||||||
|
{
|
||||||
|
/* SDLs behavior changed between SDL 2 and SDL 3: In SDL 2
|
||||||
|
the fullscreen window could be set with whatever mode
|
||||||
|
was requested. In SDL 3 the fullscreen window is always
|
||||||
|
created at desktop resolution. If a fullscreen window
|
||||||
|
is requested, we can't do anything else and are done here. */
|
||||||
|
if (fullscreen == FULLSCREEN_DESKTOP)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise try to find a mode near the requested one and
|
||||||
|
switch to it in exclusive fullscreen mode. */
|
||||||
|
/* TODO SDL3: Leak? */
|
||||||
|
const SDL_DisplayMode *closestMode = SDL_GetClosestFullscreenDisplayMode(last_display, w, h, vid_rate->value, false);
|
||||||
|
|
||||||
|
if (closestMode == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("SDL was unable to find a mode close to %ix%i@%f\n", w, h, vid_rate->value);
|
||||||
|
|
||||||
|
if (vid_rate->value != 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Retrying with desktop refresh rate\n");
|
||||||
|
closestMode = SDL_GetClosestFullscreenDisplayMode(last_display, w, h, 0, false);
|
||||||
|
|
||||||
|
if (closestMode != NULL)
|
||||||
|
{
|
||||||
|
Cvar_SetValue("vid_rate", 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Com_Printf("SDL was unable to find a mode close to %ix%i@0\n", w, h);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf("User requested %ix%i@%f, setting closest mode %ix%i@%f\n",
|
||||||
|
w, h, vid_rate->value, closestMode->w, closestMode->h , closestMode->refresh_rate);
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO SDL3: Same code is in InitGraphics(), refactor into
|
||||||
|
* a function? */
|
||||||
|
if (SDL_SetWindowFullscreenMode(window, closestMode) < 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't set closest mode: %s\n", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_SetWindowFullscreen(window, true) < 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't switch to exclusive fullscreen: %s\n", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = SDL_SyncWindow(window);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Synchronizing window state timed out\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (ret < 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't synchronize window state: %s\n", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Com_Printf("Creating window failed: %s\n", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
GetFullscreenType()
|
||||||
|
{
|
||||||
|
if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN)
|
||||||
|
{
|
||||||
|
/* TODO SDL3: Leak? */
|
||||||
|
const SDL_DisplayMode *fsmode = SDL_GetWindowFullscreenMode(window);
|
||||||
|
|
||||||
|
if (fsmode != NULL)
|
||||||
|
{
|
||||||
|
return FULLSCREEN_EXCLUSIVE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FULLSCREEN_DESKTOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FULLSCREEN_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qboolean
|
||||||
|
GetWindowSize(int* w, int* h)
|
||||||
|
{
|
||||||
|
if (window == NULL || w == NULL || h == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_GetWindowSize(window, w, h) < 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't get window size: %s\n", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
InitDisplayIndices()
|
||||||
|
{
|
||||||
|
displayindices = malloc((num_displays + 1) * sizeof(char *));
|
||||||
|
|
||||||
|
for ( int i = 0; i < num_displays; i++ )
|
||||||
|
{
|
||||||
|
/* There are a maximum of 10 digits in 32 bit int + 1 for the NULL terminator. */
|
||||||
|
displayindices[ i ] = malloc(11 * sizeof( char ));
|
||||||
|
YQ2_COM_CHECK_OOM(displayindices[i], "malloc()", 11 * sizeof( char ))
|
||||||
|
|
||||||
|
snprintf( displayindices[ i ], 11, "%d", i );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The last entry is NULL to indicate the list of strings ends. */
|
||||||
|
displayindices[ num_displays ] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lists all available display modes.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
PrintDisplayModes(void)
|
||||||
|
{
|
||||||
|
int curdisplay;
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
/* Called without a windows, list modes
|
||||||
|
from the first display. This is the
|
||||||
|
primary display and likely the one the
|
||||||
|
game will run on. */
|
||||||
|
curdisplay = SDL_GetPrimaryDisplay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise use the window were the window
|
||||||
|
is displayed. There are some obscure
|
||||||
|
setups were this can fail - one X11 server
|
||||||
|
with several screen is one of these - so
|
||||||
|
add a fallback to the first display. */
|
||||||
|
if ((curdisplay = SDL_GetDisplayForWindow(window)) == 0)
|
||||||
|
{
|
||||||
|
curdisplay = SDL_GetPrimaryDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int nummodes = 0;
|
||||||
|
const SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(curdisplay, &nummodes);
|
||||||
|
|
||||||
|
if (modes)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nummodes; ++i)
|
||||||
|
{
|
||||||
|
const SDL_DisplayMode *mode = modes[i];
|
||||||
|
Com_Printf(" - Mode %2i: %ix%i@%.2f\n", i, mode->w, mode->h, mode->refresh_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(modes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't get display modes: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets the window icon
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
SetSDLIcon()
|
||||||
|
{
|
||||||
|
#include "icon/q2icon64.h" // 64x64 32 Bit
|
||||||
|
|
||||||
|
/* these masks are needed to tell SDL_CreateRGBSurface(From)
|
||||||
|
to assume the data it gets is byte-wise RGB(A) data */
|
||||||
|
Uint32 rmask, gmask, bmask, amask;
|
||||||
|
|
||||||
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||||
|
int shift = (q2icon64.bytes_per_pixel == 3) ? 8 : 0;
|
||||||
|
rmask = 0xff000000 >> shift;
|
||||||
|
gmask = 0x00ff0000 >> shift;
|
||||||
|
bmask = 0x0000ff00 >> shift;
|
||||||
|
amask = 0x000000ff >> shift;
|
||||||
|
#else /* little endian, like x86 */
|
||||||
|
rmask = 0x000000ff;
|
||||||
|
gmask = 0x0000ff00;
|
||||||
|
bmask = 0x00ff0000;
|
||||||
|
amask = (q2icon64.bytes_per_pixel == 3) ? 0 : 0xff000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_Surface* icon = SDL_CreateSurfaceFrom((void *)q2icon64.pixel_data, q2icon64.width, q2icon64.height, q2icon64.bytes_per_pixel * q2icon64.width, SDL_GetPixelFormatEnumForMasks(q2icon64.bytes_per_pixel * 8, rmask, gmask, bmask, amask));
|
||||||
|
SDL_SetWindowIcon(window, icon);
|
||||||
|
SDL_DestroySurface(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: We need a header for this.
|
||||||
|
// Maybe we could put it in vid.h.
|
||||||
|
void GLimp_GrabInput(qboolean grab);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shuts the SDL render backend down
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ShutdownGraphics(void)
|
||||||
|
{
|
||||||
|
ClampDisplayIndexCvar();
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
/* save current display as default */
|
||||||
|
last_display = SDL_GetDisplayForWindow(window);
|
||||||
|
|
||||||
|
/* or if current display isn't the desired default */
|
||||||
|
if (last_display != vid_displayindex->value) {
|
||||||
|
last_position_x = last_position_y = SDL_WINDOWPOS_UNDEFINED;
|
||||||
|
last_display = vid_displayindex->value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_GetWindowPosition(window,
|
||||||
|
&last_position_x, &last_position_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cleanly ungrab input (needs window) */
|
||||||
|
GLimp_GrabInput(false);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
|
||||||
|
window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure that after vid_restart the refreshrate will be queried from SDL2 again.
|
||||||
|
glimp_refreshRate = -1;
|
||||||
|
|
||||||
|
initSuccessful = false; // not initialized anymore
|
||||||
|
}
|
||||||
|
// --------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializes the SDL video subsystem. Must
|
||||||
|
* be called before anything else.
|
||||||
|
*/
|
||||||
|
qboolean
|
||||||
|
GLimp_Init(void)
|
||||||
|
{
|
||||||
|
vid_displayrefreshrate = Cvar_Get("vid_displayrefreshrate", "-1", CVAR_ARCHIVE);
|
||||||
|
vid_displayindex = Cvar_Get("vid_displayindex", "0", CVAR_ARCHIVE);
|
||||||
|
vid_highdpiaware = Cvar_Get("vid_highdpiaware", "1", CVAR_ARCHIVE);
|
||||||
|
vid_rate = Cvar_Get("vid_rate", "-1", CVAR_ARCHIVE);
|
||||||
|
|
||||||
|
if (!SDL_WasInit(SDL_INIT_VIDEO))
|
||||||
|
{
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) == -1)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't init SDL video: %s.\n", SDL_GetError());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Version version;
|
||||||
|
|
||||||
|
SDL_GetVersion(&version);
|
||||||
|
Com_Printf("-------- vid initialization --------\n");
|
||||||
|
Com_Printf("SDL version is: %i.%i.%i\n", (int)version.major, (int)version.minor, (int)version.patch);
|
||||||
|
Com_Printf("SDL video driver is \"%s\".\n", SDL_GetCurrentVideoDriver());
|
||||||
|
|
||||||
|
SDL_DisplayID *displays;
|
||||||
|
if ((displays = SDL_GetDisplays(&num_displays)) == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't get number of displays: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_free(displays);
|
||||||
|
}
|
||||||
|
|
||||||
|
InitDisplayIndices();
|
||||||
|
ClampDisplayIndexCvar();
|
||||||
|
Com_Printf("SDL display modes:\n");
|
||||||
|
|
||||||
|
PrintDisplayModes();
|
||||||
|
Com_Printf("------------------------------------\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shuts the SDL video subsystem down. Must
|
||||||
|
* be called after evrything's finished and
|
||||||
|
* clean up.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
GLimp_Shutdown(void)
|
||||||
|
{
|
||||||
|
ShutdownGraphics();
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
ClearDisplayIndices();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine if we want to be high dpi aware. If
|
||||||
|
* we are we must scale ourself. If we are not the
|
||||||
|
* compositor might scale us.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
Glimp_DetermineHighDPISupport(int flags)
|
||||||
|
{
|
||||||
|
/* Make sure that high dpi is never set when we don't want it. */
|
||||||
|
flags &= ~SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||||
|
|
||||||
|
if (vid_highdpiaware->value == 0)
|
||||||
|
{
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle high dpi awareness based on the render backend.
|
||||||
|
SDL doesn't support high dpi awareness for all backends
|
||||||
|
and the quality and behavior differs between them. */
|
||||||
|
if ((strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0))
|
||||||
|
{
|
||||||
|
flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (Re)initializes the actual window.
|
||||||
|
*/
|
||||||
|
qboolean
|
||||||
|
GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
int curWidth, curHeight;
|
||||||
|
int width = *pwidth;
|
||||||
|
int height = *pheight;
|
||||||
|
unsigned int fs_flag = 0;
|
||||||
|
|
||||||
|
if (fullscreen == FULLSCREEN_EXCLUSIVE || fullscreen == FULLSCREEN_DESKTOP)
|
||||||
|
{
|
||||||
|
fs_flag = SDL_WINDOW_FULLSCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only do this if we already have a working window and a fully
|
||||||
|
initialized rendering backend GLimp_InitGraphics() is also
|
||||||
|
called when recovering if creating GL context fails or the
|
||||||
|
one we got is unusable. */
|
||||||
|
if (initSuccessful && GetWindowSize(&curWidth, &curHeight)
|
||||||
|
&& (curWidth == width) && (curHeight == height))
|
||||||
|
{
|
||||||
|
/* TODO SDL3: Leak? */
|
||||||
|
const SDL_DisplayMode *closestMode = NULL;
|
||||||
|
|
||||||
|
/* If we want fullscreen, but aren't */
|
||||||
|
if (GetFullscreenType())
|
||||||
|
{
|
||||||
|
if (fullscreen == FULLSCREEN_EXCLUSIVE)
|
||||||
|
{
|
||||||
|
closestMode = SDL_GetClosestFullscreenDisplayMode(last_display, width, height, vid_rate->value, false);
|
||||||
|
|
||||||
|
if (closestMode == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("SDL was unable to find a mode close to %ix%i@%f\n", width, height, vid_rate->value);
|
||||||
|
|
||||||
|
if (vid_rate->value != 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Retrying with desktop refresh rate\n");
|
||||||
|
closestMode = SDL_GetClosestFullscreenDisplayMode(last_display, width, height, 0, false);
|
||||||
|
|
||||||
|
if (closestMode != NULL)
|
||||||
|
{
|
||||||
|
Cvar_SetValue("vid_rate", 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Com_Printf("SDL was unable to find a mode close to %ix%i@0\n", width, height);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fullscreen == FULLSCREEN_DESKTOP)
|
||||||
|
{
|
||||||
|
/* Fullscreen window */
|
||||||
|
closestMode = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_SetWindowFullscreenMode(window, closestMode) < 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't set fullscreen modmode: %s\n", SDL_GetError());
|
||||||
|
Cvar_SetValue("vid_fullscreen", 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SDL_SetWindowFullscreen(window, true) < 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't switch to exclusive fullscreen: %s\n", SDL_GetError());
|
||||||
|
Cvar_SetValue("vid_fullscreen", 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ret = SDL_SyncWindow(window);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Synchronizing window state timed out\n");
|
||||||
|
Cvar_SetValue("vid_fullscreen", 0);
|
||||||
|
}
|
||||||
|
else if (ret < 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't synchronize window state: %s\n", SDL_GetError());
|
||||||
|
Cvar_SetValue("vid_fullscreen", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cvar_SetValue("vid_fullscreen", fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Are we now? */
|
||||||
|
if (GetFullscreenType())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the surface used? */
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
re.ShutdownContext();
|
||||||
|
ShutdownGraphics();
|
||||||
|
|
||||||
|
window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(last_flags != -1 && (last_flags & SDL_WINDOW_OPENGL))
|
||||||
|
{
|
||||||
|
/* Reset SDL. */
|
||||||
|
SDL_GL_ResetAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let renderer prepare things (set OpenGL attributes).
|
||||||
|
FIXME: This is no longer necessary, the renderer
|
||||||
|
could and should pass the flags when calling this
|
||||||
|
function. */
|
||||||
|
flags = re.PrepareForWindow();
|
||||||
|
|
||||||
|
if (flags == -1)
|
||||||
|
{
|
||||||
|
/* It's PrepareForWindow() job to log an error */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs_flag)
|
||||||
|
{
|
||||||
|
flags |= fs_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for high dpi support. */
|
||||||
|
flags = Glimp_DetermineHighDPISupport(flags);
|
||||||
|
|
||||||
|
/* Mkay, now the hard work. Let's create the window. */
|
||||||
|
cvar_t *gl_msaa_samples = Cvar_Get("r_msaa_samples", "0", CVAR_ARCHIVE);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!CreateSDLWindow(flags, fullscreen, width, height))
|
||||||
|
{
|
||||||
|
if((flags & SDL_WINDOW_OPENGL) && gl_msaa_samples->value)
|
||||||
|
{
|
||||||
|
int msaa_samples = gl_msaa_samples->value;
|
||||||
|
|
||||||
|
if (msaa_samples > 0)
|
||||||
|
{
|
||||||
|
msaa_samples /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf("SDL SetVideoMode failed: %s\n", SDL_GetError());
|
||||||
|
Com_Printf("Reverting to %s r_mode %i (%ix%i) with %dx MSAA.\n",
|
||||||
|
(flags & fs_flag) ? "fullscreen" : "windowed",
|
||||||
|
(int) Cvar_VariableValue("r_mode"), width, height,
|
||||||
|
msaa_samples);
|
||||||
|
|
||||||
|
/* Try to recover */
|
||||||
|
Cvar_SetValue("r_msaa_samples", msaa_samples);
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,
|
||||||
|
msaa_samples > 0 ? 1 : 0);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,
|
||||||
|
msaa_samples);
|
||||||
|
}
|
||||||
|
else if (width != 640 || height != 480 || (flags & fs_flag))
|
||||||
|
{
|
||||||
|
Com_Printf("SDL SetVideoMode failed: %s\n", SDL_GetError());
|
||||||
|
Com_Printf("Reverting to windowed r_mode 4 (640x480).\n");
|
||||||
|
|
||||||
|
/* Try to recover */
|
||||||
|
Cvar_SetValue("r_mode", 4);
|
||||||
|
Cvar_SetValue("vid_fullscreen", 0);
|
||||||
|
Cvar_SetValue("vid_rate", -1);
|
||||||
|
|
||||||
|
fullscreen = FULLSCREEN_OFF;
|
||||||
|
*pwidth = width = 640;
|
||||||
|
*pheight = height = 480;
|
||||||
|
flags &= ~fs_flag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Com_Printf("Failed to revert to r_mode 4. Will try another render backend...\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last_flags = flags;
|
||||||
|
|
||||||
|
/* Now that we've got a working window print it's mode. */
|
||||||
|
int curdisplay;
|
||||||
|
if ((curdisplay = SDL_GetDisplayForWindow(window)) == 0)
|
||||||
|
{
|
||||||
|
/* There are some obscure setups were SDL is
|
||||||
|
unable to get the current display,one X11
|
||||||
|
server with several screen is one of these,
|
||||||
|
so add a fallback to the first display. */
|
||||||
|
curdisplay = SDL_GetPrimaryDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
const SDL_DisplayMode *mode;
|
||||||
|
if ((mode = SDL_GetCurrentDisplayMode(curdisplay)) == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't get current display mode: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Com_Printf("Real display mode: %ix%i@%.2f\n", mode->w, mode->h, mode->refresh_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize rendering context. */
|
||||||
|
if (!re.InitContext(window))
|
||||||
|
{
|
||||||
|
/* InitContext() should have logged an error. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We need the actual drawable size for things like the
|
||||||
|
console, the menus, etc. This might be different to
|
||||||
|
the resolution due to high dpi awareness.
|
||||||
|
|
||||||
|
The fullscreen window is special. We want it to fill
|
||||||
|
the screen when native resolution is requestes, all
|
||||||
|
other cases should look broken. */
|
||||||
|
if (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY)
|
||||||
|
{
|
||||||
|
if (fullscreen != FULLSCREEN_DESKTOP)
|
||||||
|
{
|
||||||
|
re.GetDrawableSize(&viddef.width, &viddef.height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cvar_t *r_mode = Cvar_Get("r_mode", "4", 0);
|
||||||
|
|
||||||
|
if (r_mode->value == -2 )
|
||||||
|
{
|
||||||
|
re.GetDrawableSize(&viddef.width, &viddef.height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* User likes it broken. */
|
||||||
|
viddef.width = *pwidth;
|
||||||
|
viddef.height = *pheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Another bug or design failure in SDL: When we are
|
||||||
|
not high dpi aware the drawable size returned by
|
||||||
|
SDL may be too small. It seems like the window
|
||||||
|
decoration are taken into account when they shouldn't.
|
||||||
|
It can be seen when creating a fullscreen window.
|
||||||
|
|
||||||
|
Work around that by always using the resolution and
|
||||||
|
not the drawable size when we are not high dpi aware. */
|
||||||
|
viddef.width = *pwidth;
|
||||||
|
viddef.height = *pheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf("Drawable size: %ix%i\n", viddef.width, viddef.height);
|
||||||
|
|
||||||
|
/* Set the window icon - For SDL2, this must be done after creating the window */
|
||||||
|
SetSDLIcon();
|
||||||
|
|
||||||
|
/* No cursor */
|
||||||
|
SDL_ShowCursor();
|
||||||
|
|
||||||
|
initSuccessful = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shuts the window down.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
GLimp_ShutdownGraphics(void)
|
||||||
|
{
|
||||||
|
SDL_GL_ResetAttributes();
|
||||||
|
ShutdownGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (Un)grab Input
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
GLimp_GrabInput(qboolean grab)
|
||||||
|
{
|
||||||
|
if(window != NULL)
|
||||||
|
{
|
||||||
|
SDL_SetWindowMouseGrab(window, grab ? SDL_TRUE : SDL_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SDL_SetRelativeMouseMode(grab ? SDL_TRUE : SDL_FALSE) < 0)
|
||||||
|
{
|
||||||
|
Com_Printf("WARNING: Setting Relative Mousemode failed, reason: %s\n", SDL_GetError());
|
||||||
|
Com_Printf(" You should probably update to SDL 2.0.3 or newer!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the current display refresh rate.
|
||||||
|
*/
|
||||||
|
float
|
||||||
|
GLimp_GetRefreshRate(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (vid_displayrefreshrate->value > -1 ||
|
||||||
|
vid_displayrefreshrate->modified)
|
||||||
|
{
|
||||||
|
glimp_refreshRate = vid_displayrefreshrate->value;
|
||||||
|
vid_displayrefreshrate->modified = false;
|
||||||
|
}
|
||||||
|
else if (glimp_refreshRate == -1)
|
||||||
|
{
|
||||||
|
const SDL_DisplayMode *mode;
|
||||||
|
int curdisplay;
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
/* This is paranoia. This function should only be
|
||||||
|
called if there is a working window. Otherwise
|
||||||
|
things will likely break somewhere else in the
|
||||||
|
client. */
|
||||||
|
curdisplay = SDL_GetPrimaryDisplay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((curdisplay = SDL_GetDisplayForWindow(window)) == 0)
|
||||||
|
{
|
||||||
|
/* There are some obscure setups were SDL is
|
||||||
|
unable to get the current display,one X11
|
||||||
|
server with several screen is one of these,
|
||||||
|
so add a fallback to the first display. */
|
||||||
|
curdisplay = SDL_GetPrimaryDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode = SDL_GetCurrentDisplayMode(curdisplay)) == NULL)
|
||||||
|
{
|
||||||
|
printf("Couldn't get display refresh rate: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glimp_refreshRate = mode->refresh_rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return glimp_refreshRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detect current desktop mode
|
||||||
|
*/
|
||||||
|
qboolean
|
||||||
|
GLimp_GetDesktopMode(int *pwidth, int *pheight)
|
||||||
|
{
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
/* Renderers call into this function before the
|
||||||
|
window is created. This could be refactored
|
||||||
|
by passing the mode and not the geometry from
|
||||||
|
the renderer to GLimp_InitGraphics(), however
|
||||||
|
that would break the renderer API. */
|
||||||
|
last_display = SDL_GetPrimaryDisplay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* save current display as default */
|
||||||
|
if ((last_display = SDL_GetDisplayForWindow(window)) == 0)
|
||||||
|
{
|
||||||
|
/* There are some obscure setups were SDL is
|
||||||
|
unable to get the current display,one X11
|
||||||
|
server with several screen is one of these,
|
||||||
|
so add a fallback to the first display. */
|
||||||
|
last_display = SDL_GetPrimaryDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GetWindowPosition(window, &last_position_x, &last_position_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SDL_DisplayMode *mode;
|
||||||
|
|
||||||
|
if ((mode = SDL_GetCurrentDisplayMode(last_display)) == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("Couldn't detect default desktop mode: %s\n", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pwidth = mode->w;
|
||||||
|
*pheight = mode->h;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char**
|
||||||
|
GLimp_GetDisplayIndices(void)
|
||||||
|
{
|
||||||
|
return (const char**)displayindices;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
GLimp_GetNumVideoDisplays(void)
|
||||||
|
{
|
||||||
|
return num_displays;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
GLimp_GetWindowDisplayIndex(void)
|
||||||
|
{
|
||||||
|
return last_display;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
GLimp_GetFrameworkVersion(void)
|
||||||
|
{
|
||||||
|
SDL_Version ver;
|
||||||
|
SDL_VERSION(&ver);
|
||||||
|
|
||||||
|
return ver.major;
|
||||||
|
}
|
|
@ -125,7 +125,7 @@ typedef enum {
|
||||||
} ref_restart_t;
|
} ref_restart_t;
|
||||||
|
|
||||||
// FIXME: bump API_VERSION?
|
// FIXME: bump API_VERSION?
|
||||||
#define API_VERSION 6
|
#define API_VERSION 7
|
||||||
#define EXPORT
|
#define EXPORT
|
||||||
#define IMPORT
|
#define IMPORT
|
||||||
|
|
||||||
|
@ -137,6 +137,11 @@ typedef struct
|
||||||
// if api_version is different, the dll cannot be used
|
// if api_version is different, the dll cannot be used
|
||||||
int api_version;
|
int api_version;
|
||||||
|
|
||||||
|
// if framework_version is different, the dll cannot be used
|
||||||
|
// necessary because differend SDL major version cannot be
|
||||||
|
// mixed.
|
||||||
|
int framework_version;
|
||||||
|
|
||||||
// called when the library is loaded
|
// called when the library is loaded
|
||||||
qboolean (EXPORT *Init) (void);
|
qboolean (EXPORT *Init) (void);
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ void VID_MenuDraw(void);
|
||||||
const char *VID_MenuKey(int);
|
const char *VID_MenuKey(int);
|
||||||
|
|
||||||
// Stuff provided by platform backend.
|
// Stuff provided by platform backend.
|
||||||
extern int glimp_refreshRate;
|
extern float glimp_refreshRate;
|
||||||
|
|
||||||
const char **GLimp_GetDisplayIndices(void);
|
const char **GLimp_GetDisplayIndices(void);
|
||||||
int GLimp_GetWindowDisplayIndex(void);
|
int GLimp_GetWindowDisplayIndex(void);
|
||||||
|
@ -64,7 +64,8 @@ void GLimp_Shutdown(void);
|
||||||
qboolean GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight);
|
qboolean GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight);
|
||||||
void GLimp_ShutdownGraphics(void);
|
void GLimp_ShutdownGraphics(void);
|
||||||
void GLimp_GrabInput(qboolean grab);
|
void GLimp_GrabInput(qboolean grab);
|
||||||
int GLimp_GetRefreshRate(void);
|
float GLimp_GetRefreshRate(void);
|
||||||
qboolean GLimp_GetDesktopMode(int *pwidth, int *pheight);
|
qboolean GLimp_GetDesktopMode(int *pwidth, int *pheight);
|
||||||
|
int GLimp_GetFrameworkVersion(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -456,9 +456,17 @@ VID_LoadRenderer(void)
|
||||||
// Let's check if we've got a compatible renderer.
|
// Let's check if we've got a compatible renderer.
|
||||||
if (re.api_version != API_VERSION)
|
if (re.api_version != API_VERSION)
|
||||||
{
|
{
|
||||||
|
Com_Printf("%s has incompatible api_version %d!\n", reflib_name, re.api_version);
|
||||||
|
|
||||||
VID_ShutdownRenderer();
|
VID_ShutdownRenderer();
|
||||||
|
|
||||||
Com_Printf("%s has incompatible api_version %d!\n", reflib_name, re.api_version);
|
return false;
|
||||||
|
}
|
||||||
|
else if (re.framework_version != GLimp_GetFrameworkVersion())
|
||||||
|
{
|
||||||
|
Com_Printf("%s has incompatible sdl_version %d!\n", reflib_name, re.framework_version);
|
||||||
|
|
||||||
|
VID_ShutdownRenderer();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -525,8 +533,9 @@ VID_CheckChanges(void)
|
||||||
// Mkay, let's try our luck.
|
// Mkay, let's try our luck.
|
||||||
while (!VID_LoadRenderer())
|
while (!VID_LoadRenderer())
|
||||||
{
|
{
|
||||||
// We try: custom -> gl3 -> gl1 -> soft.
|
// We try: custom -> gl3 -> gles3 -> gl1 -> soft.
|
||||||
if ((strcmp(vid_renderer->string, "gl3") != 0) &&
|
if ((strcmp(vid_renderer->string, "gl3") != 0) &&
|
||||||
|
(strcmp(vid_renderer->string, "gles3") != 0) &&
|
||||||
(strcmp(vid_renderer->string, "gl1") != 0) &&
|
(strcmp(vid_renderer->string, "gl1") != 0) &&
|
||||||
(strcmp(vid_renderer->string, "soft") != 0))
|
(strcmp(vid_renderer->string, "soft") != 0))
|
||||||
{
|
{
|
||||||
|
@ -534,6 +543,11 @@ VID_CheckChanges(void)
|
||||||
Cvar_Set("vid_renderer", "gl3");
|
Cvar_Set("vid_renderer", "gl3");
|
||||||
}
|
}
|
||||||
else if (strcmp(vid_renderer->string, "gl3") == 0)
|
else if (strcmp(vid_renderer->string, "gl3") == 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Retrying with gles3...\n");
|
||||||
|
Cvar_Set("vid_renderer", "gles");
|
||||||
|
}
|
||||||
|
else if (strcmp(vid_renderer->string, "gles3") == 0)
|
||||||
{
|
{
|
||||||
Com_Printf("Retrying with gl1...\n");
|
Com_Printf("Retrying with gl1...\n");
|
||||||
Cvar_Set("vid_renderer", "gl1");
|
Cvar_Set("vid_renderer", "gl1");
|
||||||
|
@ -569,7 +583,7 @@ VID_Init(void)
|
||||||
// Console variables
|
// Console variables
|
||||||
vid_gamma = Cvar_Get("vid_gamma", "1.0", CVAR_ARCHIVE);
|
vid_gamma = Cvar_Get("vid_gamma", "1.0", CVAR_ARCHIVE);
|
||||||
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
|
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
|
||||||
vid_renderer = Cvar_Get("vid_renderer", "gl1", CVAR_ARCHIVE);
|
vid_renderer = Cvar_Get("vid_renderer", "gl3", CVAR_ARCHIVE);
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
Cmd_AddCommand("vid_restart", VID_Restart_f);
|
Cmd_AddCommand("vid_restart", VID_Restart_f);
|
||||||
|
|
|
@ -53,7 +53,7 @@ cvar_t *showtrace;
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
#ifndef DEDICATED_ONLY
|
#ifndef DEDICATED_ONLY
|
||||||
int GLimp_GetRefreshRate(void);
|
float GLimp_GetRefreshRate(void);
|
||||||
qboolean R_IsVSyncActive(void);
|
qboolean R_IsVSyncActive(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -570,7 +570,7 @@ Qcommon_Frame(int usec)
|
||||||
// Calculate target and renderframerate.
|
// Calculate target and renderframerate.
|
||||||
if (R_IsVSyncActive())
|
if (R_IsVSyncActive())
|
||||||
{
|
{
|
||||||
int refreshrate = GLimp_GetRefreshRate();
|
float refreshrate = GLimp_GetRefreshRate();
|
||||||
|
|
||||||
// using refreshRate - 2, because targeting a value slightly below the
|
// using refreshRate - 2, because targeting a value slightly below the
|
||||||
// (possibly not 100% correctly reported) refreshRate would introduce jittering, so only
|
// (possibly not 100% correctly reported) refreshRate would introduce jittering, so only
|
||||||
|
|
Loading…
Reference in a new issue