mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-20 10:53:22 +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) #
|
||||
# #
|
||||
# Base dependencies: #
|
||||
# - SDL 2.0 #
|
||||
# - SDL 2 or SDL 3 #
|
||||
# - libGL #
|
||||
# - Vulkan headers #
|
||||
# #
|
||||
|
@ -56,6 +56,9 @@ WITH_AVCODEC:=yes
|
|||
# or libopenal.so. Not supported on Windows.
|
||||
WITH_RPATH:=yes
|
||||
|
||||
# Builds with SDL 3 instead of SDL 2.
|
||||
WITH_SDL3:=no
|
||||
|
||||
# Enable systemwide installation of game assets.
|
||||
WITH_SYSTEMWIDE:=no
|
||||
|
||||
|
@ -279,7 +282,12 @@ endif
|
|||
# ----------
|
||||
|
||||
# Extra CFLAGS for SDL.
|
||||
ifeq ($(WITH_SDL3),yes)
|
||||
SDLCFLAGS := $(shell pkgconf --cflags sdl3)
|
||||
SDLCFLAGS += -DUSE_SDL3
|
||||
else
|
||||
SDLCFLAGS := $(shell sdl2-config --cflags)
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
|
@ -356,11 +364,19 @@ endif
|
|||
# ----------
|
||||
|
||||
# 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)
|
||||
SDLLDFLAGS := -lSDL2
|
||||
else # not Darwin
|
||||
else
|
||||
SDLLDFLAGS := $(shell sdl2-config --libs)
|
||||
endif # Darwin
|
||||
endif
|
||||
endif
|
||||
|
||||
# The renderer libs don't need libSDL2main, libmingw32 or -mwindows.
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
|
@ -398,6 +414,7 @@ config:
|
|||
@echo "WITH_OPENAL = $(WITH_OPENAL)"
|
||||
@echo "WITH_AVCODEC = $(WITH_AVCODEC)"
|
||||
@echo "WITH_RPATH = $(WITH_RPATH)"
|
||||
@echo "WITH_SDL3 = $(WITH_SDL3)"
|
||||
@echo "WITH_SYSTEMWIDE = $(WITH_SYSTEMWIDE)"
|
||||
@echo "WITH_SYSTEMDIR = $(WITH_SYSTEMDIR)"
|
||||
@echo "============================"
|
||||
|
@ -971,17 +988,15 @@ CLIENT_OBJS_ := \
|
|||
src/client/cl_view.o \
|
||||
src/client/curl/download.o \
|
||||
src/client/curl/qcurl.o \
|
||||
src/client/input/sdl.o \
|
||||
src/client/menu/menu.o \
|
||||
src/client/menu/qmenu.o \
|
||||
src/client/menu/videomenu.o \
|
||||
src/client/sound/sdl.o \
|
||||
src/client/sound/ogg.o \
|
||||
src/client/sound/openal.o \
|
||||
src/client/sound/qal.o \
|
||||
src/client/sound/sdl.o \
|
||||
src/client/sound/sound.o \
|
||||
src/client/sound/wave.o \
|
||||
src/client/vid/glimp_sdl.o \
|
||||
src/client/vid/vid.o \
|
||||
src/common/argproc.o \
|
||||
src/common/clientserver.o \
|
||||
|
@ -1020,6 +1035,16 @@ CLIENT_OBJS_ := \
|
|||
src/server/sv_user.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)
|
||||
CLIENT_OBJS_ += \
|
||||
src/backends/windows/main.o \
|
||||
|
@ -1368,7 +1393,7 @@ endif
|
|||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
release/q2ded.exe : $(SERVER_OBJS) icon
|
||||
@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 $@
|
||||
else
|
||||
release/q2ded : $(SERVER_OBJS)
|
||||
|
|
|
@ -408,12 +408,14 @@ Set `0` by default.
|
|||
has 59.95hz.
|
||||
|
||||
* **vid_gamma**: The value used for gamma correction. Higher values look
|
||||
brighter. The OpenGL 1.4 and software renderers use "Hardware Gamma",
|
||||
setting the Gamma of the whole screen to this value in realtime
|
||||
(except on MacOS where it's applied to textures on load and thus needs
|
||||
a `vid_restart` after changing). The OpenGL 3.2 and Vulkan renderers
|
||||
apply this to the window in realtime via shaders (on all platforms).
|
||||
This is also set by the brightness slider in the video menu.
|
||||
brighter. The OpenGL 3.2 OpenGL ES3 and Vulkan renderers apply this to
|
||||
the window in realtime via shaders (on all platforms). When the game
|
||||
is build against SDL2, the OpenGL 1.4 renderer uses "hardware gamma"
|
||||
when available, increasing the brightness of the whole screen. On
|
||||
MacOS the gamma is applied only at renderer start, so a `vid_restart`
|
||||
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
|
||||
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 is 1.25 and the user requests 1920x1080. The client
|
||||
will render at 1920\*1.25x1080\*1.25=2400x1350.
|
||||
When set to `0` (the default) the client leaves the decision if the
|
||||
window should be scaled to the underlying compositor. Scaling applied
|
||||
by the compositor may introduce blur and sluggishness.
|
||||
When set to `0` the client leaves the decision if the window should
|
||||
be scaled to the underlying compositor. Scaling applied by the
|
||||
compositor may introduce blur and sluggishness.
|
||||
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`)
|
||||
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`.
|
||||
|
||||
* **vid_renderer**: Selects the renderer library. Possible options are
|
||||
`gl1` (the default) for the old OpenGL 1.4 renderer, `gl3` for the
|
||||
OpenGL 3.2 renderer, `gles3` for the OpenGL ES3 renderer
|
||||
and `soft` for the software renderer.
|
||||
`gl3` (the default) for the OpenGL 3.2 renderer, `gles3` for the
|
||||
OpenGL ES3 renderer, gl1 for the original OpenGL 1.4 renderer and
|
||||
`soft` for the software renderer.
|
||||
|
||||
* **r_dynamic**: Enamble dynamic light in gl1 and vk renders.
|
||||
|
||||
|
|
|
@ -26,8 +26,16 @@
|
|||
*/
|
||||
|
||||
#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_main.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "../../common/header/common.h"
|
||||
|
||||
|
|
|
@ -701,7 +701,7 @@ IN_Update(void)
|
|||
{
|
||||
// make sure GLimp_GetRefreshRate() will query from SDL again - the window might
|
||||
// be on another display now!
|
||||
glimp_refreshRate = -1;
|
||||
glimp_refreshRate = -1.0f;
|
||||
}
|
||||
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;
|
||||
|
||||
refexport.api_version = API_VERSION;
|
||||
refexport.framework_version = RI_GetSDLVersion();
|
||||
|
||||
refexport.Init = RI_Init;
|
||||
refexport.Shutdown = RI_Shutdown;
|
||||
|
|
|
@ -27,7 +27,11 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#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;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -164,6 +181,10 @@ void RI_SetVsync(void)
|
|||
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);
|
||||
|
||||
Uint16 ramp[256];
|
||||
|
@ -173,6 +194,7 @@ RI_UpdateGamma(void)
|
|||
{
|
||||
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)
|
||||
// Figure out if we are high dpi aware.
|
||||
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;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -262,7 +288,11 @@ int RI_InitContext(void* win)
|
|||
*/
|
||||
void RI_GetDrawableSize(int* width, int* height)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_GetWindowSizeInPixels(window, width, height);
|
||||
#else
|
||||
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);
|
||||
|
||||
/*
|
||||
* Returns the SDL major version. Implemented
|
||||
* here to not polute gl1_main.c with the SDL
|
||||
* headers.
|
||||
*/
|
||||
int RI_GetSDLVersion();
|
||||
|
||||
/* g11_draw */
|
||||
extern image_t * RDraw_FindPic(const char *name);
|
||||
extern void RDraw_GetPicSize(int *w, int *h, const char *pic);
|
||||
|
|
|
@ -1995,6 +1995,7 @@ GetRefAPI(refimport_t imp)
|
|||
ri = imp;
|
||||
|
||||
re.api_version = API_VERSION;
|
||||
re.framework_version = GL3_GetSDLVersion();
|
||||
|
||||
re.Init = GL3_Init;
|
||||
re.Shutdown = GL3_Shutdown;
|
||||
|
|
|
@ -29,7 +29,11 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
static SDL_Window* window = 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;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -345,9 +362,9 @@ int GL3_InitContext(void* win)
|
|||
|
||||
// Load GL pointers through GLAD and check context.
|
||||
#ifdef YQ2_GL3_GLES
|
||||
if( !gladLoadGLES2Loader(SDL_GL_GetProcAddress))
|
||||
if( !gladLoadGLES2Loader((void *)SDL_GL_GetProcAddress))
|
||||
#else // Desktop GL
|
||||
if( !gladLoadGLLoader(SDL_GL_GetProcAddress))
|
||||
if( !gladLoadGLLoader((void *)SDL_GL_GetProcAddress))
|
||||
#endif
|
||||
{
|
||||
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)
|
||||
// Figure out if we are high dpi aware.
|
||||
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;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -417,7 +438,11 @@ int GL3_InitContext(void* win)
|
|||
*/
|
||||
void GL3_GetDrawableSize(int* width, int* height)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_GetWindowSizeInPixels(window, width, height);
|
||||
#else
|
||||
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_SetVsync(void);
|
||||
extern void GL3_ShutdownContext(void);
|
||||
extern int GL3_GetSDLVersion(void);
|
||||
|
||||
// gl3_misc.c
|
||||
extern void GL3_InitParticleTexture(void);
|
||||
|
|
|
@ -22,8 +22,12 @@
|
|||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_video.h>
|
||||
#endif
|
||||
|
||||
#include "header/local.h"
|
||||
|
||||
|
@ -1802,10 +1806,19 @@ GetRefAPI(refimport_t imp)
|
|||
// used different variable name for prevent confusion and cppcheck warnings
|
||||
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));
|
||||
ri = imp;
|
||||
|
||||
refexport.api_version = API_VERSION;
|
||||
refexport.framework_version = ver.major;
|
||||
|
||||
refexport.BeginRegistration = RE_BeginRegistration;
|
||||
refexport.RegisterModel = RE_RegisterModel;
|
||||
|
@ -1890,11 +1903,19 @@ RE_InitContext(void *win)
|
|||
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_ACCELERATED);
|
||||
#else
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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)
|
||||
// Figure out if we are high dpi aware.
|
||||
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;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_GetCurrentRenderOutputSize(renderer, width, height);
|
||||
#else
|
||||
SDL_GetRendererOutputSize(renderer, width, height);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2225,7 +2254,12 @@ RE_FlushFrame(int vmin, int vmax)
|
|||
|
||||
SDL_UnlockTexture(texture);
|
||||
|
||||
#ifdef USE_SDL3
|
||||
SDL_RenderTexture(renderer, texture, NULL, NULL);
|
||||
#else
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
#endif
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
// replace use next buffer
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
#include "header/local.h"
|
||||
|
||||
|
|
|
@ -34,7 +34,11 @@
|
|||
*/
|
||||
|
||||
/* SDL includes */
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
/* Local includes */
|
||||
#include "../../client/header/client.h"
|
||||
|
@ -811,7 +815,9 @@ SDL_ClearBuffer(void)
|
|||
clear = 0;
|
||||
}
|
||||
|
||||
#ifndef USE_SDL3
|
||||
SDL_LockAudio();
|
||||
#endif
|
||||
|
||||
if (sound.buffer)
|
||||
{
|
||||
|
@ -827,7 +833,9 @@ SDL_ClearBuffer(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef USE_SDL3
|
||||
SDL_UnlockAudio();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1191,7 +1199,9 @@ SDL_Update(void)
|
|||
}
|
||||
|
||||
/* Mix the samples */
|
||||
#ifndef USE_SDL3
|
||||
SDL_LockAudio();
|
||||
#endif
|
||||
|
||||
/* Updates SDL time */
|
||||
SDL_UpdateSoundtime();
|
||||
|
@ -1221,7 +1231,9 @@ SDL_Update(void)
|
|||
}
|
||||
|
||||
SDL_PaintChannels(endtime);
|
||||
#ifndef USE_SDL3
|
||||
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
|
||||
* backend and sets up SDL.
|
||||
|
@ -1464,4 +1663,4 @@ SDL_BackendShutdown(void)
|
|||
snd_inited = 0;
|
||||
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_video.h>
|
||||
|
||||
int glimp_refreshRate = -1;
|
||||
float glimp_refreshRate = -1.0f;
|
||||
|
||||
static cvar_t *vid_displayrefreshrate;
|
||||
static cvar_t *vid_displayindex;
|
||||
|
@ -733,35 +733,19 @@ GLimp_GrabInput(qboolean grab)
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns the current display refresh rate. There're 2 limitations:
|
||||
*
|
||||
* * 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.
|
||||
* Returns the current display refresh rate.
|
||||
*/
|
||||
int
|
||||
float
|
||||
GLimp_GetRefreshRate(void)
|
||||
{
|
||||
|
||||
if (vid_displayrefreshrate->value > -1 ||
|
||||
vid_displayrefreshrate->modified)
|
||||
{
|
||||
glimp_refreshRate = ceil(vid_displayrefreshrate->value);
|
||||
glimp_refreshRate = vid_displayrefreshrate->value;
|
||||
vid_displayrefreshrate->modified = false;
|
||||
}
|
||||
|
||||
if (glimp_refreshRate == -1)
|
||||
else if (glimp_refreshRate == -1)
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
|
@ -835,3 +819,12 @@ GLimp_GetWindowDisplayIndex(void)
|
|||
{
|
||||
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;
|
||||
|
||||
// FIXME: bump API_VERSION?
|
||||
#define API_VERSION 6
|
||||
#define API_VERSION 7
|
||||
#define EXPORT
|
||||
#define IMPORT
|
||||
|
||||
|
@ -137,6 +137,11 @@ typedef struct
|
|||
// if api_version is different, the dll cannot be used
|
||||
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
|
||||
qboolean (EXPORT *Init) (void);
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ void VID_MenuDraw(void);
|
|||
const char *VID_MenuKey(int);
|
||||
|
||||
// Stuff provided by platform backend.
|
||||
extern int glimp_refreshRate;
|
||||
extern float glimp_refreshRate;
|
||||
|
||||
const char **GLimp_GetDisplayIndices(void);
|
||||
int GLimp_GetWindowDisplayIndex(void);
|
||||
|
@ -64,7 +64,8 @@ void GLimp_Shutdown(void);
|
|||
qboolean GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight);
|
||||
void GLimp_ShutdownGraphics(void);
|
||||
void GLimp_GrabInput(qboolean grab);
|
||||
int GLimp_GetRefreshRate(void);
|
||||
float GLimp_GetRefreshRate(void);
|
||||
qboolean GLimp_GetDesktopMode(int *pwidth, int *pheight);
|
||||
int GLimp_GetFrameworkVersion(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -456,9 +456,17 @@ VID_LoadRenderer(void)
|
|||
// Let's check if we've got a compatible renderer.
|
||||
if (re.api_version != API_VERSION)
|
||||
{
|
||||
Com_Printf("%s has incompatible api_version %d!\n", reflib_name, re.api_version);
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -525,8 +533,9 @@ VID_CheckChanges(void)
|
|||
// Mkay, let's try our luck.
|
||||
while (!VID_LoadRenderer())
|
||||
{
|
||||
// We try: custom -> gl3 -> gl1 -> soft.
|
||||
// We try: custom -> gl3 -> gles3 -> gl1 -> soft.
|
||||
if ((strcmp(vid_renderer->string, "gl3") != 0) &&
|
||||
(strcmp(vid_renderer->string, "gles3") != 0) &&
|
||||
(strcmp(vid_renderer->string, "gl1") != 0) &&
|
||||
(strcmp(vid_renderer->string, "soft") != 0))
|
||||
{
|
||||
|
@ -534,6 +543,11 @@ VID_CheckChanges(void)
|
|||
Cvar_Set("vid_renderer", "gl3");
|
||||
}
|
||||
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");
|
||||
Cvar_Set("vid_renderer", "gl1");
|
||||
|
@ -569,7 +583,7 @@ VID_Init(void)
|
|||
// Console variables
|
||||
vid_gamma = Cvar_Get("vid_gamma", "1.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
|
||||
Cmd_AddCommand("vid_restart", VID_Restart_f);
|
||||
|
|
|
@ -53,7 +53,7 @@ cvar_t *showtrace;
|
|||
|
||||
// Forward declarations
|
||||
#ifndef DEDICATED_ONLY
|
||||
int GLimp_GetRefreshRate(void);
|
||||
float GLimp_GetRefreshRate(void);
|
||||
qboolean R_IsVSyncActive(void);
|
||||
#endif
|
||||
|
||||
|
@ -570,7 +570,7 @@ Qcommon_Frame(int usec)
|
|||
// Calculate target and renderframerate.
|
||||
if (R_IsVSyncActive())
|
||||
{
|
||||
int refreshrate = GLimp_GetRefreshRate();
|
||||
float refreshrate = GLimp_GetRefreshRate();
|
||||
|
||||
// using refreshRate - 2, because targeting a value slightly below the
|
||||
// (possibly not 100% correctly reported) refreshRate would introduce jittering, so only
|
||||
|
|
Loading…
Reference in a new issue