From 7c87b5259a621c062c7c6a5b5cc52fc21f49e5a8 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 15:38:25 +0200 Subject: [PATCH 01/35] port SRB2s new makefiles + add dedicated build (squashed) also fix some of the new warnings to make a dedicated build just pass DEDICATED=1 to the compiler TODO:make this compatible with bluajit --- .gitignore | 15 +- bin/FreeBSD/Debug/.gitignore | 2 - bin/FreeBSD/Release/.gitignore | 2 - bin/Linux/Debug/.gitignore | 1 - bin/Linux/Release/.gitignore | 3 - bin/Linux64/Debug/.gitignore | 1 - bin/Linux64/Release/.gitignore | 1 - bin/Mingw/Debug/.gitignore | 4 - bin/Mingw/Release/.gitignore | 4 - bin/Mingw64/Debug/.gitignore | 3 - bin/Mingw64/Release/.gitignore | 4 - bin/SDL/Debug/.gitignore | 2 - bin/SDL/Release/.gitignore | 2 - bin/dummy/.gitignore | 2 - objs/.gitignore | 8 - objs/FreeBSD/SDL/Debug/.gitignore | 2 - objs/FreeBSD/SDL/Release/.gitignore | 2 - objs/Linux/SDL/Debug/.gitignore | 2 - objs/Linux/SDL/Release/.gitignore | 2 - objs/Linux64/SDL/Debug/.gitignore | 2 - objs/Linux64/SDL/Release/.gitignore | 2 - objs/MasterClient/.gitignore | 2 - objs/MasterServer/.gitignore | 2 - objs/Mingw/Debug/.gitignore | 2 - objs/Mingw/Release/.gitignore | 2 - objs/Mingw/SDL/Debug/.gitignore | 2 - objs/Mingw/SDL/Release/.gitignore | 2 - objs/Mingw64/Debug/.gitignore | 2 - objs/Mingw64/Release/.gitignore | 2 - objs/Mingw64/SDL/Debug/.gitignore | 2 - objs/Mingw64/SDL/Release/.gitignore | 2 - objs/SDL/Release/.gitignore | 2 - objs/cygwin/Debug/.gitignore | 2 - objs/cygwin/Release/.gitignore | 2 - objs/dummy/.gitignore | 2 - src/CMakeLists.txt | 14 +- src/Makefile | 1056 +++++-------- src/Makefile.d/dedicated.mk | 24 + src/Makefile.d/detect.mk | 124 ++ src/Makefile.d/features.mk | 106 ++ src/Makefile.d/haiku.mk | 71 + src/Makefile.d/nix.mk | 47 + src/Makefile.d/old.mk | 16 + src/Makefile.d/platform.mk | 76 + src/Makefile.d/sdl.mk | 71 + src/Makefile.d/util.mk | 93 ++ src/Makefile.d/versions.mk | 174 +++ src/Makefile.d/win32.mk | 124 ++ src/Sourcefile | 97 ++ src/blua/Sourcefile | 26 + src/d_main.c | 2 + src/d_netcmd.c | 2 - src/dedicated/CMakeLists.txt | 108 ++ src/dedicated/Sourcefile | 7 + src/dedicated/dosstr.c | 38 + src/dedicated/endtxt.c | 234 +++ src/dedicated/endtxt.h | 24 + src/dedicated/i_main.c | 238 +++ src/dedicated/i_sound.c | 339 ++++ src/dedicated/i_system.c | 2218 +++++++++++++++++++++++++++ src/dedicated/i_threads.c | 364 +++++ src/dedicated/i_video.c | 154 ++ src/g_game.c | 5 +- src/hardware/Sourcefile | 14 + src/m_menu.c | 2 +- src/m_misc.c | 3 +- src/p_mobj.c | 4 +- src/sdl/Sourcefile | 7 + src/sdl/i_main.c | 2 +- src/sdl/i_system.c | 2 +- src/w_wad.c | 2 + 71 files changed, 5173 insertions(+), 809 deletions(-) delete mode 100644 bin/FreeBSD/Debug/.gitignore delete mode 100644 bin/FreeBSD/Release/.gitignore delete mode 100644 bin/Linux/Debug/.gitignore delete mode 100644 bin/Linux/Release/.gitignore delete mode 100644 bin/Linux64/Debug/.gitignore delete mode 100644 bin/Linux64/Release/.gitignore delete mode 100644 bin/Mingw/Debug/.gitignore delete mode 100644 bin/Mingw/Release/.gitignore delete mode 100644 bin/Mingw64/Debug/.gitignore delete mode 100644 bin/Mingw64/Release/.gitignore delete mode 100644 bin/SDL/Debug/.gitignore delete mode 100644 bin/SDL/Release/.gitignore delete mode 100644 bin/dummy/.gitignore delete mode 100644 objs/.gitignore delete mode 100644 objs/FreeBSD/SDL/Debug/.gitignore delete mode 100644 objs/FreeBSD/SDL/Release/.gitignore delete mode 100644 objs/Linux/SDL/Debug/.gitignore delete mode 100644 objs/Linux/SDL/Release/.gitignore delete mode 100644 objs/Linux64/SDL/Debug/.gitignore delete mode 100644 objs/Linux64/SDL/Release/.gitignore delete mode 100644 objs/MasterClient/.gitignore delete mode 100644 objs/MasterServer/.gitignore delete mode 100644 objs/Mingw/Debug/.gitignore delete mode 100644 objs/Mingw/Release/.gitignore delete mode 100644 objs/Mingw/SDL/Debug/.gitignore delete mode 100644 objs/Mingw/SDL/Release/.gitignore delete mode 100644 objs/Mingw64/Debug/.gitignore delete mode 100644 objs/Mingw64/Release/.gitignore delete mode 100644 objs/Mingw64/SDL/Debug/.gitignore delete mode 100644 objs/Mingw64/SDL/Release/.gitignore delete mode 100644 objs/SDL/Release/.gitignore delete mode 100644 objs/cygwin/Debug/.gitignore delete mode 100644 objs/cygwin/Release/.gitignore delete mode 100644 objs/dummy/.gitignore create mode 100644 src/Makefile.d/dedicated.mk create mode 100644 src/Makefile.d/detect.mk create mode 100644 src/Makefile.d/features.mk create mode 100644 src/Makefile.d/haiku.mk create mode 100644 src/Makefile.d/nix.mk create mode 100644 src/Makefile.d/old.mk create mode 100644 src/Makefile.d/platform.mk create mode 100644 src/Makefile.d/sdl.mk create mode 100644 src/Makefile.d/util.mk create mode 100644 src/Makefile.d/versions.mk create mode 100644 src/Makefile.d/win32.mk create mode 100644 src/Sourcefile create mode 100644 src/blua/Sourcefile create mode 100644 src/dedicated/CMakeLists.txt create mode 100644 src/dedicated/Sourcefile create mode 100644 src/dedicated/dosstr.c create mode 100644 src/dedicated/endtxt.c create mode 100644 src/dedicated/endtxt.h create mode 100644 src/dedicated/i_main.c create mode 100644 src/dedicated/i_sound.c create mode 100644 src/dedicated/i_system.c create mode 100644 src/dedicated/i_threads.c create mode 100644 src/dedicated/i_video.c create mode 100644 src/hardware/Sourcefile create mode 100644 src/sdl/Sourcefile diff --git a/.gitignore b/.gitignore index 8b73f04f5..7f8d56035 100644 --- a/.gitignore +++ b/.gitignore @@ -13,16 +13,17 @@ Win32_LIB_ASM_Release *.dgb *.debug *.debug.txt -/bin/VC10/ -/objs/VC10/ *.user *.db *.opendb /.vs /debian /assets/debian -compile.sh -*.gz -.vscode/ -out -build +/make +/bin +/build +/build/* +/CMakeUserPresets.json +/out +/objs/VC10 +*.kate-swp diff --git a/bin/FreeBSD/Debug/.gitignore b/bin/FreeBSD/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/FreeBSD/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/FreeBSD/Release/.gitignore b/bin/FreeBSD/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/FreeBSD/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/Linux/Debug/.gitignore b/bin/Linux/Debug/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux/Debug/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Linux/Release/.gitignore b/bin/Linux/Release/.gitignore deleted file mode 100644 index 5b5c54a54..000000000 --- a/bin/Linux/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/lsdlsrb2 -/pnd -/*.mo diff --git a/bin/Linux64/Debug/.gitignore b/bin/Linux64/Debug/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux64/Debug/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Linux64/Release/.gitignore b/bin/Linux64/Release/.gitignore deleted file mode 100644 index c63fd53bc..000000000 --- a/bin/Linux64/Release/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdl2srb2kart diff --git a/bin/Mingw/Debug/.gitignore b/bin/Mingw/Debug/.gitignore deleted file mode 100644 index 3458ff764..000000000 --- a/bin/Mingw/Debug/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.exe -*.mo -r_opengl.dll -*.bat diff --git a/bin/Mingw/Release/.gitignore b/bin/Mingw/Release/.gitignore deleted file mode 100644 index 3458ff764..000000000 --- a/bin/Mingw/Release/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.exe -*.mo -r_opengl.dll -*.bat diff --git a/bin/Mingw64/Debug/.gitignore b/bin/Mingw64/Debug/.gitignore deleted file mode 100644 index e431dca5d..000000000 --- a/bin/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll diff --git a/bin/Mingw64/Release/.gitignore b/bin/Mingw64/Release/.gitignore deleted file mode 100644 index b2443f38d..000000000 --- a/bin/Mingw64/Release/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.exe -*.mo -r_opengl.dll -*.bat \ No newline at end of file diff --git a/bin/SDL/Debug/.gitignore b/bin/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/SDL/Release/.gitignore b/bin/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/dummy/.gitignore b/bin/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/.gitignore b/objs/.gitignore deleted file mode 100644 index 35ecd6def..000000000 --- a/objs/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -#All folders -SRB2.res -depend.dep -depend.ped -*.o -#VC9 folder only -/VC9/Win32 -/VC9/x64 diff --git a/objs/FreeBSD/SDL/Debug/.gitignore b/objs/FreeBSD/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/FreeBSD/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/FreeBSD/SDL/Release/.gitignore b/objs/FreeBSD/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/FreeBSD/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Debug/.gitignore b/objs/Linux/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Release/.gitignore b/objs/Linux/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Debug/.gitignore b/objs/Linux64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Release/.gitignore b/objs/Linux64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/MasterClient/.gitignore b/objs/MasterClient/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/MasterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/MasterServer/.gitignore b/objs/MasterServer/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/MasterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/Debug/.gitignore b/objs/Mingw/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/Release/.gitignore b/objs/Mingw/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Debug/.gitignore b/objs/Mingw/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Release/.gitignore b/objs/Mingw/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/Debug/.gitignore b/objs/Mingw64/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/Release/.gitignore b/objs/Mingw64/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Debug/.gitignore b/objs/Mingw64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Release/.gitignore b/objs/Mingw64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/SDL/Release/.gitignore b/objs/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/cygwin/Debug/.gitignore b/objs/cygwin/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/cygwin/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/cygwin/Release/.gitignore b/objs/cygwin/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/cygwin/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/dummy/.gitignore b/objs/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 729b5896a..4ce38953d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -228,6 +228,14 @@ set(SRB2_CONFIG_STATIC_OPENGL OFF CACHE BOOL "Use statically linked OpenGL. NOT RECOMMENDED.") set(SRB2_CONFIG_USE_FBO_OGL ON CACHE BOOL "Enable OpenGL FBO Downsampling support.") +set(SRB2_CONFIG_DEDICATED OFF CACHE BOOL + "Build a dedicated server.") + +if(${SRB2_CONFIG_DEDICATED}) + set(SRB2_CONFIG_HAVE_GME NO) + set(SRB2_CONFIG_HAVE_OPENMPT NO) + set(SRB2_CONFIG_HWRENDER NO) +endif() ### use internal libraries? if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only @@ -554,7 +562,11 @@ add_definitions(-DCMAKECONFIG) # ${SRB2_BLUA_HEADERS} #) -add_subdirectory(sdl) +if(${SRB2_CONFIG_DEDICATED}) + add_subdirectory(dedicated) +else() + add_subdirectory(sdl) +endif() if(NOT ${SRB2_SDL2_AVAILABLE} AND NOT ${SRB2_WIN32_AVAILABLE}) message(FATAL_ERROR "There are no targets available to build an SRB2Kart executable. :(") diff --git a/src/Makefile b/src/Makefile index b6077ba6c..e995b3ccf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,783 +1,419 @@ - -# GNU Make makefile for SRB2 -############################################################################# -# Copyright (C) 1998-2000 by DooM Legacy Team. -# Copyright (C) 2003-2018 by Sonic Team Junior. +# GNU Makefile for SRB2 +# the poly3 Makefile adapted over and over... +# +# Copyright 1998-2000 DooM Legacy Team. +# Copyright 2020-2023 James R. +# Copyright 2003-2023 Sonic Team Junior. # # This program is free software distributed under the # terms of the GNU General Public License, version 2. # See the 'LICENSE' file for more details. # -# -DLINUX -> use for the GNU/Linux specific -# -DHAVE_SDL -> use for the SDL interface +# Special targets: # -# Sets: -# Compile the Mingw version with 'make MINGW=1' -# Compile the SDL/Mingw version with 'make MINGW=1 SDL=1' -# Compile the SDL/Linux version with 'make LINUX=1' -# Compile the SDL/Solaris version with 'make SOLARIS=1' -# Compile the SDL/FreeBSD version with 'gmake FREEBSD=1' -# Compile the SDL/Cygwin version with 'make CYGWIN32=1' -# Compile the SDL/other version try with 'make SDL=1' +# clean - remove executables and objects for this build +# cleandep - remove dependency files for this build +# distclean - remove entire executable, object and +# dependency file directory structure. +# dump - disassemble executable +# info - print settings # -# 'Targets': -# clean -# Remove all object files -# cleandep -# Remove depend.dep -# dll -# compile primary HW render DLL/SO -# all_dll -# compile all HW render and 3D sound DLLs for the set -# opengl_dll -# Pure Mingw only, compile OpenGL HW render DLL +# This Makefile can automatically detect the host system +# as well as the compiler version. If system or compiler +# version cannot be detected, you may need to set a flag +# manually. # # -# Addon: -# To Cross-Compile, CC=gcc-version make * PREFIX= -# Compile with GCC 2.97 version, add 'GCC29=1' -# Compile with GCC 4.0x version, add 'GCC40=1' -# Compile with GCC 4.1x version, add 'GCC41=1' -# Compile with GCC 4.2x version, add 'GCC42=1' -# Compile with GCC 4.3x version, add 'GCC43=1' -# Compile with GCC 4.4x version, add 'GCC44=1' -# Compile with GCC 4.5x version, add 'GCC45=1' -# Compile with GCC 4.6x version, add 'GCC46=1' -# Compile a profile version, add 'PROFILEMODE=1' -# Compile a debug version, add 'DEBUGMODE=1' -# Compile with less warnings, add 'RELAXWARNINGS=1' -# Generate compiler errors for most compiler warnings, add 'ERRORMODE=1' -# Compile without 3D hardware support, add 'NOHW=1' -# Compile with GDBstubs, add 'RDB=1' -# Compile without PNG, add 'NOPNG=1' -# Compile without zlib, add 'NOZLIB=1' +# Platform/system flags: # -# Addon for SDL: -# To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config' -# Compile without SDL_Mixer, add 'NOMIXER=1' -# Compile without BSD API, add 'NONET=1' -# Compile without IPX/SPX, add 'NOIPX=1' -# Compile without libopenmpt, add 'NOOPENMPT=1' -# To link with the whole SDL_Image lib to load Icons, add 'SDL_IMAGE=1' but it isn't not realy needed -# To link with SDLMain to hide console or make on a console-less binary, add 'SDLMAIN=1' +# LINUX=1, LINUX64=1 +# MINGW=1, MINGW64=1 - Windows (MinGW toolchain) +# UNIX=1 - Generic Unix like system +# FREEBSD=1 +# SDL=1 - Use SDL backend. SDL is the only implemented backend though. +# If disabled, a dummy backend will be used. # -############################################################################# +# A list of supported GCC versions can be found in +# Makefile.d/detect.mk -- search 'gcc_versions'. +# +# Feature flags: +# +# Safe to use online +# ------------------ +# NOHW=1 - Disable OpenGL renderer. +# NOSCREENFBO=1 - Disable screen FBO for downsampling in OpenGL. +# NOSATURNPAK=1 - Disable handling the special Saturn packet and resynch system +# NOSATURNJOIN=1 - Disable the seperate Saturn allowjoin toggle +# ZDEBUG=1 - Enable more detailed memory debugging +# HAVE_MINIUPNPC=1 - Enable automated port forwarding. +# Already enabled by default for 32-bit +# Windows. +# NOCURL=1 - Disable libcurl--HTTP capability. +# NOGME=1 - Disable game music emu, retro VGM support. +# NOOPENMPT=1 - Disable module (tracker) music support. +# NOMIXER=1 - Disable SDL Mixer (audio playback). +# NOTHREADS=1 - Disable multithreading. +# +# Netplay incompatible +# -------------------- +# NOMD5=1 - Disable MD5 checksum (validation tool). +# NOPOSTPROCESSING=1 - ? +# MOBJCONSISTANCY=1 - ?? +# PACKETDROP=1 - ?? +# NOEXECINFO=1 - Disable stack trace dump support +# DEBUGMODE=1 - Enable various debugging capabilities. +# Also disables optimizations. +# +# Development flags: +# +# VALGRIND=1 - Enable Valgrind memory debugging support. +# PROFILEMODE=1 - Enable performance profiling (gprof). +# USEASAN=1 - Enable building with Address Sanitizer. +# NOLIBBACKTRACE=1 - Disable using Libbacktrace for crashlog traces. +# +# General flags for building: +# +# STATIC=1 - Use static linking. +# DISTCC=1 +# CCACHE=1 +# UPX= - UPX command to use for compressing final +# executable. +# WINDOWSHELL=1 - Use Windows commands. +# PREFIX= - Prefix to many commands, for cross compiling. +# STABS=1 - ? +# ECHO=1 - Print out each command in the build process. +# NOECHOFILENAMES=1 - Don't print out each that is being +# worked on. +# SILENT=1 - Print absolutely nothing except errors. +# RELAXWARNINGS=1 - Use less compiler warnings/errors. +# ERRORMODE=1 - Treat most compiler warnings as errors. +# NOCASTALIGNWARN=1 - ? +# NOLDWARNING=1 - ? +# NOSDLMAIN=1 - ? +# SDLMAIN=1 - ? +# USELTO=1 - Enable building with LTO. +# +# Library configuration flags: +# Everything here is an override. +# +# PNG_PKGCONFIG= - libpng-config command. +# PNG_CFLAGS=, PNG_LDFLAGS= +# +# CURLCONFIG= - curl-config command. +# CURL_CFLAGS=, CURL_LDFLAGS= +# +# VALGRIND_PKGCONFIG= - pkg-config package name. +# VALGRIND_CFLAGS=, VALGRIND_LDFLAGS= +# +# LIBGME_PKGCONFIG=, LIBGME_CFLAGS=, LIBGME_LDFLAGS= -ALL_SYSTEMS=\ - PANDORA\ - LINUX64\ - MINGW64\ - HAIKU\ - MINGW\ - UNIX\ - LINUX\ - SOLARIS\ - FREEBSD\ - MACOSX\ - SDL\ +# LIBOPENMPT_PKGCONFIG= +# LIBOPENMPT_CFLAGS=, LIBOPENMPT_LDFLAGS= +# +# ZLIB_PKGCONFIG=, ZLIB_CFLAGS=, ZLIB_LDFLAGS= +# +# SDL_PKGCONFIG= +# SDL_CONFIG= - sdl-config command. +# SDL_CFLAGS=, SDL_LDFLAGS= -# check for user specified system -ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES))) -ifeq ($(OS),Windows_NT) # all windows are Windows_NT... +NOBLUAJIT=1 - ifeq ($(shell uname -s | grep -o MINGW64),MINGW64) # 64-bit MinGW - $(info Detected a Windows system, compiling for 64-bit MinGW SDL2...) - MINGW64=1 - else # 32-bit MinGW - $(info Detected a Windows system, compiling for 32-bit MinGW SDL2...) - MINGW=1 - endif +clean_targets=cleandep clean distclean info - SDL=1 - WINDOWSHELL=1 - NOOBJDUMP=1 +.PHONY : $(clean_targets) all -else # if you on the *nix - system:=$(shell uname -s) +goals:=$(or $(MAKECMDGOALS),all) +cleanonly:=$(filter $(clean_targets),$(goals)) +destructive:=$(filter-out info,$(cleanonly)) - ifeq ($(system),Linux) - new_system=LINUX - else - - $(error \ - Could not automatically detect your system,\ - try specifying a system manually) - - endif - - ifeq ($(shell getconf LONG_BIT),64) - system+=64-bit - new_system:=$(new_system)64 - endif - - $(info Detected $(system) ($(new_system))...) - $(new_system)=1 - -endif +ifndef cleanonly +include Makefile.d/old.mk endif -NOUPX=1 +include Makefile.d/util.mk -# SRB2 data files -D_DIR?=../bin/Resources -D_FILES=$(D_DIR)/srb2.srb \ - $(D_DIR)/patch.dta \ - #$(D_DIR)/music.dta \ - $(D_DIR)/gfx.kart \ - $(D_DIR)/textures.kart \ - $(D_DIR)/chars.kart \ - $(D_DIR)/maps.kart \ - $(D_DIR)/sounds.kart \ - $(D_DIR)/patch.kart \ - $(D_DIR)/music.kart \ - -PKG_CONFIG?=pkg-config - -ifdef PANDORA -LINUX=1 -endif - -ifdef LINUX64 -LINUX=1 -NONX86=1 -# LINUX64 does not imply X86_64=1; could mean ARM64 or Itanium -endif - -ifdef MINGW64 -MINGW=1 -NONX86=1 -# MINGW64 should not necessarily imply X86_64=1, but we make that assumption elsewhere -# Once that changes, remove this -X86_64=1 -endif #ifdef MINGW64 - -ifdef HAIKU -SDL=1 -endif - -include Makefile.cfg - -ifdef HAIKU -NOIPX=1 -ifndef NONET -LIBS=-lnetwork -endif -CFLAGS+=-DUNIXCOMMON -PNG_CFLAGS?= -PNG_LDFLAGS?=-lpng -endif - -ifdef PANDORA -NONX86=1 -NOHW=1 -endif - -ifndef NOOPENMPT -HAVE_OPENMPT=1 -endif - -ifndef NOHW -ifndef NOSCREENFBO -USE_FBO_OGL=1 -endif -endif - -ifndef NONET -ifndef NOSATURNJOIN -DOSATURNJOIN=1 -endif -ifndef NOSATURNPAK -DOSATURNPAK=1 -endif -endif - -ifdef MINGW -include win32/Makefile.cfg -endif #ifdef MINGW - -ifdef UNIX -UNIXCOMMON=1 -endif - -ifdef LINUX -UNIXCOMMON=1 -NOOBJDUMP=1 -ifndef NOGME -HAVE_LIBGME=1 -endif -endif - -ifdef SOLARIS -UNIXCOMMON=1 -endif - -ifdef FREEBSD -UNIXCOMMON=1 -endif - -ifdef MACOSX -UNIXCOMMON=1 -endif - -ifdef SDL - include sdl/Makefile.cfg -endif #ifdef SDL - -ifdef DISTCC - CC:=distcc $(CC) -endif - -ifdef CCACHE - CC:=ccache $(CC) -endif - -MSGFMT?=msgfmt - -ifndef ECHO - REMOVE:=@$(REMOVE) - CC:=@$(CC) - CXX:=@$(CXX) - OBJCOPY:=@$(OBJCOPY) - OBJDUMP:=@$(OBJDUMP) - STRIP:=@$(STRIP) - WINDRES:=@$(WINDRES) - CP:=@$(CP) - MKDIR:=@$(MKDIR) - MKISOFS:=@$(MKISOFS) - DD:=@$(DD) - NDSTOOL:=@$(NDSTOOL) - GZIP:=@$(GZIP) - MSGFMT:=@$(MSGFMT) - UPX:=@$(UPX) - UPX_OPTS+=-q -endif - -ifdef NONET - OPTS+=-DNONET - NOCURL=1 -else -ifdef NO_IPV6 - OPTS+=-DNO_IPV6 -endif -endif - -ifdef NOHW - OPTS+=-DNOHW -else - OPTS+=-DHWRENDER - OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_portal.o\ - $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o $(OBJDIR)/hw_shaders.o -endif - -OPTS += -DCOMPVERSION - -ifndef NONX86 -ifndef GCC29 - ARCHOPTS?=-msse3 -mfpmath=sse -else - ARCHOPTS?=-mpentium -endif -else -ifdef X86_64 - ARCHOPTS?=-march=nocona -endif -endif - -# apparently MingW just completely ignores everything so just always force this shit -# FIXME: we should port our code to c24 -CFLAGS+=-std=gnu17 -CPPFLAGS+=-std=gnu17 - -ifndef NOPNG -OPTS+=-DHAVE_PNG - -ifdef PNG_PKGCONFIG -PNG_CFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --libs) -else ifdef PREFIX -PNG_CONFIG?=$(PREFIX)-libpng-config +CC:=$(PREFIX)-gcc +endif + +OBJDUMP_OPTS?=--wide --source --line-numbers + +OBJCOPY?=$(call Prefix,objcopy) +OBJDUMP?=$(call Prefix,objdump) +WINDRES?=$(call Prefix,windres) + +GZIP?=gzip +GZIP_OPTS?=-9 -f -n +ifdef WINDOWSHELL +GZIP_OPTS+=--rsyncable +endif + +UPX_OPTS?=--best --preserve-build-id +ifndef ECHO +UPX_OPTS+=-qq +endif + +include Makefile.d/detect.mk + +# make would try to remove the implicitly made directories +.PRECIOUS : %/ comptime.c + +sources:= +makedir:=../make + +# -DCOMPVERSION: flag to use comptime.h +opts:=-DCOMPVERSION -g +libs:= + +# This is a list of variables names, of which if defined, +# also defines the name as a macro to the compiler. +passthru_opts:= + +include Makefile.d/platform.mk +include Makefile.d/features.mk +include Makefile.d/versions.mk + +ifdef DEBUGMODE +makedir:=$(makedir)/debug +endif + +depdir:=$(makedir)/deps +objdir:=$(makedir)/objs + +# very sophisticated dependency +sources+=\ + $(call List,Sourcefile) + +ifdef NOBLUAJIT +sources+=\ + $(call List,blua/Sourcefile) else -PNG_CONFIG?=libpng-config +include bluajit/Makefile.cfg +include bluajit/Makefile.cfg2 endif -ifdef PNG_STATIC -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --static --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --static --ldflags) +depends:=$(basename $(filter %.c %.cpp %.s,$(sources))) +objects:=$(basename $(filter %.c %.cpp %.s %.nas,$(sources))) + +depends:=$(depends:%=$(depdir)/%.d) + +# comptime.o added directly to objects instead of thru +# sources because comptime.c includes comptime.h, but +# comptime.h may not exist yet. It's a headache so this is +# easier. +objects:=$(objects:=.o) comptime.o + +# windows resource file +rc_file:=$(basename $(filter %.rc,$(sources))) +ifdef rc_file +objects+=$(rc_file:=.res) +endif + +objects:=$(addprefix $(objdir)/,$(objects)) + +ifdef DEBUGMODE +bin:=../bin/debug else -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --ldflags) -endif +bin:=../bin endif -ifdef LINUX -PNG_CFLAGS+=-D_LARGEFILE64_SOURCE -endif +# default EXENAME (usually set by platform) +EXENAME?=srb2kart +DBGNAME?=$(EXENAME).debug -LIBS+=$(PNG_LDFLAGS) -CFLAGS+=$(PNG_CFLAGS) +exe:=$(bin)/$(EXENAME) +dbg:=$(bin)/$(DBGNAME) -OBJS+=$(OBJDIR)/apng.o -endif +build_done==== Build is done, look for \ + $( $@ + $(.)$(GZIP) $(GZIP_OPTS) $@ + +# '::' means run unconditionally +# this really updates comptime.h +comptime.c :: ifdef WINDOWSHELL -$(.)..\comptime.bat . else -$(.)../comptime.sh . endif -clean: cleandep - $(REMOVE) *~ *.flc - $(REMOVE) $(OBJDIR)/*.o +# I wish I could make dependencies out of rc files :( +$(objdir)/win32/Srb2win.res : \ + win32/afxres.h win32/resource.h -ifdef MINGW - $(REMOVE) $(OBJDIR)/*.res -endif - -ifdef CYGWIN32 - $(REMOVE) $(OBJDIR)/*.res -endif - - -# executable - -$(BIN)/$(EXENAME): $(POS) $(OBJS) - -$(MKDIR) $(BIN) - @echo Linking $(EXENAME)... - $(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS) -ifndef VALGRIND -ifndef NOOBJDUMP - @echo Dumping debugging info - $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(EXENAME) > $(BIN)/$(DBGNAME).txt - -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt +# dependency recipe template +# 1: source file suffix +# 2: extra flags to gcc +define _recipe = +$(depdir)/%.d : %.$(1) | $$$$(@D)/ ifndef WINDOWSHELL - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt +ifdef Echo_name + @printf '%-20.20s\r' $$< endif +endif + $(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$< +endef + +$(eval $(call _recipe,c)) +$(eval $(call _recipe,cpp)) +$(eval $(call _recipe,s,$(asflags))) + +# compiling recipe template +# 1: target file suffix +# 2: source file suffix +# 3: compile command +define _recipe = +$(objdir)/%.$(1) : %.$(2) | $$$$(@D)/ + $(call Echo_name,$$<) + $(.)$(3) +endef + +$(eval $(call _recipe,o,c,$(cc) -c -o $$@ $$<)) +$(eval $(call _recipe,o,cpp,$(cxx) -c -o $$@ $$<)) +$(eval $(call _recipe,o,s,$(cc) $(asflags) -c -o $$@ $$<)) +$(eval $(call _recipe,res,rc,$(windres) -i $$< -o $$@)) + +_rm=$(.)$(rmrf) $(call Windows_path,$(1)) + +cleandep : + $(call _rm,$(depends) comptime.h) + +clean : + $(call _rm,$(exe) $(dbg) $(dbg).txt $(objects)) + +distclean : + $(call _rm,../bin ../objs ../dep ../make comptime.h) + +ifndef NOBLUAJIT + $(call _rm,$(objdir)/buildvm* $(objdir)/minilua* $(objdir)/lj_vm*) + +cleanjit: + $(call _rm,$(objdir)/buildvm* $(objdir)/minilua* $(objdir)/lj_vm* $(ALL_HDRGEN) $(LJVMCORE_O) $(ALL_GEN)) endif -# mac os x lsdlsrb2 does not like objcopy -ifndef MACOSX - $(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME) - $(OBJCOPY) --strip-debug $(BIN)/$(EXENAME) - -$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME) -endif -ifndef NOUPX - -$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME) -endif -endif - -ifdef APPIMAGE - @echo Building AppImage... -ifdef APPIMAGE_NOASSETS - $(.)../AppImage_build.sh --small --quiet $(BIN)/ +info: +ifdef WINDOWSHELL + @REM else - $(.)../AppImage_build.sh -q $(BIN)/ -endif - @echo AppImage build complete, please look for $(EXENAME).AppImage in $(BIN) + @: endif - @echo Build is done, please look for $(EXENAME) in $(BIN), \(checking for post steps\) - -reobjdump: - @echo Redumping debugging info - $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(DBGNAME) > $(BIN)/$(DBGNAME).txt - -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt -ifndef WINDOWSHELL - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt -endif - -$(OBJDIR): - -$(MKDIR) $(OBJDIR) - -ifndef SDL -ifdef NOHW -dll : -else -dll : opengl_dll -endif -ifdef MINGW -all_dll: opengl_dll - -opengl_dll: $(BIN)/r_opengl.dll -$(BIN)/r_opengl.dll: $(OBJDIR)/ogl_win.o $(OBJDIR)/r_opengl.o - -$(MKDIR) $(BIN) - @echo Linking R_OpenGL.dll... - $(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lgdi32 -static-libgcc -ifndef NOUPX - -$(UPX) $(UPX_OPTS) $@ -endif -endif - -else -ifdef SDL -ifdef MINGW -$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_gl.h screen.h \ - command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ - hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h hardware/hw_portal.h\ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -else -$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_gl.h screen.h \ - command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ - hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h hardware/hw_portal.h \ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@ -endif -endif - -endif - -#dependecy made by gcc itself ! -$(OBJS): --include $(OBJDIR)/depend.dep - -$(OBJDIR)/depend.dep: - @echo "Creating dependency file, depend.dep" - @echo > comptime.h - -$(MKDIR) $(OBJDIR) - $(CC) $(CFLAGS) -MM *.c > $(OBJDIR)/depend.ped - $(CC) $(CFLAGS) -MM $(INTERFACE)/*.c >> $(OBJDIR)/depend.ped -ifndef NOHW - $(CC) $(CFLAGS) -MM hardware/*.c >> $(OBJDIR)/depend.ped -endif - - $(CC) $(CFLAGS) -MM blua/*.c >> $(OBJDIR)/depend.ped - - @sed -e 's,\(.*\)\.o: ,$(subst /,\/,$(OBJDIR))\/&,g' < $(OBJDIR)/depend.ped > $(OBJDIR)/depend.dep - $(REMOVE) $(OBJDIR)/depend.ped - @echo "Created dependency file, depend.dep" - -ifdef VALGRIND -$(OBJDIR)/z_zone.o: z_zone.c - $(CC) $(CFLAGS) $(WFLAGS) -DHAVE_VALGRIND $(VALGRIND_CFLAGS) -c $< -o $@ -endif - -$(OBJDIR)/comptime.o: comptime.c pre-build - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(BIN)/%.mo: locale/%.po - -$(MKDIR) $(BIN) - $(MSGFMT) -f -o $@ $< - -$(OBJDIR)/%.o: %.c - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: $(INTERFACE)/%.c - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -ifdef MACOSX -$(OBJDIR)/%.o: sdl/macosx/%.c - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif - -$(OBJDIR)/%.o: hardware/%.c - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: blua/%.c - $(CC) $(CFLAGS) $(LUA_CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: %.s - $(CC) $(OPTS) -x assembler-with-cpp -c $< -o $@ - -$(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h - $(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff - -ifdef SDL -ifdef MINGW -$(OBJDIR)/win_dbg.o: win32/win_dbg.c - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif -endif - -############################################################# -# -############################################################# +#$(warning The handwritten GNU Makefile for SRB2 is deprecated, and may be removed in the future. Please consider switching to CMake.) diff --git a/src/Makefile.d/dedicated.mk b/src/Makefile.d/dedicated.mk new file mode 100644 index 000000000..698ea5531 --- /dev/null +++ b/src/Makefile.d/dedicated.mk @@ -0,0 +1,24 @@ +makedir:=$(makedir)/Dedicated + +sources+=$(call List,dedicated/Sourcefile) + +opts+=-DDEDICATED + +ifdef FREEBSD +# on FreeBSD, we have to link to libpthread explicitly +libs+=-lpthread +endif + +ifdef MINGW +libs+=-mconsole +endif + +ifndef NOTHREADS +opts+=-DHAVE_THREADS +sources+=dedicated/i_threads.c +endif + +NOOPENMPT=1 +NOGME=1 +NOHW=1 +NOUPNP=1 diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk new file mode 100644 index 000000000..dd31d2f3e --- /dev/null +++ b/src/Makefile.d/detect.mk @@ -0,0 +1,124 @@ +# +# Detect the host system and compiler version. +# + +# Previously featured:\ + PANDORA\ + DUMMY\ + DJGPPDOS\ + SOLARIS\ + MACOSX\ + +all_systems:=\ + LINUX64\ + MINGW64\ + MINGW\ + UNIX\ + LINUX\ + FREEBSD\ + HAIKU\ + +# check for user specified system +ifeq (,$(filter $(all_systems),$(.VARIABLES))) +ifeq ($(OS),Windows_NT) # all windows are Windows_NT... + + ifeq ($(shell uname -s | grep -o MINGW64),MINGW64) # 64-bit MinGW + _m=Detected a Windows system,\ + compiling for 64-bit MinGW SDL...) + $(call Print,$(_m)) + MINGW64=1 + else # 32-bit MinGW + _m=Detected a Windows system,\ + compiling for 32-bit MinGW SDL...) + $(call Print,$(_m)) + MINGW=1 + endif + + NOOBJDUMP=1 +else # if you on the *nix + +system:=$(shell uname -s) + +ifeq ($(system),Linux) +new_system:=LINUX +else ifeq ($(system),Haiku) +new_system:=HAIKU +else + +$(error \ + Could not automatically detect your system,\ + try specifying a system manually) + +endif + +ifeq ($(shell getconf LONG_BIT),64) +system+=64-bit +new_system:=$(new_system)64 +endif + +$(call Print,Detected $(system) ($(new_system))...) +$(new_system):=1 + +endif +endif + +# This must have high to low order. +gcc_versions:=\ + 151 150 15\ + 142 141 140 14\ + 132 131 130 13\ + 123 122 121 120 12\ + 114 113 112 111 110 11\ + 105 104 103 102 101 100 10\ + 95 94 93 92 91 90\ + 85 84 83 82 81 80\ + 75 74 73 72 71 70\ + 64 63 62 61 60\ + 55 54 53 52 51 50\ + 49 48 47 46 45 44 43 42 41 40 + +latest_gcc_version:=15.1.1 + +# Automatically set version flag, but not if one was +# manually set. And don't bother if this is a clean only +# run. +ifeq (,$(call Wildvar,GCC% destructive)) + +# can't use $(CC) --version here since that uses argv[0] to display the name +# also gcc outputs the information to stderr, so I had to do 2>&1 +# this program really doesn't like identifying itself +shellversion:=$(shell $(CC) -v 2>&1) +# Try to remove "-win32" +version:=$(subst -win32,.0,$(shellversion)) + +# check if this is in fact GCC +ifneq (,$(findstring gcc version,$(version))) + +# in stark contrast to the name, gcc will give me a nicely formatted version number for free +shellversion:=$(shell $(CC) -dumpfullversion) + +# Try to remove "-win32" +version:=$(subst -win32,.0,$(shellversion)) + +# Turn version into words of major, minor +v:=$(subst ., ,$(version)) +# concat. major minor +v:=$(word 1,$(v))$(word 2,$(v)) + +# If this version is not in the list, +# default to the latest supported +ifeq (,$(filter $(v),$(gcc_versions))) +define line = +Your compiler version, GCC $(version), \ +is not supported by the Makefile. +The Makefile will assume GCC $(latest_gcc_version). +endef +$(call Print,$(line)) +GCC$(subst .,,$(latest_gcc_version)):=1 +else +$(call Print,Detected GCC $(version) (GCC$(v))) +GCC$(v):=1 +endif + +endif +endif diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk new file mode 100644 index 000000000..ca789dbee --- /dev/null +++ b/src/Makefile.d/features.mk @@ -0,0 +1,106 @@ +# +# Makefile for feature flags. +# + +passthru_opts+=\ + NOHW NOMD5 NOPOSTPROCESSING\ + MOBJCONSISTANCY PACKETDROP ZDEBUG\ + HAVE_MINIUPNPC\ + HAVE_DISCORDRPC DEVELOP\ + NOBLUAJIT + +# build with debugging information +ifdef DEBUGMODE +PACKETDROP=1 +opts+=-DPARANOIA -DRANGECHECK +endif + +ifndef NOHW +opts+=-DHWRENDER + +ifndef NOSCREENFBO +opts+=-DUSE_FBO_OGL +endif + +sources+=$(call List,hardware/Sourcefile) +endif + +ifndef NOMD5 +sources+=md5.c +endif + +ifndef NONET +ifndef NOSATURNJOIN +opts+=-DDOSATURNJOIN +endif +ifndef NOSATURNPAK +opts+=-DDOSATURNPAK +endif +endif + +ifndef NOZLIB +ifndef NOPNG +ifdef PNG_PKGCONFIG +$(eval $(call Use_pkg_config,PNG_PKGCONFIG)) +else +PNG_CONFIG?=$(call Prefix,libpng-config) +$(eval $(call Configure,PNG,$(PNG_CONFIG) \ + $(if $(PNG_STATIC),--static),,--ldflags)) +endif +ifdef LINUX +opts+=-D_LARGEFILE64_SOURCE +endif +opts+=-DHAVE_PNG +sources+=apng.c +endif +endif + +ifndef NOCURL +CURLCONFIG?=curl-config +$(eval $(call Configure,CURL,$(CURLCONFIG))) +opts+=-DHAVE_CURL +endif + +ifdef HAVE_MINIUPNPC +MINIUPNPC_PKGCONFIG?=miniupnpc +$(eval $(call Use_pkg_config,MINIUPNPC)) +HAVE_MINIUPNPC=1 +opts+=-DHAVE_MINIUPNPC +endif + +ifndef NOLIBBACKTRACE +$(eval $(call Propogate_flags,LIBBACKTRACE)) +libs+=-lbacktrace +opts+=-DHAVE_LIBBACKTRACE +endif + +#windoze hack +ifdef MINGW +ifndef NODISCORDRPC +HAVE_DISCORDRPC=1 +endif +endif + +ifdef HAVE_DISCORDRPC +$(eval $(call Propogate_flags,DISCORDRPC)) +libs+=-ldiscord-rpc +opts+=-DUSE_STUN +sources+=discord.c stun.c +endif + +# (Valgrind is a memory debugger.) +ifdef VALGRIND +VALGRIND_PKGCONFIG?=valgrind +VALGRIND_LDFLAGS= +$(eval $(call Use_pkg_config,VALGRIND)) +ZDEBUG=1 +opts+=-DHAVE_VALGRIND +endif + +default_packages:=\ + GME/libgme/LIBGME\ + OPENMPT/libopenmpt/LIBOPENMPT\ + ZLIB/zlib\ + +$(foreach p,$(default_packages),\ + $(eval $(call Check_pkg_config,$(p)))) diff --git a/src/Makefile.d/haiku.mk b/src/Makefile.d/haiku.mk new file mode 100644 index 000000000..6742ec75b --- /dev/null +++ b/src/Makefile.d/haiku.mk @@ -0,0 +1,71 @@ +# +# Makefile options for Haiku +# + +opts+=-DUNIXCOMMON -DLUA_USE_POSIX + +ifndef DEDICATED +ifndef DUMMY +SDL?=1 +DEDICATED?=0 +endif +endif + +NOEXECINFO=1 + +ifeq (${SDL},1) +EXENAME?=srb2haiku +else ifeq (${DEDICATED},1) +EXENAME?=srb2haikud +endif + +ifndef NONET +libs+=-lnetwork +endif + +define _set = +$(1)_CFLAGS?=$($(1)_opts) +$(1)_LDFLAGS?=$($(1)_libs) +endef + +lib:=../libs/gme +LIBGME_opts:=-I$(lib)/include +LIBGME_libs:=-l:libgme.so.0 +$(eval $(call _set,LIBGME)) + +lib:=../libs/libopenmpt +LIBOPENMPT_opts:=-I$(lib)/inc +LIBOPENMPT_libs:=-l:libopenmpt.so.0 +$(eval $(call _set,LIBOPENMPT)) + +ifdef SDL +lib:=../libs/SDL2_mixer +mixer_opts:=-I$(lib)/include +mixer_libs:=-l:libSDL2_mixer-2.0.so.0 + +lib:=../libs/SDL2 +SDL_opts:=-I$(lib)/include $(mixer_opts) +SDL_libs:=$(mixer_libs) -l:libSDL2-2.0.so.0 +$(eval $(call _set,SDL)) +endif + +lib:=../libs/zlib +ZLIB_opts:=-I$(lib) +ZLIB_libs:=-l:libz.so.1 +$(eval $(call _set,ZLIB)) + +ifndef PNG_CONFIG +PNG_opts:= +PNG_libs:=-l:libpng16.so.16 +$(eval $(call _set,PNG)) +endif + +lib:=../libs/curl +CURL_opts:=-I$(lib)/include +CURL_libs:=-l:libcurl.so.4 +$(eval $(call _set,CURL)) + +lib:=../libs/miniupnpc +MINIUPNPC_opts:=-I$(lib)/include +MINIUPNPC_libs:=-l:libminiupnpc.so.17 +$(eval $(call _set,MINIUPNPC)) diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk new file mode 100644 index 000000000..7135f258b --- /dev/null +++ b/src/Makefile.d/nix.mk @@ -0,0 +1,47 @@ +# +# Makefile options for unices (linux, bsd...) +# + + +opts+=-DUNIXCOMMON -DLUA_USE_POSIX +# Use -rdynamic so a backtrace log shows function names +# instead of addresses +libs+=-lm -rdynamic + +ifndef NOHW +opts+=-I/usr/X11R6/include +libs+=-L/usr/X11R6/lib +endif + +ifndef DEDICATED +SDL?=1 +DEDICATED?=0 +endif + +ifeq (${SDL},1) +EXENAME?=lsdl2srb2kart +endif + +ifeq (${DEDICATED},1) +EXENAME?=lsrb2kartd +endif + +# In common usage. +ifdef LINUX +libs+=-lrt +passthru_opts+=NOTERMIOS +endif + +# Tested by Steel, as of release 2.2.8. +ifdef FREEBSD +opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD +libs+=-L/usr/X11R6/lib -lkvm -lexecinfo +endif + +# FIXME: UNTESTED +#ifdef SOLARIS +#NOIPX=1 +#opts+=-I/usr/local/include -I/opt/sfw/include \ +# -DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP +#libs+=-L/opt/sfw/lib -lsocket -lnsl +#endif diff --git a/src/Makefile.d/old.mk b/src/Makefile.d/old.mk new file mode 100644 index 000000000..ec9b6d776 --- /dev/null +++ b/src/Makefile.d/old.mk @@ -0,0 +1,16 @@ +# +# Warn about old build directories and offer to purge. +# + +_old:=$(wildcard $(addprefix ../bin/,FreeBSD Linux \ + Linux64 Mingw Mingw64 SDL dummy) ../objs ../dep) + +ifdef _old +$(foreach v,$(_old),$(info $(abspath $(v)))) +$(info ) +$(info These directories are no longer\ + required and should be removed.) +$(info You may remove them manually or\ + by using 'make distclean') +$(error ) +endif diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk new file mode 100644 index 000000000..d5423a397 --- /dev/null +++ b/src/Makefile.d/platform.mk @@ -0,0 +1,76 @@ +# +# Platform specific options. +# + +PKG_CONFIG?=pkg-config + +ifdef WINDOWSHELL +rmrf=-2>NUL DEL /S /Q +mkdir=-2>NUL MD +cat=TYPE +else +rmrf=rm -rf +mkdir=mkdir -p +cat=cat +endif + +ifdef LINUX64 +LINUX=1 +endif + +ifdef MINGW64 +MINGW=1 +endif + +ifdef LINUX +UNIX=1 +ifdef LINUX64 +NONX86=1 +# LINUX64 does not imply X86_64=1; +# could mean ARM64 or Itanium +platform=linux/64 +else +platform=linux +endif +else ifdef FREEBSD +UNIX=1 +platform=freebsd +else ifdef HAIKU +# Give Haiku its own configuration, since it +# isn't actually UNIX. +include Makefile.d/haiku.mk +else ifdef SOLARIS # FIXME: UNTESTED +UNIX=1 +platform=solaris +else ifdef CYGWIN32 # FIXME: UNTESTED +platform=cygwin +else ifdef MINGW +ifdef MINGW64 +NONX86=1 +NOASM=1 +# MINGW64 should not necessarily imply X86_64=1, +# but we make that assumption elsewhere +# Once that changes, remove this +X86_64=1 +platform=mingw/64 +else +platform=mingw +endif +include Makefile.d/win32.mk +endif + +ifdef platform +makedir:=$(makedir)/$(platform) +endif + +ifdef UNIX +include Makefile.d/nix.mk +endif + +ifeq ($(SDL), 1) +include Makefile.d/sdl.mk +else ifeq ($(DEDICATED), 1) +include Makefile.d/dedicated.mk +else +include Makefile.d/dummy.mk +endif diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk new file mode 100644 index 000000000..9f2074d9d --- /dev/null +++ b/src/Makefile.d/sdl.mk @@ -0,0 +1,71 @@ +# +# Makefile options for SDL2 backend. +# + +# +# SDL...., *looks at Alam*, THIS IS A MESS! +# +# ...a little bird flexes its muscles... +# + +makedir:=$(makedir)/SDL + +sources+=$(call List,sdl/Sourcefile) +opts+=-DDIRECTFULLSCREEN -DHAVE_SDL + +NOUPNP=1 + +# FIXME: UNTESTED +#ifdef PANDORA +#include sdl/SRB2Pandora/Makefile.cfg +#endif #ifdef PANDORA + +# FIXME: UNTESTED +#ifdef CYGWIN32 +#include sdl/MakeCYG.cfg +#endif #ifdef CYGWIN32 + +ifndef NOHW +sources+=sdl/ogl_sdl.c +endif + +ifdef NOMIXER +sources+=sdl/sdl_sound.c +else +opts+=-DHAVE_MIXER +sources+=sdl/mixer_sound.c + + ifndef HAIKU # Haiku has a special import path + libs+=-lSDL2_mixer + endif +endif + +ifndef NOTHREADS +opts+=-DHAVE_THREADS +sources+=sdl/i_threads.c +endif + +ifdef SDL_PKGCONFIG +$(eval $(call Use_pkg_config,SDL)) +else +SDL_CONFIG?=$(call Prefix,sdl2-config) +SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) +SDL_LDFLAGS?=$(shell $(SDL_CONFIG) \ + $(if $(STATIC),--static-libs,--libs)) +$(eval $(call Propogate_flags,SDL)) +endif + +ifdef MINGW +ifndef NOSDLMAIN +SDLMAIN=1 +endif +endif + +ifdef SDLMAIN +opts+=-DSDLMAIN +else +ifdef MINGW +opts+=-Umain +libs+=-mconsole +endif +endif diff --git a/src/Makefile.d/util.mk b/src/Makefile.d/util.mk new file mode 100644 index 000000000..bda68df13 --- /dev/null +++ b/src/Makefile.d/util.mk @@ -0,0 +1,93 @@ +# +# Utility macros for the rest of the Makefiles. +# + +Ifnot=$(if $(1),$(3),$(2)) +Ifndef=$(call Ifnot,$($(1)),$(2),$(3)) + +# Match and expand a list of variables by pattern. +Wildvar=$(foreach v,$(filter $(1),$(.VARIABLES)),$($(v))) + +# Read a list of words from file and prepend each with the +# directory of the file. +_cat=$(shell $(cat) $(call Windows_path,$(1))) +List=$(addprefix $(dir $(1)),$(call _cat,$(1))) + +# Convert path separators to backslash on Windows. +Windows_path=$(if $(WINDOWSHELL),$(subst /,\,$(1)),$(1)) + +define Propogate_flags = +opts+=$$($(1)_CFLAGS) +libs+=$$($(1)_LDFLAGS) +endef + +# Set library's _CFLAGS and _LDFLAGS from some command. +# Automatically propogates the flags too. +# 1: variable prefix (e.g. CURL) +# 2: start of command (e.g. curl-config) +# --- optional ---- +# 3: CFLAGS command arguments, default '--cflags' +# 4: LDFLAGS command arguments, default '--libs' +# 5: common command arguments at the end of command +define Configure = +$(1)_CFLAGS?=$$(shell $(2) $(or $(3),--cflags) $(5)) +$(1)_LDFLAGS?=$$(shell $(2) $(or $(4),--libs) $(5)) +$(call Propogate_flags,$(1)) +endef + +# Configure library with pkg-config. The package name is +# taken from a _PKGCONFIG variable. +# 1: variable prefix +# +# LIBGME_PKGCONFIG=libgme +# $(eval $(call Use_pkg_config,LIBGME)) +define Use_pkg_config = +$(call Configure,$(1),$(PKG_CONFIG),,,$($(1)_PKGCONFIG)) +endef + +# Check disabling flag and configure package in one step +# according to delimited argument. +# (There is only one argument, but it split by slash.) +# 1/: short form library name (uppercase). This is +# prefixed with 'NO' and 'HAVE_'. E.g. NOGME, HAVE_GME +# /2: package name (e.g. libgme) +# /3: variable prefix +# +# The following example would check if NOGME is not +# defined before attempting to define LIBGME_CFLAGS and +# LIBGME_LDFLAGS as with Use_pkg_config. +# +# $(eval $(call Check_pkg_config,GME/libgme/LIBGME)) +define Check_pkg_config = +_p:=$(subst /, ,$(1)) +_v1:=$$(word 1,$$(_p)) +_v2:=$$(or $$(word 3,$$(_p)),$$(_v1)) +ifndef NO$$(_v1) +$$(_v2)_PKGCONFIG?=$$(word 2,$$(_p)) +$$(eval $$(call Use_pkg_config,$$(_v2))) +opts+=-DHAVE_$$(_v1) +endif +endef + +# $(call Prefix,gcc) +Prefix=$(if $(PREFIX),$(PREFIX)-)$(1) + +Echo= +Echo_name= +Print= + +ifndef SILENT +Echo=@echo $(1) +ifndef ECHO +ifndef NOECHOFILENAMES +Echo_name=$(call Echo,-- $(1) ...) +endif +endif +ifndef MAKE_RESTARTS +ifndef destructive +Print=$(info $(1)) +endif +endif +endif + +.=$(call Ifndef,ECHO,@) diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk new file mode 100644 index 000000000..7c130d908 --- /dev/null +++ b/src/Makefile.d/versions.mk @@ -0,0 +1,174 @@ +# +# Flags to put a sock in GCC! +# + +# See the versions list in detect.mk +# This will define all version flags going backward. +# Yes, it's magic. +define _predecessor = +ifdef GCC$(firstword $(1)) +GCC$(lastword $(1)):=1 +endif +endef +_n:=$(words $(gcc_versions)) +$(foreach v,$(join $(wordlist 2,$(_n),- $(gcc_versions)),\ + $(addprefix =,$(wordlist 2,$(_n),$(gcc_versions)))),\ + $(and $(findstring =,$(v)),\ + $(eval $(call _predecessor,$(subst =, ,$(v)))))) + +# -W -Wno-unused +WFLAGS:=-Wall -Wno-trigraphs +ifndef GCC295 +#WFLAGS+=-Wno-packed +endif +ifndef RELAXWARNINGS + WFLAGS+=-W +#WFLAGS+=-Wno-sign-compare +ifndef GCC295 + WFLAGS+=-Wno-div-by-zero +endif +#WFLAGS+=-Wsystem-headers +WFLAGS+=-Wfloat-equal +#WFLAGS+=-Wtraditional + WFLAGS+=-Wundef +ifndef GCC295 + WFLAGS+=-Wendif-labels +endif +ifdef GCC41 + WFLAGS+=-Wshadow +endif +#WFLAGS+=-Wlarger-than-%len% + WFLAGS+=-Wpointer-arith -Wbad-function-cast +ifdef GCC45 +#WFLAGS+=-Wc++-compat +endif + WFLAGS+=-Wcast-qual +ifndef NOCASTALIGNWARN + WFLAGS+=-Wcast-align +endif + WFLAGS+=-Wwrite-strings +ifndef ERRORMODE +#WFLAGS+=-Wconversion +ifdef GCC43 + #WFLAGS+=-Wno-sign-conversion +endif +endif + WFLAGS+=-Wsign-compare +ifdef GCC91 + WFLAGS+=-Wno-error=address-of-packed-member +endif +ifdef GCC45 + WFLAGS+=-Wlogical-op +endif + WFLAGS+=-Waggregate-return +ifdef HAIKU +ifdef GCC41 + #WFLAGS+=-Wno-attributes +endif +endif +#WFLAGS+=-Wstrict-prototypes +ifdef GCC40 + WFLAGS+=-Wold-style-definition +endif + WFLAGS+=-Wmissing-prototypes -Wmissing-declarations +ifdef GCC40 + WFLAGS+=-Wmissing-field-initializers +endif + WFLAGS+=-Wmissing-noreturn +#WFLAGS+=-Wmissing-format-attribute +#WFLAGS+=-Wno-multichar +#WFLAGS+=-Wno-deprecated-declarations +#WFLAGS+=-Wpacked +#WFLAGS+=-Wpadded +#WFLAGS+=-Wredundant-decls + WFLAGS+=-Wnested-externs +#WFLAGS+=-Wunreachable-code + WFLAGS+=-Winline +ifdef DEBUGMODE + WFLAGS+=-Wno-error=inline +endif +ifdef GCC43 + WFLAGS+=-funit-at-a-time + WFLAGS+=-Wlogical-op +endif +ifndef GCC295 + WFLAGS+=-Wdisabled-optimization +endif +endif +WFLAGS+=-Wformat-y2k +ifdef GCC71 +WFLAGS+=-Wno-error=format-overflow=2 +endif +WFLAGS+=-Wformat-security +ifndef GCC29 +#WFLAGS+=-Winit-self +endif +ifdef GCC46 +WFLAGS+=-Wno-suggest-attribute=noreturn +endif + +ifdef NOLDWARNING +LDFLAGS+=-Wl,--as-needed +endif + +ifdef ERRORMODE +WFLAGS+=-Werror +endif + +ifdef GCC43 + #WFLAGS+=-Wno-error=clobbered +endif +ifdef GCC44 +#WFLAGS+=-Wno-error=array-bounds +endif +ifdef GCC46 + WFLAGS+=-Wno-error=suggest-attribute=noreturn +endif +ifdef GCC54 + WFLAGS+=-Wno-logical-op -Wno-error=logical-op +endif +ifdef GCC61 + WFLAGS+=-Wno-tautological-compare -Wno-error=tautological-compare +endif +ifdef GCC71 + WFLAGS+=-Wimplicit-fallthrough=4 +endif +ifdef GCC81 + WFLAGS+=-Wno-error=format-overflow + WFLAGS+=-Wno-format-overflow + WFLAGS+=-Wno-error=multistatement-macros +endif + +ifdef NONX86 + ifdef X86_64 # yeah that SEEMS contradictory + opts+=-march=nocona + endif +else + ifndef GCC29 + opts+=-msse3 -mfpmath=sse + else + opts+=-mpentium + endif +endif + +ifdef DEBUGMODE +ifdef GCC48 +opts+=-Og +else +opts+=-O0 +endif +endif + +ifdef VALGRIND +ifdef GCC46 +WFLAGS+=-Wno-error=unused-but-set-variable +WFLAGS+=-Wno-unused-but-set-variable +endif +endif + +# Lua +ifdef GCC43 +ifndef GCC44 +WFLAGS+=-Wno-logical-op +endif +endif diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk new file mode 100644 index 000000000..353c666ee --- /dev/null +++ b/src/Makefile.d/win32.mk @@ -0,0 +1,124 @@ +# +# Mingw, if you don't know, that's Win32/Win64 +# + +ifndef MINGW64 +EXENAME?=srb2kart-saturn_32bit.exe +else +EXENAME?=srb2kart-saturn_64bit.exe +endif + +# disable dynamicbase if under msys2 +ifdef MSYSTEM +libs+=-Wl,--disable-dynamicbase +endif + +sources+=win32/Srb2win.rc +opts+=-DSTDC_HEADERS +libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 + +ifndef DEDICATED +ifndef DUMMY +SDL?=1 +endif +endif + +ifndef NOHW +opts+=-DUSE_WGL_SWAP +endif + +ifdef MINGW64 +libs+=-lws2_32 +else +#ifndef HAVE_IPV6 +#libs+=-lwsock32 +#else +libs+=-lws2_32 +#endif +endif + +ifndef MINGW64 +libs+=--large-address-aware +NOLIBBACKTRACE=1 +endif + +ifndef MINGW64 +32=32 +x86=x86 +i686=i686 +else +32=64 +x86=x86_64 +i686=x86_64 +endif + +mingw:=$(i686)-w64-mingw32 + +define _set = +$(1)_CFLAGS?=$($(1)_opts) +$(1)_LDFLAGS?=$($(1)_libs) +endef + +lib:=../libs/gme +LIBGME_opts:=-I$(lib)/include +LIBGME_libs:=-L$(lib)/win$(32) -lgme +$(eval $(call _set,LIBGME)) + +lib:=../libs/libopenmpt +LIBOPENMPT_opts:=-I$(lib)/inc +LIBOPENMPT_libs:=-L$(lib)/lib/$(x86)/mingw -lopenmpt +$(eval $(call _set,LIBOPENMPT)) + +lib:=../libs/SDL2_mixer/$(mingw) + +ifdef SDL +mixer_opts:=-I$(lib)/include/SDL2 +mixer_libs:=-L$(lib)/lib + +lib:=../libs/SDL2/$(mingw) +SDL_opts:=-I$(lib)/include/SDL2\ + $(mixer_opts) -Dmain=SDL_main +SDL_libs:=-L$(lib)/lib $(mixer_libs)\ + -lmingw32 -lSDL2main -lSDL2 -mwindows +$(eval $(call _set,SDL)) +endif + +ifdef MINGW64 +lib:=../libs/libbacktrace +LIBBACKTRACE_opts:=-I$(lib)/include +LIBBACKTRACE_libs:=-L$(lib)/lib/x86_64 -lbacktrace +$(eval $(call _set,LIBBACKTRACE)) +else +lib:=../libs/drmingw +opts+=-I$(lib)/include +libs+=-L$(lib)/lib/win32 -lmgwhelp -lexchndl +endif + +lib:=../libs/zlib +ZLIB_opts:=-I$(lib) +ZLIB_libs:=-L$(lib)/win32 -l:libz$(32).a +$(eval $(call _set,ZLIB)) + +ifndef PNG_CONFIG +lib:=../libs/libpng-src +PNG_opts:=-I$(lib) +PNG_libs:=-L$(lib)/projects -lpng$(32) +$(eval $(call _set,PNG)) +endif + +lib:=../libs/curl +CURL_opts:=-I$(lib)/include +CURL_libs:=-L$(lib)/lib$(32) -lcurl +$(eval $(call _set,CURL)) + +ifndef MINGW64 # miniupnc is broken with MINGW64 +lib:=../libs/miniupnpc +MINIUPNPC_opts:=-I$(lib)/include -DMINIUPNP_STATICLIB +MINIUPNPC_libs:=-L$(lib)/mingw$(32) -lminiupnpc -lws2_32 -liphlpapi +$(eval $(call _set,MINIUPNPC)) +endif + +lib:=../libs/discord-rpc/win$(32)-dynamic +DISCORDRPC_opts+=-I$(lib)/include +DISCORDRPC_libs+=-L$(lib)/lib -ldiscord-rpc +$(eval $(call _set,DISCORDRPC)) diff --git a/src/Sourcefile b/src/Sourcefile new file mode 100644 index 000000000..4d117111d --- /dev/null +++ b/src/Sourcefile @@ -0,0 +1,97 @@ +am_map.c +b_bot.c +command.c +console.c +d_clisrv.c +d_main.c +d_net.c +d_netcmd.c +d_netfil.c +d_protocol.c +dehacked.c +f_finale.c +f_wipe.c +filesrch.c +g_game.c +g_input.c +hu_stuff.c +i_tcp.c +i_time.c +info.c +lzf.c +m_aatree.c +m_anigif.c +m_argv.c +m_bbox.c +m_cheat.c +m_cond.c +m_fixed.c +m_menu.c +m_textinput.c +m_misc.c +m_perfstats.c +m_queue.c +m_random.c +mserv.c +http-mserv.c +qs22j.c +s_sound.c +screen.c +sounds.c +st_stuff.c +string.c +tables.c +v_video.c +w_wad.c +y_inter.c +z_zone.c +r_bsp.c +r_data.c +r_draw.c +r_fps.c +r_main.c +r_patch.c +r_patchrotation.c +r_plane.c +r_segs.c +r_sky.c +r_splats.c +r_things.c +r_portal.c +p_ceilng.c +p_enemy.c +p_floor.c +p_inter.c +p_lights.c +p_map.c +p_maputl.c +p_mobj.c +p_polyobj.c +p_saveg.c +p_setup.c +p_sight.c +p_slopes.c +p_spec.c +p_telept.c +p_tick.c +p_user.c +k_director.c +k_kart.c +k_stats.c +lua_baselib.c +lua_blockmaplib.c +lua_consolelib.c +lua_hooklib.c +lua_hudlib.c +lua_hudlib_drawlist.c +lua_infolib.c +lua_maplib.c +lua_mathlib.c +lua_mobjlib.c +lua_playerlib.c +lua_script.c +lua_skinlib.c +lua_thinkerlib.c +lua_udatalib.c +lua_glib.c +hashtable.c diff --git a/src/blua/Sourcefile b/src/blua/Sourcefile new file mode 100644 index 000000000..da89f45a4 --- /dev/null +++ b/src/blua/Sourcefile @@ -0,0 +1,26 @@ +lapi.c +lauxlib.c +lbaselib.c +ldblib.c +lcode.c +ldebug.c +ldo.c +ldump.c +lfunc.c +lgc.c +linit.c +liolib.c +llex.c +lmem.c +lobject.c +lopcodes.c +lparser.c +lstate.c +lstring.c +lstrlib.c +ltable.c +ltablib.c +ltm.c +lundump.c +lvm.c +lzio.c diff --git a/src/d_main.c b/src/d_main.c index 728a1a760..79e06285e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1607,7 +1607,9 @@ void D_SRB2Main(void) #endif // for dedicated server +#if !defined (DEDICATED) dedicated = M_CheckParm("-dedicated") != 0; +#endif strcpy(title, "SRB2Kart"); strcpy(srb2, "SRB2Kart"); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5b8a8c18b..cf72835db 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -305,14 +305,12 @@ consvar_t cv_verticallook[MAXSPLITSCREENPLAYERS] = { {"verticallook4", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL} }; -#if defined(HAVE_SDL) || defined(_WINDOWS) //joystick 1 and 2 consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS] = { {"use_joystick", "1", CV_SAVE|CV_CALL, NULL, I_InitJoystick1, 0, NULL, NULL, 0, 0, NULL}, {"use_joystick2", "2", CV_SAVE|CV_CALL, NULL, I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}, {"use_joystick3", "3", CV_SAVE|CV_CALL, NULL, I_InitJoystick3, 0, NULL, NULL, 0, 0, NULL}, {"use_joystick4", "4", CV_SAVE|CV_CALL, NULL, I_InitJoystick4, 0, NULL, NULL, 0, 0, NULL} }; -#endif #if defined (HAVE_SDL) consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { diff --git a/src/dedicated/CMakeLists.txt b/src/dedicated/CMakeLists.txt new file mode 100644 index 000000000..36f670251 --- /dev/null +++ b/src/dedicated/CMakeLists.txt @@ -0,0 +1,108 @@ +# Declare dedicated interface sources + +target_sourcefile(c) + +target_sources(SRB2SDL2 PRIVATE) + +if(${CMAKE_SYSTEM} MATCHES Windows) + target_sources(SRB2SDL2 PRIVATE + ../win32/win_dbg.c + ../win32/Srb2win.rc) +endif() + +if(${CMAKE_SYSTEM} MATCHES Windows) + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2legacy) +elseif(${CMAKE_SYSTEM} MATCHES Linux) + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME lsrb2dlegacy) +else() + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2legacy) +endif() + +if(${CMAKE_SYSTEM} MATCHES Darwin) + find_library(CORE_LIB CoreFoundation) + target_link_libraries(SRB2SDL2 PRIVATE + ${CORE_LIB} + ${PNG_LIBRARIES} + ${ZLIB_LIBRARIES} + ) + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}") +else() + target_link_libraries(SRB2SDL2 PRIVATE + ${PNG_LIBRARIES} + ${ZLIB_LIBRARIES} + ) + + if(${CMAKE_SYSTEM} MATCHES Linux) + target_link_libraries(SRB2SDL2 PRIVATE + m + rt + ) + endif() +endif() + +#target_link_libraries(SRB2SDL2 PRIVATE SRB2Core) + +set_target_properties(SRB2SDL2 PROPERTIES VERSION ${SRB2_VERSION}) + +if(${CMAKE_SYSTEM} MATCHES Windows) + target_link_libraries(SRB2SDL2 PRIVATE + ws2_32 + ) + target_compile_options(SRB2SDL2 PRIVATE + -U_WINDOWS + ) +endif() + +target_include_directories(SRB2SDL2 PRIVATE + ${PNG_INCLUDE_DIRS} + ${ZLIB_INCLUDE_DIRS} +) + +target_compile_definitions(SRB2SDL2 PRIVATE + -DDEDICATED +) + +## strip debug symbols into separate file when using gcc +if(CMAKE_COMPILER_IS_GNUCC) + if(${CMAKE_BUILD_TYPE} MATCHES Debug) + message(STATUS "Will make separate debug symbols in *.debug") + add_custom_command(TARGET SRB2SDL2 POST_BUILD + COMMAND ${OBJCOPY} --only-keep-debug $ $.debug + COMMAND ${OBJCOPY} --strip-debug $ + COMMAND ${OBJCOPY} --add-gnu-debuglink=$.debug $ + ) + endif() +endif() + +#### Installation #### +if(${CMAKE_SYSTEM} MATCHES Darwin) + install(TARGETS SRB2SDL2 + BUNDLE DESTINATION . + ) +else() + install(TARGETS SRB2SDL2 SRB2SDL2 + RUNTIME DESTINATION . + ) +endif() + +# Mac bundle fixup +# HACK: THIS IS IMPORTANT! See the escaped \${CMAKE_INSTALL_PREFIX}? This +# makes it so that var is evaluated LATER during cpack, not right now! +# This fixes the quirk where the bundled libraries don't land in the final package +# https://cmake.org/pipermail/cmake/2011-March/043532.html +# +# HOWEVER: ${CPACK_PACKAGE_DESCRIPTION_SUMMARY} is NOT escaped, because that var +# is only available to us at this step. Read the link: ${CMAKE_INSTALL_PREFIX} at +# this current step points to the CMAKE build folder, NOT the folder that CPACK uses. +# Therefore, it makes sense to escape that var, but not the other. +if(${CMAKE_SYSTEM} MATCHES Darwin) + install(CODE " + include(BundleUtilities) + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/${CPACK_PACKAGE_DESCRIPTION_SUMMARY}.app\" + \"\" + /Library/Frameworks + )" + ) +endif() + +set(SRB2_SDL2_AVAILABLE YES PARENT_SCOPE) diff --git a/src/dedicated/Sourcefile b/src/dedicated/Sourcefile new file mode 100644 index 000000000..176e60a96 --- /dev/null +++ b/src/dedicated/Sourcefile @@ -0,0 +1,7 @@ +i_system.c +i_main.c +i_video.c +i_sound.c +i_threads.c +dosstr.c +endtxt.c diff --git a/src/dedicated/dosstr.c b/src/dedicated/dosstr.c new file mode 100644 index 000000000..f9bbee9b4 --- /dev/null +++ b/src/dedicated/dosstr.c @@ -0,0 +1,38 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// This file is in the public domain. +// (Re)written by Graue in 2006. +// +//----------------------------------------------------------------------------- +/// \file +/// \brief String uppercasing/lowercasing functions for non-DOS non-Win32 +/// systems + +#include "../doomtype.h" + +#ifndef HAVE_DOSSTR_FUNCS + +#include + +int strupr(char *n) +{ + while (*n != '\0') + { + *n = toupper(*n); + n++; + } + return 1; +} + +int strlwr(char *n) +{ + while (*n != '\0') + { + *n = tolower(*n); + n++; + } + return 1; +} + +#endif diff --git a/src/dedicated/endtxt.c b/src/dedicated/endtxt.c new file mode 100644 index 000000000..1e72ca9a8 --- /dev/null +++ b/src/dedicated/endtxt.c @@ -0,0 +1,234 @@ +/* + * Function to write the SRB2 end message text + * + * Copyright (C) 1998 by Udo Munk + * + * This code is provided AS IS and there are no guarantees, none. + * Feel free to share and modify. + */ +//----------------------------------------------------------------------------- +/// \file +/// \brief Support to show ENDOOM text +/// +/// Loads the lump ENDOOM, set up the console to print +/// out the colors and text + +#include +#include + +// need this 19990118 by Kin +#include "../doomdef.h" +#include "../w_wad.h" +#include "../z_zone.h" +#include "endtxt.h" +/** \brief The ShowEndTxt function + + + Prints out the ENDOOM the way DOOM.EXE/DOOM2.EXE did for Win32 or Linux/GNU + + \return void + + +*/ + +void ShowEndTxt(void) +{ + INT32 i; + UINT16 j, att = 0; + INT32 nlflag = 1; +#ifdef _WIN32 + HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD mode, bytesWritten; + CONSOLE_SCREEN_BUFFER_INFO backupcon; + COORD resizewin = {80,-1}; + CHAR let = 0; +#endif + UINT16 *ptext; + void *data; + lumpnum_t endoomnum = W_GetNumForName("ENDOOM"); + //char *col; + + /* if the xterm has more then 80 columns we need to add nl's */ + /* doesn't work, COLUMNS is not in the environment at this time ??? + col = I_getenv("COLUMNS"); + if (col) { + if (atoi(col) > 80) + nlflag++; + } + */ + + /* get the lump with the text */ + data = ptext = W_CacheLumpNum(endoomnum, PU_CACHE); + +#ifdef _WIN32 + if (co == INVALID_HANDLE_VALUE || GetFileType(co) != FILE_TYPE_CHAR || !GetConsoleMode(co, &mode)) // test if it a good handle + { + Z_Free(data); + return; + } + + backupcon.wAttributes = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; // Just in case + GetConsoleScreenBufferInfo(co, &backupcon); //Store old state + resizewin.Y = backupcon.dwSize.Y; + if (backupcon.dwSize.X < resizewin.X) + SetConsoleScreenBufferSize(co, resizewin); + + for (i=1; i<=80*25; i++) // print 80x25 text and deal with the attributes too + { + j = (UINT16)(*ptext >> 8); // attribute first + let = (char)(*ptext & 0xff); // text second + if (j != att) // attribute changed? + { + att = j; // save current attribute + SetConsoleTextAttribute(co, j); //set fg and bg color for buffer + } + + WriteConsoleA(co, &let, 1, &bytesWritten, NULL); // now the text + + if (nlflag && !(i % 80) && backupcon.dwSize.X > resizewin.X) // do we need a nl? + { + att = backupcon.wAttributes; + SetConsoleTextAttribute(co, att); // all attributes off + WriteConsoleA(co, "\n", 1, &bytesWritten, NULL); // newline to console + } + ptext++; + } + SetConsoleTextAttribute(co, backupcon.wAttributes); // all attributes off +#else + /* print 80x25 text and deal with the attributes too */ + for (i=1; i<=80*25; i++) { + /* attribute first */ + /* attribute changed? */ + if ((j = *ptext >> 8) != att) { + /* save current attribute */ + att = j; + /* set new attribute, forground color first */ + printf("\033["); + switch (j & 0x0f) { + case 0: /* black */ + printf("30"); + break; + case 1: /* blue */ + printf("34"); + break; + case 2: /* green */ + printf("32"); + break; + case 3: /* cyan */ + printf("36"); + break; + case 4: /* red */ + printf("31"); + break; + case 5: /* magenta */ + printf("35"); + break; + case 6: /* brown */ + printf("33"); + break; + case 7: /* bright grey */ + printf("37"); + break; + case 8: /* dark grey */ + printf("1;30"); + break; + case 9: /* bright blue */ + printf("1;34"); + break; + case 10: /* bright green */ + printf("1;32"); + break; + case 11: /* bright cyan */ + printf("1;36"); + break; + case 12: /* bright red */ + printf("1;31"); + break; + case 13: /* bright magenta */ + printf("1;35"); + break; + case 14: /* yellow */ + printf("1;33"); + break; + case 15: /* white */ + printf("1;37"); + break; + } + printf("m"); + /* now background color */ + printf("\033["); + switch ((j >> 4) & 0x0f) { + case 0: /* black */ + printf("40"); + break; + case 1: /* blue */ + printf("44"); + break; + case 2: /* green */ + printf("42"); + break; + case 3: /* cyan */ + printf("46"); + break; + case 4: /* red */ + printf("41"); + break; + case 5: /* magenta */ + printf("45"); + break; + case 6: /* brown */ + printf("43"); + break; + case 7: /* bright grey */ + printf("47"); + break; + case 8: /* dark grey */ + printf("1;40"); + break; + case 9: /* bright blue */ + printf("1;44"); + break; + case 10: /* bright green */ + printf("1;42"); + break; + case 11: /* bright cyan */ + printf("1;46"); + break; + case 12: /* bright red */ + printf("1;41"); + break; + case 13: /* bright magenta */ + printf("1;45"); + break; + case 14: /* yellow */ + printf("1;43"); + break; + case 15: /* white */ + printf("1;47"); + break; + } + printf("m"); + } + + /* now the text */ + printf("%c",*ptext++ & 0xff); + + /* do we need a nl? */ + if (nlflag) + { + if (!(i % 80)) + { + printf("\033[0m"); + att = 0; + printf("\n"); + } + } + } + /* all attributes off */ + printf("\033[0m"); +#endif + if (nlflag) + printf("\n"); + + Z_Free(data); +} diff --git a/src/dedicated/endtxt.h b/src/dedicated/endtxt.h new file mode 100644 index 000000000..41f8e51ad --- /dev/null +++ b/src/dedicated/endtxt.h @@ -0,0 +1,24 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief Support to show ENDOOM text + +#ifndef __ENDTXT__ +#define __ENDTXT__ + +void ShowEndTxt (void); + +#endif diff --git a/src/dedicated/i_main.c b/src/dedicated/i_main.c new file mode 100644 index 000000000..911e356d0 --- /dev/null +++ b/src/dedicated/i_main.c @@ -0,0 +1,238 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief Main program, simply calls D_SRB2Main and D_SRB2Loop, the high level loop. + +#include "../doomdef.h" +#include "../m_argv.h" +#include "../d_main.h" +#include "../m_misc.h" /* path shit */ +#include "../i_system.h" +#include "../d_clisrv.h" + +#if defined (__GNUC__) || defined (__unix__) +#include +#endif + +#ifdef __unix__ +#include +#endif + +#include "time.h" // For log timestamps + +#ifdef HAVE_TTF +#include "i_ttf.h" +#endif + +#ifdef HAVE_LIBBACKTRACE +#include + +struct backtrace_state *bt_state = NULL; +#endif + +#ifdef LOGMESSAGES +FILE *logstream = NULL; +char logfilename[1024]; +#endif + +#ifndef DOXYGEN +#ifndef O_TEXT +#define O_TEXT 0 +#endif + +#ifndef O_SEQUENTIAL +#define O_SEQUENTIAL 0 +#endif +#endif + +#ifdef _WIN32 +#ifndef _AMD64_ +#include "exchndl.h" +#define DRMINGW +#endif +#endif + +#if defined (_WIN32) +#include "../win32/win_dbg.h" +typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID); +#endif + +#ifdef _WIN32 +static void +ChDirToExe (void) +{ + CHAR path[MAX_PATH]; + if (GetModuleFileNameA(NULL, path, MAX_PATH) > 0) + { + strrchr(path, '\\')[0] = '\0'; + SetCurrentDirectoryA(path); + } +} +#endif + +/** \brief The main function + + \param argc number of arg + \param *argv string table + + \return int +*/ +#if defined (__GNUC__) && (__GNUC__ >= 4) +#pragma GCC diagnostic ignored "-Wmissing-noreturn" +#endif + +#ifdef LOGMESSAGES +static void InitLogging(void) +{ + const char *logdir = NULL; + time_t my_time; + struct tm * timeinfo; + const char *format; + const char *reldir; + int left; + boolean fileabs; +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + const char *link; +#endif + + logdir = D_Home(); + + my_time = time(NULL); + timeinfo = localtime(&my_time); + + if (M_CheckParm("-logfile") && M_IsNextParm()) + { + format = M_GetNextParm(); + fileabs = M_IsPathAbsolute(format); + } + else + { + format = "log-%Y-%m-%d_%H-%M-%S.txt"; + fileabs = false; + } + + if (fileabs) + { + strftime(logfilename, sizeof logfilename, format, timeinfo); + } + else + { + if (M_CheckParm("-logdir") && M_IsNextParm()) + reldir = M_GetNextParm(); + else + reldir = "logs"; + + if (M_IsPathAbsolute(reldir)) + { + left = snprintf(logfilename, sizeof logfilename, + "%s"PATHSEP, reldir); + } + else +#ifdef DEFAULTDIR + if (logdir) + { + left = snprintf(logfilename, sizeof logfilename, + "%s"PATHSEP DEFAULTDIR PATHSEP"%s"PATHSEP, logdir, reldir); + } + else +#endif/*DEFAULTDIR*/ + { + left = snprintf(logfilename, sizeof logfilename, + "."PATHSEP"%s"PATHSEP, reldir); + } + + strftime(&logfilename[left], sizeof logfilename - left, + format, timeinfo); + } + + M_MkdirEachUntil(logfilename, + M_PathParts(logdir) - 1, + M_PathParts(logfilename) - 1, 0755); + +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + logstream = fopen(logfilename, "w"); +#ifdef DEFAULTDIR + if (logdir) + link = va("%s/"DEFAULTDIR"/latest-log.txt", logdir); + else +#endif/*DEFAULTDIR*/ + link = "latest-log.txt"; + unlink(link); + if (symlink(logfilename, link) == -1) + { + I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); + } +#else/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ + logstream = fopen("latest-log.txt", "wt+"); +#endif/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ +} +#endif + +int main(int argc, char **argv) +{ + myargc = argc; + myargv = argv; /// \todo pull out path to exe from this string + + dedicated = true; + +#ifdef HAVE_LIBBACKTRACE + bt_state = backtrace_create_state( + argv[0], +#ifdef HAVE_THREADS + 1, +#else + 0, +#endif + NULL, + NULL + ); +#endif + +#ifdef _WIN32 + ChDirToExe(); +#endif + +#ifdef LOGMESSAGES + if (!M_CheckParm("-nolog")) + InitLogging(); +#endif/*LOGMESSAGES*/ + + //I_OutputMsg("I_StartupSystem() ...\n"); + I_StartupSystem(); +#if defined (_WIN32) + { +#ifdef DRMINGW + ExcHndlInit(); +#endif + } +#endif + + // startup SRB2 + CONS_Printf("Setting up SRB2Kart...\n"); + D_SRB2Main(); + CONS_Printf("Entering main game loop...\n"); + // never return + D_SRB2Loop(); + +#ifdef BUGTRAP + // This is safe even if BT didn't start. + ShutdownBugTrap(); +#endif + + // return to OS + return 0; +} diff --git a/src/dedicated/i_sound.c b/src/dedicated/i_sound.c new file mode 100644 index 000000000..de43aab85 --- /dev/null +++ b/src/dedicated/i_sound.c @@ -0,0 +1,339 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by 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. +// +// The source 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief SDL interface for sound + +#include +#include "../doomdef.h" +#include "../i_sound.h" +#include "../s_sound.h" + +/** \brief Sound subsystem runing and waiting +*/ +UINT8 sound_started = false; + +/** \brief The I_GetSfx function + + \param sfx sfx to setup + + \return data for sfx +*/ +void *I_GetSfx(sfxinfo_t *sfx) +{ + (void)sfx; + return NULL; +} + +/** \brief The I_FreeSfx function + + \param sfx sfx to be freed up + + \return void +*/ +void I_FreeSfx(sfxinfo_t *sfx) +{ + (void)sfx; +} + +/** \brief Init at program start... +*/ +void I_StartupSound(void){} + +/** \brief ... shut down and relase at program termination. +*/ +void I_ShutdownSound(void){} + +/// ------------------------ +/// SFX I/O +/// ------------------------ + +/** \brief Starts a sound in a particular sound channel. + \param id sfxid + \param vol volume for sound + \param sep left-right balancle + \param pitch not used + \param priority not used + + \return sfx handle +*/ +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) +{ + (void)id; + (void)vol; + (void)sep; + (void)pitch; + (void)priority; + (void)channel; + return 0; +} + +/** \brief Stops a sound channel. + + \param handle stop sfx handle + + \return void +*/ +void I_StopSound(INT32 handle) +{ + (void)handle; +} + +/** \brief Some digital sound drivers need this. +*/ +void I_UpdateSound(void){} + +/** \brief Called by S_*() functions to see if a channel is still playing. + + \param handle sfx handle + + \return 0 if no longer playing, 1 if playing. +*/ +boolean I_SoundIsPlaying(INT32 handle) +{ + (void)handle; + return false; +} + +/** \brief Updates the sfx handle + + \param handle sfx handle + \param vol volume + \param sep separation + \param pitch ptich + + \return void +*/ +void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) +{ + (void)handle; + (void)vol; + (void)sep; + (void)pitch; +} + +/** \brief The I_SetSfxVolume function + + \param volume volume to set at + + \return void +*/ +void I_SetSfxVolume(UINT8 volume) +{ + (void)volume; +} + +/// ------------------------ +// MUSIC SYSTEM +/// ------------------------ + +/** \brief Init the music systems +*/ +void I_InitMusic(void){} + +/** \brief Shutdown the music systems +*/ +void I_ShutdownMusic(void){} + +/// ------------------------ +// MUSIC PROPERTIES +/// ------------------------ + +musictype_t I_SongType(void) +{ + return MU_NONE; +} + +boolean I_SongPlaying(void) +{ + return false; +} + +boolean I_SongPaused(void) +{ + return false; +} + +/// ------------------------ +// MUSIC EFFECTS +/// ------------------------ + +boolean I_SetSongSpeed(float speed) +{ + (void)speed; + return false; +} + +/// ------------------------ +// MUSIC SEEKING +/// ------------------------ + +UINT32 I_GetSongLength(void) +{ + return 0; +} + +boolean I_SetSongLoopPoint(UINT32 looppoint) +{ + (void)looppoint; + return false; +} + +UINT32 I_GetSongLoopPoint(void) +{ + return 0; +} + +boolean I_SetSongPosition(UINT32 position) +{ + (void)position; + return false; +} + +UINT32 I_GetSongPosition(void) +{ + return 0; +} + +/// ------------------------ +// MUSIC PLAYBACK +/// ------------------------ + +/** \brief Registers a song handle to song data. + + \param data pointer to song data + \param len len of data + + \return song handle + + \todo Remove this +*/ +boolean I_LoadSong(char *data, size_t len) +{ + (void)data; + (void)len; + return false; +} + +/** \brief See ::I_LoadSong, then think backwards + + \param handle song handle + + \sa I_LoadSong + \todo remove midi handle +*/ +void I_UnloadSong(void){} + +/** \brief Called by anything that wishes to start music + + \param handle Song handle + \param looping looping it if true + + \return if true, it's playing the song + + \todo pass music name, not handle +*/ +boolean I_PlaySong(boolean looping) +{ + (void)looping; + return false; +} + +/** \brief Stops a song over 3 seconds + + \param handle Song handle + \return void + + /todo drop handle +*/ +void I_StopSong(void){} + +/** \brief PAUSE game handling. + + \param handle song handle + + \return void +*/ +void I_PauseSong(void){} + +/** \brief RESUME game handling + + \param handle song handle + + \return void +*/ +void I_ResumeSong(void){} + +/** \brief The I_SetMusicVolume function + + \param volume volume to set at + + \return void +*/ +void I_SetMusicVolume(UINT8 volume) +{ + (void)volume; +} + +boolean I_SetSongTrack(INT32 track) +{ + (void)track; + return false; +} + +/// ------------------------ +/// MUSIC FADING +/// ------------------------ + +void I_SetInternalMusicVolume(UINT8 volume) +{ + (void)volume; +} + +void I_StopFadingSong(void){} + +boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void)) +{ + (void)target_volume; + (void)source_volume; + (void)ms; + (void)callback; + return false; +} + +boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void)) +{ + (void)target_volume; + (void)ms; + (void)callback; + return false; +} + +boolean I_FadeOutStopSong(UINT32 ms) +{ + (void)ms; + return false; +} + +boolean I_FadeInPlaySong(UINT32 ms, boolean looping) +{ + (void)ms; + (void)looping; + return false; +} + +void I_UpdateSongLagThreshold(void) +{ +} diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c new file mode 100644 index 000000000..e568873f0 --- /dev/null +++ b/src/dedicated/i_system.c @@ -0,0 +1,2218 @@ +// Emacs style mode select -*- C++ -*- +// +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 2014-2018 by Sonic Team Junior. +// +// 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. +// +// Changes by Graue are in the public domain. +// +//----------------------------------------------------------------------------- +/// \file +/// \brief SRB2 system stuff for dedicated + +#ifdef CMAKECONFIG +#include "config.h" +#else +#include "../config.h.in" +#endif + +#include + +// A little more than the minimum sleep duration on Windows. +// May be incorrect for other platforms, but we don't currently have a way to +// query the scheduler granularity. SDL will do what's needed to make this as +// low as possible though. +#define MIN_SLEEP_DURATION_MS 2.1 + +#ifdef _WIN32 +#define RPC_NO_WINDOWS_H +#include +#include "../doomtype.h" +typedef BOOL (WINAPI *p_GetDiskFreeSpaceExA)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); +typedef BOOL (WINAPI *p_IsProcessorFeaturePresent) (DWORD); +typedef DWORD (WINAPI *p_timeGetTime) (void); +typedef UINT (WINAPI *p_timeEndPeriod) (UINT); +typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR); +typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); +#endif + +#include +#include +#include +#ifdef __GNUC__ +#include +#elif defined (_MSC_VER) +#include +#endif +#if defined (__unix__) || defined (UNIXCOMMON) +#include +#endif + +#include +#ifdef _WIN32 +#include +#endif + +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif + +#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) +#include +#if defined (__linux__) +#include +#else +#include +#include +/*For meminfo*/ +#include +#ifdef FREEBSD +#include +#endif +#include +#include +#endif +#endif + +#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) +#ifndef NOTERMIOS +#include +#include // ioctl +#define HAVE_TERMIOS +#endif +#endif + +#if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) +#include +#include +#include +#define NEWSIGNALHANDLER +#endif + +#ifndef NOMUMBLE +#ifdef __linux__ // need -lrt +#include +#ifdef MAP_FAILED +#define HAVE_SHM +#endif +#include +#endif + +#ifdef _WIN32 +#define HAVE_MUMBLE +#define WINMUMBLE +#elif defined (HAVE_SHM) +#define HAVE_MUMBLE +#endif +#endif // NOMUMBLE + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifdef __APPLE__ +#include "macosx/mac_resources.h" +#endif + +#ifndef errno +#include +#endif + +// Locations for searching the srb2.srb +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2Kart" +#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2Kart" +#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2Kart" +#define DEFAULTWADLOCATION4 "/usr/games/SRB2Kart" +#define DEFAULTSEARCHPATH1 "/usr/local/games" +#define DEFAULTSEARCHPATH2 "/usr/games" +#define DEFAULTSEARCHPATH3 "/usr/local" +#endif + +/** \brief WAD file to look for +*/ +#define WADKEYWORD1 "srb2.srb" +#define WADKEYWORD2 "srb2.wad" +/** \brief holds wad path +*/ +static char returnWadPath[256]; + +#include "../doomdef.h" +#include "../m_misc.h" +#include "../i_video.h" +#include "../i_sound.h" +#include "../i_system.h" +#include "../screen.h" //vid.WndParent +#include "../d_net.h" +#include "../g_game.h" +#include "../filesrch.h" +#include "../z_zone.h" // Z_Free +#include "endtxt.h" + +#include "../i_joy.h" + +#include "../m_argv.h" + +#ifdef MAC_ALERT +#include "macosx/mac_alert.h" +#endif + +#include "../d_main.h" + +#if !defined(NOMUMBLE) && defined(HAVE_MUMBLE) +// Mumble context string +#include "../d_clisrv.h" +#include "../byteptr.h" +#endif + +#ifdef HAVE_LIBBACKTRACE +#include +// TODO - move this to some header file instead +extern struct backtrace_state *bt_state; + +typedef struct bt_crash_reason_s { + enum { + BTCRASH_SIGNAL, + BTCRASH_ERRORMSG, + } type; + + union { + INT32 signal; + const char *errormsg; + } value; +} bt_crash_reason_t; + +#define BT_CRASH_REASON_SIGNAL(num) (bt_crash_reason_t){ .type = BTCRASH_SIGNAL, .value = { .signal = num } } +#define BT_CRASH_REASON_ERRORMSG(msg) (bt_crash_reason_t){ .type = BTCRASH_ERRORMSG, .value = { .errormsg = msg } } + +static void printsignal(FILE *fp, INT32 num) +{ + switch (num) + { + case SIGILL: + fprintf(fp, "SIGILL - illegal instruction - invalid function image"); + break; + case SIGFPE: + fprintf(fp, "SIGFPE - mathematical exception"); + break; + case SIGSEGV: + fprintf(fp, "SIGSEGV - segment violation"); + break; + case SIGABRT: + fprintf(fp, "SIGABRT - abnormal termination triggered by abort call"); + break; + default: + fprintf(fp, "Signal number %d", num); + } +} + +typedef struct bt_out_buf_s { + boolean error; + char *pos; + size_t size; +} bt_out_buf_t; + +static void bt_syminfo_cb(void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize) +{ + (void)symval; + (void)symsize; + + bt_out_buf_t *buf = (bt_out_buf_t*)data; + + if (!symname) + symname = "???"; + + int n = snprintf(buf->pos, buf->size, "%p %s\n", (void*)pc, symname); + + if (n <= 0) + { + buf->size = 0; + return; + } + + buf->pos += n; + buf->size -= n; +} + +static int bt_simple_cb(void *data, uintptr_t pc) +{ + bt_out_buf_t *buf = (bt_out_buf_t*)data; + + backtrace_syminfo(bt_state, pc, bt_syminfo_cb, NULL, data); + + if (!buf->size) return 1; + + return 0; +} + +static int bt_full_cb(void *data, uintptr_t pc, const char *filename, int lineno, const char *function) +{ + bt_out_buf_t *buf = (bt_out_buf_t*)data; + + if (!filename) filename = "???"; + if (!function) function = "???"; + + int n = snprintf(buf->pos, buf->size, "%p %s\n\t%s:%d\n", (void*)pc, function, filename, lineno); + + if (n <= 0) return 1; + + buf->pos += n; + buf->size -= n; + + if (!buf->size) return 1; + + return 0; +} + +static void bt_error_cb(void *data, const char *msg, int errnum) +{ + (void)msg; // We don't need this + + bt_out_buf_t *buf = (bt_out_buf_t*)data; + + // No debug info + if (errnum == -1) + buf->error = true; +} + +static void write_backtrace(bt_crash_reason_t reason) +{ + FILE *out = fopen(va("%s" PATHSEP "%s", srb2home, "srb2kart-crash-log.txt"), "a"); + + time_t rawtime; + struct tm *timeinfo; + + const size_t BUFSIZE = 8192; + char backtrace[BUFSIZE]; + + bt_out_buf_t buf; + buf.error = false; + buf.pos = backtrace; + buf.size = BUFSIZE; + + + if (!out) + { + fprintf(stderr, "\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n"); + out = stderr; + } + + // Get the current time as a string. + time(&rawtime); + timeinfo = localtime(&rawtime); + + fprintf(out, "------------------------\n\n"); + + fprintf(out, "Program name: %s %s\n", SRB2APPLICATION, VERSIONSTRING); + + if (compdate && comptime && comprevision && compbranch) + fprintf(out, "Compiled: %s %s, commit %s, branch %s\n", compdate, comptime, comprevision, compbranch); + + if (gamestate == GS_LEVEL) + { + char *title = G_BuildMapTitle(gamemap); + + if (title) + { + fprintf(out, "Game map: %s (%s)\n", title, G_BuildMapName(gamemap)); + Z_Free(title); + } + else + fprintf(out, "Game map: %s\n", G_BuildMapName(gamemap)); + } + + fprintf(out, "Time of crash: %s\n", asctime(timeinfo)); + + fprintf(out, "Caused by: "); + + switch (reason.type) + { + case BTCRASH_SIGNAL: + printsignal(out, reason.value.signal); + break; + + case BTCRASH_ERRORMSG: + fprintf(out, "%s", reason.value.errormsg); + break; + } + + fprintf(out, "\nBacktrace:\n"); + + // Try to get full backtrace, it will print files and line numbers + backtrace_full(bt_state, 2, bt_full_cb, bt_error_cb, (void*)&buf); + + if (buf.error) + { + // Fall back to simple backtrace, only prints function names + backtrace_simple(bt_state, 2, bt_simple_cb, NULL, (void*)&buf); + } + + fputs(backtrace, out); + + if (out != stderr) + { + fclose(out); + fprintf(stderr, "Crash report created, find srb2kart-crash-log.txt in your SRB2Kart directory\n"); + } +} + +#endif + +boolean consolevent = false; +boolean framebuffer = false; + +boolean g_in_exiting_signal_handler = false; + +UINT8 keyboard_started = false; + +static void I_ReportSignal(int num, int coredumped) +{ + //static char msg[] = "oh no! back to reality!\r\n"; + const char * sigmsg; + char msg[256]; + + switch (num) + { +// case SIGINT: +// sigmsg = "SIGINT - interrupted"; +// break; + case SIGILL: + sigmsg = "SIGILL - illegal instruction - invalid function image"; + break; + case SIGFPE: + sigmsg = "SIGFPE - mathematical exception"; + break; + case SIGSEGV: + sigmsg = "SIGSEGV - segment violation"; + break; +// case SIGTERM: +// sigmsg = "SIGTERM - Software termination signal from kill"; +// break; +// case SIGBREAK: +// sigmsg = "SIGBREAK - Ctrl-Break sequence"; +// break; + case SIGABRT: + sigmsg = "SIGABRT - abnormal termination triggered by abort call"; + break; + default: + sprintf(msg,"signal number %d", num); + if (coredumped) + sigmsg = 0; + else + sigmsg = msg; + } + + if (coredumped) + { + if (sigmsg) + sprintf(msg, "%s (core dumped)", sigmsg); + else + strcat(msg, " (core dumped)"); + } + else + { + sprintf(msg, "%s", sigmsg); + } + +#ifdef HAVE_LIBBACKTRACE + strncat(msg, "\n\nCrash report has been saved into srb2kart-crash-log.txt", 255); +#elif defined(_WIN32) && !defined(__MINGW64__) + strncat(msg, "\n\nCrash report has been saved into srb2kart.rpt", 255); +#endif + + I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg); +} + +#ifndef NEWSIGNALHANDLER +FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) +{ + g_in_exiting_signal_handler = true; + + D_QuitNetGame(); // Fix server freezes + +#ifdef HAVE_LIBBACKTRACE + write_backtrace(BT_CRASH_REASON_SIGNAL(num)); +#endif + + if (demo.recording) + G_SaveDemo(); + + I_ReportSignal(num, 0); + I_ShutdownSystem(); + signal(num, SIG_DFL); //default signal action + raise(num); + I_Quit(); +} +#endif + +FUNCNORETURN static ATTRNORETURN void quit_handler(int num) +{ + signal(num, SIG_DFL); //default signal action + raise(num); + I_Quit(); +} + +#ifdef HAVE_TERMIOS +// TERMIOS console code from Quake3: thank you! +boolean stdin_active = true; + +typedef struct +{ + size_t cursor; + char buffer[256]; +} feild_t; + +feild_t tty_con; + +// lock to prevent clearing partial lines, since not everything +// printed ends on a newline. +static boolean ttycon_ateol = true; +// some key codes that the terminal may be using +// TTimo NOTE: I'm not sure how relevant this is +static INT32 tty_erase; +static INT32 tty_eof; + +static struct termios tty_tc; + +// ============================================================= +// tty console routines +// NOTE: if the user is editing a line when something gets printed to the early console then it won't look good +// so we provide tty_Clear and tty_Show to be called before and after a stdout or stderr output +// ============================================================= + +// flush stdin, I suspect some terminals are sending a LOT of garbage +// FIXME TTimo relevant? +#if 0 +static inline void tty_FlushIn(void) +{ + char key; + while (read(STDIN_FILENO, &key, 1)!=-1); +} +#endif + +// do a backspace +// TTimo NOTE: it seems on some terminals just sending '\b' is not enough +// so for now, in any case we send "\b \b" .. yeah well .. +// (there may be a way to find out if '\b' alone would work though) +// Hanicef NOTE: using \b this way is unreliable because of terminal state, +// it's better to use \r to reset the cursor to the beginning of the +// line and clear from there. +static void tty_Back(void) +{ + write(STDOUT_FILENO, "\r", 1); + if (tty_con.cursor>0) + { + write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); + } + write(STDOUT_FILENO, " \b", 2); +} + +static void tty_Clear(void) +{ + size_t i; + write(STDOUT_FILENO, "\r", 1); + if (tty_con.cursor>0) + { + for (i=0; i 0) + { + tty_con.cursor--; + tty_con.buffer[tty_con.cursor] = '\0'; + tty_Back(); + } + ev.data1 = KEY_BACKSPACE; + } + else if (key < ' ') // check if this is a control char + { + if (key == '\n') + { + tty_Clear(); + tty_con.cursor = 0; + ev.data1 = KEY_ENTER; + } + else if (key == 0x4) // ^D, aka EOF + { + // shut down, most unix programs behave this way + I_Quit(); + } + else continue; + } + else if (tty_con.cursor < sizeof(tty_con.buffer)) + { + // push regular character + ev.data1 = tty_con.buffer[tty_con.cursor] = key; + tty_con.cursor++; + // print the current line (this is differential) + write(STDOUT_FILENO, &key, 1); + } + if (ev.data1) D_PostEvent(&ev); + } +} + +#elif defined (_WIN32) +static BOOL I_ReadyConsole(HANDLE ci) +{ + DWORD gotinput; + if (ci == INVALID_HANDLE_VALUE) return FALSE; + if (WaitForSingleObject(ci,0) != WAIT_OBJECT_0) return FALSE; + if (GetFileType(ci) != FILE_TYPE_CHAR) return FALSE; + if (!GetConsoleMode(ci, &gotinput)) return FALSE; + return (GetNumberOfConsoleInputEvents(ci, &gotinput) && gotinput); +} + +static boolean entering_con_command = false; + +static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co) +{ + event_t event; + CONSOLE_SCREEN_BUFFER_INFO CSBI; + DWORD t; + + memset(&event,0x00,sizeof (event)); + + if (evt.bKeyDown) + { + event.type = ev_console; + entering_con_command = true; + switch (evt.wVirtualKeyCode) + { + case VK_ESCAPE: + case VK_TAB: + event.data1 = KEY_NULL; + break; + case VK_RETURN: + entering_con_command = false; + // Fall through. + default: + //event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char + event.data1 = evt.uChar.AsciiChar; + } + if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t)) + { + if (event.data1 && event.data1 != KEY_LSHIFT && event.data1 != KEY_RSHIFT) + { +#ifdef _UNICODE + WriteConsole(co, &evt.uChar.UnicodeChar, 1, &t, NULL); +#else + WriteConsole(co, &evt.uChar.AsciiChar, 1 , &t, NULL); +#endif + } + if (evt.wVirtualKeyCode == VK_BACK + && GetConsoleScreenBufferInfo(co,&CSBI)) + { + WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t); + } + } + } + if (event.data1) D_PostEvent(&event); +} + +void I_GetConsoleEvents(void) +{ + HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); + HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); + INPUT_RECORD input; + DWORD t; + + while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t) + { + switch (input.EventType) + { + case KEY_EVENT: + Impl_HandleKeyboardConsoleEvent(input.Event.KeyEvent, co); + break; + case MOUSE_EVENT: + case WINDOW_BUFFER_SIZE_EVENT: + case MENU_EVENT: + case FOCUS_EVENT: + break; + } + } +} + +static void I_StartupConsole(void) +{ + HANDLE ci, co; + const INT32 ded = M_CheckParm("-dedicated"); + BOOL gotConsole = FALSE; + if (M_CheckParm("-console") || ded) + gotConsole = AllocConsole(); +#ifdef _DEBUG + else if (M_CheckParm("-noconsole") && !ded) +#else + else if (!M_CheckParm("-console") && !ded) +#endif + { + FreeConsole(); + gotConsole = FALSE; + } + + if (gotConsole) + { + SetConsoleTitleA("SRB2Kart Console"); + consolevent = true; + } + + //Let get the real console HANDLE, because Mingw's Bash is bad! + ci = CreateFile(TEXT("CONIN$") , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + co = CreateFile(TEXT("CONOUT$"), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (ci != INVALID_HANDLE_VALUE) + { + const DWORD CM = ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT; + SetStdHandle(STD_INPUT_HANDLE, ci); + if (GetFileType(ci) == FILE_TYPE_CHAR) + SetConsoleMode(ci, CM); //default mode but no ENABLE_MOUSE_INPUT + } + if (co != INVALID_HANDLE_VALUE) + { + SetStdHandle(STD_OUTPUT_HANDLE, co); + SetStdHandle(STD_ERROR_HANDLE, co); + } +} +static inline void I_ShutdownConsole(void){} +#else +void I_GetConsoleEvents(void){} +static inline void I_StartupConsole(void) +{ +#ifdef _DEBUG + consolevent = !M_CheckParm("-noconsole"); +#else + consolevent = M_CheckParm("-console"); +#endif + + framebuffer = M_CheckParm("-framebuffer"); + + if (framebuffer) + consolevent = false; +} +static inline void I_ShutdownConsole(void){} +#endif + +// +// StartupKeyboard +// +static void I_RegisterSignals (void) +{ +#ifdef SIGINT + signal(SIGINT , quit_handler); +#endif +#ifdef SIGBREAK + signal(SIGBREAK , quit_handler); +#endif +#ifdef SIGTERM + signal(SIGTERM , quit_handler); +#endif + + // If these defines don't exist, + // then compilation would have failed above us... +#ifndef NEWSIGNALHANDLER + signal(SIGILL , signal_handler); + signal(SIGSEGV , signal_handler); + signal(SIGABRT , signal_handler); + signal(SIGFPE , signal_handler); +#endif +} + +#ifdef NEWSIGNALHANDLER +static void signal_handler_child(INT32 num) +{ +#ifdef HAVE_LIBBACKTRACE + write_backtrace(BT_CRASH_REASON_SIGNAL(num)); +#endif + + if (demo.recording) + G_SaveDemo(); + + signal(num, SIG_DFL); //default signal action + raise(num); +} + +static void I_RegisterChildSignals(void) +{ + // If these defines don't exist, + // then compilation would have failed above us... + signal(SIGILL , signal_handler_child); + signal(SIGSEGV , signal_handler_child); + signal(SIGABRT , signal_handler_child); + signal(SIGFPE , signal_handler_child); +} +#endif + +// +//I_OutputMsg +// +void I_OutputMsg(const char *fmt, ...) +{ + size_t len; + char *txt; + va_list argptr; + + va_start(argptr,fmt); + len = vsnprintf(NULL, 0, fmt, argptr); + va_end(argptr); + if (len == 0) + return; + + txt = malloc(len+1); + va_start(argptr,fmt); + vsprintf(txt, fmt, argptr); + va_end(argptr); + +#ifdef HAVE_TTF + if (TTF_WasInit()) I_TTFDrawText(currentfont, solid, DEFAULTFONTFGR, DEFAULTFONTFGG, DEFAULTFONTFGB, DEFAULTFONTFGA, + DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt); +#endif + +#if defined (_WIN32) && defined (_MSC_VER) + OutputDebugStringA(txt); +#endif + + len = strlen(txt); + +#ifdef LOGMESSAGES + if (logstream) + { + size_t d = fwrite(txt, len, 1, logstream); + fflush(logstream); + (void)d; + } +#endif + +#if defined (_WIN32) +#ifdef DEBUGFILE + if (debugfile != stderr) +#endif + { + HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD bytesWritten; + + if (co == INVALID_HANDLE_VALUE) + { + free(txt); + return; + } + + if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten)) + { + static COORD coordNextWrite = {0,0}; + LPVOID oldLines = NULL; + INT oldLength; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + // Save the lines that we're going to obliterate. + GetConsoleScreenBufferInfo(co, &csbi); + oldLength = csbi.dwSize.X * (csbi.dwCursorPosition.Y - coordNextWrite.Y) + csbi.dwCursorPosition.X - coordNextWrite.X; + + if (oldLength > 0) + { + LPVOID blank = malloc(oldLength); + if (!blank) + { + free(txt); + return; + } + memset(blank, ' ', oldLength); // Blank out. + oldLines = malloc(oldLength*sizeof(TCHAR)); + if (!oldLines) + { + free(txt); + free(blank); + return; + } + + ReadConsoleOutputCharacter(co, oldLines, oldLength, coordNextWrite, &bytesWritten); + + // Move to where we what to print - which is where we would've been, + // had console input not been in the way, + SetConsoleCursorPosition(co, coordNextWrite); + + WriteConsoleA(co, blank, oldLength, &bytesWritten, NULL); + free(blank); + + // And back to where we want to print again. + SetConsoleCursorPosition(co, coordNextWrite); + } + + // Actually write the string now! + WriteConsoleA(co, txt, (DWORD)len, &bytesWritten, NULL); + + // Next time, output where we left off. + GetConsoleScreenBufferInfo(co, &csbi); + coordNextWrite = csbi.dwCursorPosition; + + // Restore what was overwritten. + if (oldLines && entering_con_command) + WriteConsole(co, oldLines, oldLength, &bytesWritten, NULL); + if (oldLines) free(oldLines); + } + else // Redirected to a file. + WriteFile(co, txt, (DWORD)len, &bytesWritten, NULL); + } +#else +#ifdef HAVE_TERMIOS + if (consolevent && ttycon_ateol) + { + tty_Clear(); + ttycon_ateol = false; + } +#endif + + if (!framebuffer) + fprintf(stderr, "%s", txt); +#ifdef HAVE_TERMIOS + if (consolevent && txt[len-1] == '\n') + { + write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); + ttycon_ateol = true; + } +#endif + + // 2004-03-03 AJR Since not all messages end in newline, some were getting displayed late. + if (!framebuffer) + fflush(stderr); + +#endif + free(txt); +} + +// +// I_GetKey +// +INT32 I_GetKey (void) +{ + // Warning: I_GetKey empties the event queue till next keypress + event_t *ev; + INT32 rc = 0; + + // return the first keypress from the event queue + for (; eventtail != eventhead; eventtail = (eventtail+1)&(MAXEVENTS-1)) + { + ev = &events[eventtail]; + if (ev->type == ev_keydown || ev->type == ev_console) + { + rc = ev->data1; + continue; + } + } + + return rc; +} + +// +// I_JoyScale +// +void I_JoyScale(void) +{ +} + +void I_JoyScale2(void) +{ +} + +void I_JoyScale3(void) +{ +} + +void I_JoyScale4(void) +{ +} + +/** \brief Shuts down joystick 1 + + + \return void + + +*/ +void I_ShutdownJoystick(void) +{ +} + +void I_GetJoystickEvents(UINT8 index) +{ + (void)index; +} + +// +// I_InitJoystick +// +void I_InitJoystick(UINT8 index) +{ + (void)index; +} + +void I_InitJoystick1(void) +{ +} + +void I_InitJoystick2(void) +{ +} + +void I_InitJoystick3(void) +{ +} + +void I_InitJoystick4(void) +{ +} + +INT32 I_NumJoys(void) +{ + return 0; +} + +const char *I_GetJoyName(INT32 joyindex) +{ + (void)joyindex; + return NULL; +} + +void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration) +{ + (void)playernum; + (void)low_strength; + (void)high_strength; + (void)duration; +} + +void I_SetGamepadIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue) +{ + (void)playernum; + (void)red; + (void)green; + (void)blue; +} + +#ifndef NOMUMBLE +#ifdef HAVE_MUMBLE +// Best Mumble positional audio settings: +// Minimum distance 3.0 m +// Bloom 175% +// Maximum distance 80.0 m +// Minimum volume 50% +#define DEG2RAD (0.017453292519943295769236907684883l) // TAU/360 or PI/180 +#define MUMBLEUNIT (64.0f) // FRACUNITS in a Meter + +static struct { +#ifdef WINMUMBLE + UINT32 uiVersion; + DWORD uiTick; +#else + UINT32 uiVersion; + UINT32 uiTick; +#endif + float fAvatarPosition[3]; + float fAvatarFront[3]; + float fAvatarTop[3]; // defaults to Y-is-up (only used for leaning) + wchar_t name[256]; // game name + float fCameraPosition[3]; + float fCameraFront[3]; + float fCameraTop[3]; // defaults to Y-is-up (only used for leaning) + wchar_t identity[256]; // player id +#ifdef WINMUMBLE + UINT32 context_len; +#else + UINT32 context_len; +#endif + unsigned char context[256]; // server/team + wchar_t description[2048]; // game description +} *mumble = NULL; +#endif // HAVE_MUMBLE + +static void I_SetupMumble(void) +{ +#ifdef WINMUMBLE + HANDLE hMap = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink"); + if (!hMap) + return; + + mumble = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumble)); + if (!mumble) + CloseHandle(hMap); +#elif defined (HAVE_SHM) + int shmfd; + char memname[256]; + + snprintf(memname, 256, "/MumbleLink.%d", getuid()); + shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR); + + if(shmfd < 0) + return; + + mumble = mmap(NULL, sizeof(*mumble), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); + if (mumble == MAP_FAILED) + mumble = NULL; +#endif +} + +void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) +{ +#ifdef HAVE_MUMBLE + double angle; + fixed_t anglef; + + if (!mumble) + return; + + if (mumble->uiVersion != 2) { + wcsncpy(mumble->name, L"SRB2Kart "VERSIONSTRINGW, 256); + wcsncpy(mumble->description, L"Sonic Robo Blast 2 Kart with integrated Mumble Link support.", 2048); + mumble->uiVersion = 2; + } + mumble->uiTick++; + + if (!netgame || gamestate != GS_LEVEL) { // Zero out, but never delink. + mumble->fAvatarPosition[0] = mumble->fAvatarPosition[1] = mumble->fAvatarPosition[2] = 0.0f; + mumble->fAvatarFront[0] = 1.0f; + mumble->fAvatarFront[1] = mumble->fAvatarFront[2] = 0.0f; + mumble->fCameraPosition[0] = mumble->fCameraPosition[1] = mumble->fCameraPosition[2] = 0.0f; + mumble->fCameraFront[0] = 1.0f; + mumble->fCameraFront[1] = mumble->fCameraFront[2] = 0.0f; + return; + } + + { + UINT8 *p = mumble->context; + WRITEMEM(p, server_context, 8); + WRITEINT16(p, gamemap); + mumble->context_len = (UINT32)(p - mumble->context); + } + + if (mobj) { + mumble->fAvatarPosition[0] = FIXED_TO_FLOAT(mobj->x) / MUMBLEUNIT; + mumble->fAvatarPosition[1] = FIXED_TO_FLOAT(mobj->z) / MUMBLEUNIT; + mumble->fAvatarPosition[2] = FIXED_TO_FLOAT(mobj->y) / MUMBLEUNIT; + + anglef = AngleFixed(mobj->angle); + angle = FIXED_TO_FLOAT(anglef)*DEG2RAD; + mumble->fAvatarFront[0] = (float)cos(angle); + mumble->fAvatarFront[1] = 0.0f; + mumble->fAvatarFront[2] = (float)sin(angle); + } else { + mumble->fAvatarPosition[0] = mumble->fAvatarPosition[1] = mumble->fAvatarPosition[2] = 0.0f; + mumble->fAvatarFront[0] = 1.0f; + mumble->fAvatarFront[1] = mumble->fAvatarFront[2] = 0.0f; + } + + mumble->fCameraPosition[0] = FIXED_TO_FLOAT(listener.x) / MUMBLEUNIT; + mumble->fCameraPosition[1] = FIXED_TO_FLOAT(listener.z) / MUMBLEUNIT; + mumble->fCameraPosition[2] = FIXED_TO_FLOAT(listener.y) / MUMBLEUNIT; + + anglef = AngleFixed(listener.angle); + angle = FIXED_TO_FLOAT(anglef)*DEG2RAD; + mumble->fCameraFront[0] = (float)cos(angle); + mumble->fCameraFront[1] = 0.0f; + mumble->fCameraFront[2] = (float)sin(angle); +#else + (void)mobj; + (void)listener; +#endif // HAVE_MUMBLE +} +#undef WINMUMBLE +#endif // NOMUMBLE + + +/** \brief empty ticcmd for player 1 +*/ +static ticcmd_t emptycmd; + +ticcmd_t *I_BaseTiccmd(void) +{ + return &emptycmd; +} + +/** \brief empty ticcmd for player 2 +*/ +static ticcmd_t emptycmd2; + +ticcmd_t *I_BaseTiccmd2(void) +{ + return &emptycmd2; +} + +/** \brief empty ticcmd for player 3 + */ +static ticcmd_t emptycmd3; + +ticcmd_t *I_BaseTiccmd3(void) +{ + return &emptycmd3; +} + +/** \brief empty ticcmd for player 4 + */ +static ticcmd_t emptycmd4; + +ticcmd_t *I_BaseTiccmd4(void) +{ + return &emptycmd4; +} + +// +// I_GetTime +// returns time in 1/TICRATE second tics +// + +precise_t I_GetPreciseTime(void) +{ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (precise_t)ts.tv_sec * 1000000000 + ts.tv_nsec; +#elif defined (_WIN32) + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); + return (precise_t)counter.QuadPart; +#else + return 0; +#endif +} + +UINT64 I_GetPrecisePrecision(void) +{ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + return 1000000000; +#elif defined (_WIN32) + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + return (UINT64)frequency.QuadPart; +#else + return 1000000; +#endif +} + +void I_StartupTimer(void){} + +void I_Sleep(UINT32 ms) +{ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + struct timespec ts = { + .tv_sec = ms / 1000, + .tv_nsec = ms % 1000 * 1000000, + }; + int status; + do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); + while (status == EINTR); +#elif defined (_WIN32) + Sleep(ms); +#else + (void)ms; +#warning No sleep function for this system! +#endif +} + +void I_SleepDuration(precise_t duration) +{ +#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) + UINT64 precision = I_GetPrecisePrecision(); + struct timespec ts = { + .tv_sec = duration / precision, + .tv_nsec = duration * 1000000000 / precision % 1000000000, + }; + int status; + do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); + while (status == EINTR); +#elif defined (MIN_SLEEP_DURATION_MS) + UINT64 precision = I_GetPrecisePrecision(); + INT32 sleepvalue = cv_sleep.value; + UINT64 delaygranularity; + precise_t cur; + precise_t dest; + + { + double gran = round(((double)(precision / 1000) * sleepvalue * MIN_SLEEP_DURATION_MS)); + delaygranularity = (UINT64)gran; + } + + cur = I_GetPreciseTime(); + dest = cur + duration; + + // the reason this is not dest > cur is because the precise counter may wrap + // two's complement arithmetic is our friend here, though! + // e.g. cur 0xFFFFFFFFFFFFFFFE = -2, dest 0x0000000000000001 = 1 + // 0x0000000000000001 - 0xFFFFFFFFFFFFFFFE = 3 + while ((INT64)(dest - cur) > 0) + { + // If our cv_sleep value exceeds the remaining sleep duration, use the + // hard sleep function. + if (sleepvalue > 0 && (dest - cur) > delaygranularity) + { + I_Sleep(sleepvalue); + } + + // Otherwise, this is a spinloop. + + cur = I_GetPreciseTime(); + } +#endif +} + +#ifdef NEWSIGNALHANDLER +FUNCNORETURN static ATTRNORETURN void newsignalhandler_Warn(const char *pr) +{ + char text[128]; + + snprintf(text, sizeof text, + "Error while setting up signal reporting: %s: %s", + pr, + strerror(errno) + ); + + I_OutputMsg("%s\n", text); + + I_ShutdownConsole(); + exit(-1); +} + +static void I_Fork(void) +{ + int child; + int status; + int signum; + int c; + + child = fork(); + + switch (child) + { + case -1: + newsignalhandler_Warn("fork()"); + break; + case 0: + I_RegisterChildSignals(); + break; + default: + if (logstream) + fclose(logstream);/* the child has this */ + + c = wait(&status); + +#ifdef LOGMESSAGES + /* By the way, exit closes files. */ + logstream = fopen(logfilename, "at"); +#else + logstream = 0; +#endif + + if (c == -1) + { + kill(child, SIGKILL); + newsignalhandler_Warn("wait()"); + } + else + { + if (WIFSIGNALED (status)) + { + signum = WTERMSIG (status); +#ifdef WCOREDUMP + I_ReportSignal(signum, WCOREDUMP (status)); +#else + I_ReportSignal(signum, 0); +#endif + status = 128 + signum; + } + else if (WIFEXITED (status)) + { + status = WEXITSTATUS (status); + } + + I_ShutdownConsole(); + exit(status); + } + } +} +#endif/*NEWSIGNALHANDLER*/ + +INT32 I_StartupSystem(void) +{ + I_StartupConsole(); +#ifdef NEWSIGNALHANDLER + I_Fork(); +#endif +#ifdef HAVE_THREADS + I_start_threads(); + I_AddExitFunc(I_stop_threads); +#endif + I_RegisterSignals(); +#ifndef NOMUMBLE + I_SetupMumble(); +#endif + return 0; +} + +// +// I_Quit +// +void I_Quit(void) +{ + static boolean quiting = false; + + /* prevent recursive I_Quit() */ + if (quiting) goto death; + quiting = false; + I_ShutdownConsole(); + M_SaveConfig(NULL); //save game config, cvars.. +#ifndef NONET + D_SaveBan(); // save the ban list +#endif + G_SaveGameData(false); // Tails 12-08-2002 + //added:16-02-98: when recording a demo, should exit using 'q' key, + // but sometimes we forget and use 'F10'.. so save here too. + + if (demo.recording) + G_CheckDemoStatus(); + if (metalrecording) + G_StopMetalRecording(); + + D_QuitNetGame(); + I_ShutdownMusic(); + I_ShutdownSound(); + // use this for 1.28 19990220 by Kin + I_ShutdownGraphics(); + I_ShutdownSystem(); + /* if option -noendtxt is set, don't print the text */ + if (!M_CheckParm("-noendtxt") && W_CheckNumForName("ENDOOM") != LUMPERROR) + { + printf("\r"); + ShowEndTxt(); + } + if (myargmalloc) + free(myargv); // Deallocate allocated memory +death: + W_Shutdown(); + exit(0); +} + +void I_WaitVBL(INT32 count) +{ + count = 1; + I_Sleep(count); +} + +void I_BeginRead(void) +{ +} + +void I_EndRead(void) +{ +} + +// +// I_Error +// +/** \brief phuck recursive errors +*/ +static INT32 errorcount = 0; + +/** \brief recursive error detecting +*/ +static boolean shutdowning = false; + +void I_Error(const char *error, ...) +{ + va_list argptr; + char buffer[8192]; + + // recursive error detecting + if (shutdowning) + { + errorcount++; + // try to shutdown each subsystem separately + if (errorcount == 1) + I_ShutdownMusic(); + if (errorcount == 2) + I_ShutdownSound(); + if (errorcount == 3) + I_ShutdownGraphics(); + if (errorcount == 4) + I_ShutdownSystem(); + if (errorcount == 5) + { + M_SaveConfig(NULL); + G_SaveGameData(false); + } + if (errorcount > 20) + { + va_start(argptr, error); + vsprintf(buffer, error, argptr); + va_end(argptr); + + I_OutputMsg("SRB2Kart %s Recursive Error", buffer); + + W_Shutdown(); + exit(-1); // recursive errors detected + } + } + + shutdowning = true; + + // Display error message in the console before we start shutting it down + va_start(argptr, error); + vsprintf(buffer, error, argptr); + va_end(argptr); + I_OutputMsg("\nI_Error(): %s\n", buffer); + +#ifdef HAVE_LIBBACKTRACE + write_backtrace(BT_CRASH_REASON_ERRORMSG(buffer)); +#endif + // --- + + I_ShutdownConsole(); + + M_SaveConfig(NULL); // save game config, cvars.. +#ifndef NONET + D_SaveBan(); // save the ban list +#endif + G_SaveGameData(false); // Tails 12-08-2002 + + // Shutdown. Here might be other errors. + if (demo.recording) + G_CheckDemoStatus(); + if (metalrecording) + G_StopMetalRecording(); + + D_QuitNetGame(); + I_ShutdownMusic(); + I_ShutdownSound(); + // use this for 1.28 19990220 by Kin + I_ShutdownGraphics(); + I_ShutdownSystem(); + + W_Shutdown(); + +#if defined (PARANOIA) && defined (__CYGWIN__) + *(INT32 *)2 = 4; //Alam: Debug! +#endif + + exit(-1); +} + +/** \brief quit function table +*/ +static quitfuncptr quit_funcs[MAX_QUIT_FUNCS]; /* initialized to all bits 0 */ + +// +// Adds a function to the list that need to be called by I_SystemShutdown(). +// +void I_AddExitFunc(void (*func)()) +{ + INT32 c; + + for (c = 0; c < MAX_QUIT_FUNCS; c++) + { + if (!quit_funcs[c]) + { + quit_funcs[c] = func; + break; + } + } +} + + +// +// Removes a function from the list that need to be called by +// I_SystemShutdown(). +// +void I_RemoveExitFunc(void (*func)()) +{ + INT32 c; + + for (c = 0; c < MAX_QUIT_FUNCS; c++) + { + if (quit_funcs[c] == func) + { + while (c < MAX_QUIT_FUNCS-1) + { + quit_funcs[c] = quit_funcs[c+1]; + c++; + } + quit_funcs[MAX_QUIT_FUNCS-1] = NULL; + break; + } + } +} + +#if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)) +static void Shittycopyerror(const char *name) +{ + I_OutputMsg( + "Error copying log file: %s: %s\n", + name, + strerror(errno) + ); +} + +static void Shittylogcopy(void) +{ + char buf[8192]; + FILE *fp; + size_t r; + if (fseek(logstream, 0, SEEK_SET) == -1) + { + Shittycopyerror("fseek"); + } + else if (( fp = fopen(logfilename, "wt") )) + { + while (( r = fread(buf, 1, sizeof buf, logstream) )) + { + if (fwrite(buf, 1, r, fp) < r) + { + Shittycopyerror("fwrite"); + break; + } + } + if (ferror(logstream)) + { + Shittycopyerror("fread"); + } + fclose(fp); + } + else + { + Shittycopyerror(logfilename); + } +} +#endif/*!(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))*/ + +// +// Closes down everything. This includes restoring the initial +// palette and video mode, and removing whatever mouse, keyboard, and +// timer routines have been installed. +// +// NOTE: Shutdown user funcs are effectively called in reverse order. +// +void I_ShutdownSystem(void) +{ + INT32 c; + +#ifndef NEWSIGNALHANDLER + I_ShutdownConsole(); +#endif + + for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) + if (quit_funcs[c]) + (*quit_funcs[c])(); +#ifdef LOGMESSAGES + if (logstream) + { + I_OutputMsg("I_ShutdownSystem(): end of logstream.\n"); +#if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)) + Shittylogcopy(); +#endif + fclose(logstream); + logstream = NULL; + } +#endif +} + +void I_GetDiskFreeSpace(INT64 *freespace) +{ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (SOLARIS) || defined (__HAIKU__) + *freespace = INT32_MAX; + return; +#else // Both Linux and BSD have this, apparently. + struct statfs stfs; + if (statfs(".", &stfs) == -1) + { + *freespace = INT32_MAX; + return; + } + *freespace = stfs.f_bavail * stfs.f_bsize; +#endif +#elif defined (_WIN32) + static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; + static boolean testwin95 = false; + ULARGE_INTEGER usedbytes, lfreespace; + + if (!testwin95) + { + pfnGetDiskFreeSpaceEx = (p_GetDiskFreeSpaceExA)(LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetDiskFreeSpaceExA"); + testwin95 = true; + } + if (pfnGetDiskFreeSpaceEx) + { + if (pfnGetDiskFreeSpaceEx(NULL, &lfreespace, &usedbytes, NULL)) + *freespace = lfreespace.QuadPart; + else + *freespace = INT32_MAX; + } + else + { + DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters; + GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, + &NumberOfFreeClusters, &TotalNumberOfClusters); + *freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters; + } +#else // Dummy for platform independent; 1GB should be enough + *freespace = 1024*1024*1024; +#endif +} + +char *I_GetUserName(void) +{ + static char username[MAXPLAYERNAME+1]; + char *p; +#ifdef _WIN32 + DWORD i = MAXPLAYERNAME; + + if (!GetUserNameA(username, &i)) +#endif + { + p = I_GetEnv("USER"); + if (!p) + { + p = I_GetEnv("user"); + if (!p) + { + p = I_GetEnv("USERNAME"); + if (!p) + { + p = I_GetEnv("username"); + if (!p) + { + return NULL; + } + } + } + } + strncpy(username, p, MAXPLAYERNAME); + } + + + if (strcmp(username, "") != 0) + return username; + return NULL; // dummy for platform independent version +} + +INT32 I_mkdir(const char *dirname, INT32 unixright) +{ +//[segabor] +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (__CYGWIN__) || defined (__OS2__) + return mkdir(dirname, unixright); +#elif defined (_WIN32) + UNREFERENCED_PARAMETER(unixright); /// \todo should implement ntright under nt... + return CreateDirectoryA(dirname, NULL); +#else + (void)dirname; + (void)unixright; + return false; +#endif +} + +char *I_GetEnv(const char *name) +{ + return getenv(name); +} + +INT32 I_PutEnv(char *variable) +{ + return putenv(variable); +} + +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +const char *I_ClipboardPaste(void) +{ + return NULL; +} + +/** \brief The isWadPathOk function + + \param path string path to check + + \return if true, wad file found + + +*/ +static boolean isWadPathOk(const char *path) +{ + char *wad3path = malloc(256); + + if (!wad3path) + return false; + + sprintf(wad3path, pandf, path, WADKEYWORD1); + + if (FIL_ReadFileOK(wad3path)) + { + free(wad3path); + return true; + } + + sprintf(wad3path, pandf, path, WADKEYWORD2); + + if (FIL_ReadFileOK(wad3path)) + { + free(wad3path); + return true; + } + + free(wad3path); + return false; +} + +static void pathonly(char *s) +{ + size_t j; + + for (j = strlen(s); j != (size_t)-1; j--) + if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/')) + { + if (s[j] == ':') s[j+1] = 0; + else s[j] = 0; + return; + } +} + +/** \brief search for srb2.srb in the given path + + \param searchDir starting path + + \return WAD path if not NULL + + +*/ +static const char *searchWad(const char *searchDir) +{ + static char tempsw[256] = ""; + filestatus_t fstemp; + + strcpy(tempsw, WADKEYWORD1); + fstemp = filesearch(tempsw,searchDir,NULL,true,20); + if (fstemp == FS_FOUND) + { + pathonly(tempsw); + return tempsw; + } + + strcpy(tempsw, WADKEYWORD2); + fstemp = filesearch(tempsw, searchDir, NULL, true, 20); + if (fstemp == FS_FOUND) + { + pathonly(tempsw); + return tempsw; + } + return NULL; +} + +/** \brief go through all possible paths and look for srb2.srb + + \return path to srb2.srb if any +*/ +static const char *locateWad(void) +{ + const char *envstr; + const char *WadPath; + + I_OutputMsg("SRB2WADDIR"); + // does SRB2WADDIR exist? + if (((envstr = I_GetEnv("SRB2WADDIR")) != NULL) && isWadPathOk(envstr)) + return envstr; + +#ifndef NOCWD + I_OutputMsg(",."); + // examine current dir + strcpy(returnWadPath, "."); + if (isWadPathOk(returnWadPath)) + return NULL; +#endif + + +#ifdef DEFAULTDIR + I_OutputMsg(",HOME/" DEFAULTDIR); + // examine user jart directory + if ((envstr = I_GetEnv("HOME")) != NULL) + { + sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr); + if (isWadPathOk(returnWadPath)) + return returnWadPath; + } +#endif + + +#ifdef CMAKECONFIG +#ifndef NDEBUG + I_OutputMsg(","CMAKE_ASSETS_DIR); + strcpy(returnWadPath, CMAKE_ASSETS_DIR); + if (isWadPathOk(returnWadPath)) + { + return returnWadPath; + } +#endif +#endif + +#ifdef __APPLE__ + OSX_GetResourcesPath(returnWadPath); + I_OutputMsg(",%s", returnWadPath); + if (isWadPathOk(returnWadPath)) + { + return returnWadPath; + } +#endif + + // examine default dirs +#ifdef DEFAULTWADLOCATION1 + I_OutputMsg(","DEFAULTWADLOCATION1); + strcpy(returnWadPath, DEFAULTWADLOCATION1); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION2 + I_OutputMsg(","DEFAULTWADLOCATION2); + strcpy(returnWadPath, DEFAULTWADLOCATION2); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION3 + I_OutputMsg(","DEFAULTWADLOCATION3); + strcpy(returnWadPath, DEFAULTWADLOCATION3); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION4 + I_OutputMsg(","DEFAULTWADLOCATION4); + strcpy(returnWadPath, DEFAULTWADLOCATION4); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION5 + I_OutputMsg(","DEFAULTWADLOCATION5); + strcpy(returnWadPath, DEFAULTWADLOCATION5); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION6 + I_OutputMsg(","DEFAULTWADLOCATION6); + strcpy(returnWadPath, DEFAULTWADLOCATION6); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION7 + I_OutputMsg(","DEFAULTWADLOCATION7); + strcpy(returnWadPath, DEFAULTWADLOCATION7); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifndef NOHOME + // find in $HOME + I_OutputMsg(",HOME/" DEFAULTDIR); + if ((envstr = I_GetEnv("HOME")) != NULL) + { + char *tmp = malloc(strlen(envstr) + sizeof(PATHSEP) + sizeof(DEFAULTDIR)); + strcpy(tmp, envstr); + strcat(tmp, PATHSEP); + strcat(tmp, DEFAULTDIR); + WadPath = searchWad(tmp); + free(tmp); + if (WadPath) + return WadPath; + } +#endif +#ifdef DEFAULTSEARCHPATH1 + // find in /usr/local + I_OutputMsg(", in:"DEFAULTSEARCHPATH1); + WadPath = searchWad(DEFAULTSEARCHPATH1); + if (WadPath) + return WadPath; +#endif +#ifdef DEFAULTSEARCHPATH2 + // find in /usr/games + I_OutputMsg(", in:"DEFAULTSEARCHPATH2); + WadPath = searchWad(DEFAULTSEARCHPATH2); + if (WadPath) + return WadPath; +#endif +#ifdef DEFAULTSEARCHPATH3 + // find in ??? + I_OutputMsg(", in:"DEFAULTSEARCHPATH3); + WadPath = searchWad(DEFAULTSEARCHPATH3); + if (WadPath) + return WadPath; +#endif + // if nothing was found + return NULL; +} + +const char *I_LocateWad(void) +{ + const char *waddir; + + I_OutputMsg("Looking for WADs in: "); + waddir = locateWad(); + I_OutputMsg("\n"); + + if (waddir) + { + // change to the directory where we found srb2.srb +#if defined (_WIN32) + SetCurrentDirectoryA(waddir); +#else + if (chdir(waddir) == -1) + I_OutputMsg("Couldn't change working directory\n"); +#endif + } + return waddir; +} + +#ifdef __linux__ +#define MEMINFO_FILE "/proc/meminfo" +#define MEMTOTAL "MemTotal:" +#define MEMAVAILABLE "MemAvailable:" +#define MEMFREE "MemFree:" +#define CACHED "Cached:" +#define BUFFERS "Buffers:" +#define SHMEM "Shmem:" + +/* Parse the contents of /proc/meminfo (in buf), return value of "name" + * (example: MemTotal) */ +static long get_entry(const char* name, const char* buf) +{ + long val; + char* hit = strstr(buf, name); + if (hit == NULL) { + return -1; + } + + errno = 0; + val = strtol(hit + strlen(name), NULL, 10); + if (errno != 0) { + CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno)); + return -1; + } + return val; +} +#endif + +size_t I_GetFreeMem(size_t *total) +{ +#ifdef FREEBSD + u_int v_free_count, v_page_size, v_page_count; + size_t size = sizeof(v_free_count); + sysctlbyname("vm.stats.vm.v_free_count", &v_free_count, &size, NULL, 0); + size = sizeof(v_page_size); + sysctlbyname("vm.stats.vm.v_page_size", &v_page_size, &size, NULL, 0); + size = sizeof(v_page_count); + sysctlbyname("vm.stats.vm.v_page_count", &v_page_count, &size, NULL, 0); + + if (total) + *total = v_page_count * v_page_size; + return v_free_count * v_page_size; +#elif defined (SOLARIS) + /* Just guess */ + if (total) + *total = 32 << 20; + return 32 << 20; +#elif defined (_WIN32) + MEMORYSTATUS info; + + info.dwLength = sizeof (MEMORYSTATUS); + GlobalMemoryStatus( &info ); + if (total) + *total = (size_t)info.dwTotalPhys; + return (size_t)info.dwAvailPhys; +#elif defined (__OS2__) + UINT32 pr_arena; + + if (total) + DosQuerySysInfo( QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, + (PVOID) total, sizeof (UINT32)); + DosQuerySysInfo( QSV_MAXPRMEM, QSV_MAXPRMEM, + (PVOID) &pr_arena, sizeof (UINT32)); + + return pr_arena; +#elif defined (__linux__) + /* Linux */ + char buf[1024]; + char *memTag; + size_t freeKBytes; + size_t totalKBytes; + INT32 n; + INT32 meminfo_fd = -1; + long Cached; + long MemFree; + long Buffers; + long Shmem; + long MemAvailable = -1; + + meminfo_fd = open(MEMINFO_FILE, O_RDONLY); + n = read(meminfo_fd, buf, 1023); + close(meminfo_fd); + + if (n < 0) + { + // Error + if (total) + *total = 0L; + return 0; + } + + buf[n] = '\0'; + if ((memTag = strstr(buf, MEMTOTAL)) == NULL) + { + // Error + if (total) + *total = 0L; + return 0; + } + + memTag += sizeof (MEMTOTAL); + totalKBytes = (size_t)atoi(memTag); + + if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL) + { + Cached = get_entry(CACHED, buf); + MemFree = get_entry(MEMFREE, buf); + Buffers = get_entry(BUFFERS, buf); + Shmem = get_entry(SHMEM, buf); + MemAvailable = Cached + MemFree + Buffers - Shmem; + + if (MemAvailable == -1) + { + // Error + if (total) + *total = 0L; + return 0; + } + freeKBytes = MemAvailable; + } + else + { + memTag += sizeof (MEMAVAILABLE); + freeKBytes = atoi(memTag); + } + + if (total) + *total = totalKBytes << 10; + return freeKBytes << 10; +#else + // Guess 48 MB. + if (total) + *total = 48<<20; + return 48<<20; +#endif +} + +// note CPUAFFINITY code used to reside here +void I_RegisterSysCommands(void) {} + +boolean I_InitNetwork(void) +{ + // this must exist, but this is actually handled in i_tcp.c + return false; +} diff --git a/src/dedicated/i_threads.c b/src/dedicated/i_threads.c new file mode 100644 index 000000000..f981fa961 --- /dev/null +++ b/src/dedicated/i_threads.c @@ -0,0 +1,364 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2020-2023 by James R. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file i_threads.c +/// \brief Multithreading abstraction + +#if defined (__unix__) || (!defined(__APPLE__) && defined (UNIXCOMMON)) + +#include + +#include "../i_threads.h" +#include "../doomdef.h" + +typedef struct thread_s thread_t; + +struct thread_s +{ + thread_t *next; + void *userdata; + I_thread_fn func; + pthread_t thread; +}; + +// we use a linked list to avoid moving memory blocks when allocating new threads. +static thread_t *thread_list; +static pthread_mutex_t thread_lock = PTHREAD_MUTEX_INITIALIZER; + +static void *HandleThread(void *data) +{ + thread_t *thread = data; + thread->func(thread->userdata); + + pthread_mutex_lock(&thread_lock); + thread->func = NULL; + pthread_mutex_unlock(&thread_lock); + return NULL; +} + +void +I_spawn_thread ( + const char * name, + I_thread_fn entry, + void * userdata +) +{ + thread_t *thread; + (void)name; + + pthread_mutex_lock(&thread_lock); + thread = thread_list; + while (thread != NULL) + { + if (thread->func == NULL) + { + // join with the exited thread to release it's resources. + pthread_join(thread->thread, NULL); + break; + } + thread = thread->next; + } + if (thread == NULL) + { + thread = malloc(sizeof(thread_t)); + thread->next = thread_list; + thread_list = thread; + } + + thread->func = entry; + thread->userdata = userdata; + pthread_create(&thread->thread, NULL, HandleThread, thread); + pthread_mutex_unlock(&thread_lock); +} + +int I_thread_is_stopped(void) +{ + thread_t *thread; + pthread_mutex_lock(&thread_lock); + thread = thread_list; + while (thread != NULL) + { + if (thread->func != NULL) + { + pthread_mutex_unlock(&thread_lock); + return false; + } + thread = thread->next; + } + pthread_mutex_unlock(&thread_lock); + return true; +} + +void I_start_threads(void) +{ +} + +void I_stop_threads(void) +{ + thread_t *thread = thread_list; + while (thread != NULL) + { + // join with all threads here, since finished threads haven't been awaited yet. + pthread_join(thread->thread, NULL); + thread = thread->next; + } +} + +void I_lock_mutex(I_mutex *anchor) +{ + pthread_mutex_lock(&thread_lock); + if (*anchor == NULL) + { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + + // SRB2 relies on lock recursion, so we need a mutex configured for that. + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + *anchor = malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(*anchor, &attr); + pthread_mutexattr_destroy(&attr); + } + pthread_mutex_unlock(&thread_lock); + pthread_mutex_lock(*anchor); +} + +void I_unlock_mutex(I_mutex id) +{ + pthread_mutex_unlock(id); +} + +void I_hold_cond(I_cond *cond_anchor, I_mutex mutex_id) +{ + I_Assert(mutex_id != NULL); + pthread_mutex_lock(&thread_lock); + if (*cond_anchor == NULL) + { + *cond_anchor = malloc(sizeof(pthread_cond_t)); + pthread_cond_init(*cond_anchor, NULL); + } + pthread_mutex_unlock(&thread_lock); + pthread_cond_wait(*cond_anchor, mutex_id); +} + +void I_wake_one_cond(I_cond *anchor) +{ + pthread_mutex_lock(&thread_lock); + if (*anchor == NULL) + { + *anchor = malloc(sizeof(pthread_cond_t)); + pthread_cond_init(*anchor, NULL); + } + pthread_mutex_unlock(&thread_lock); + pthread_cond_signal(*anchor); +} + +void I_wake_all_cond(I_cond *anchor) +{ + pthread_mutex_lock(&thread_lock); + if (*anchor == NULL) + { + *anchor = malloc(sizeof(pthread_cond_t)); + pthread_cond_init(*anchor, NULL); + } + pthread_mutex_unlock(&thread_lock); + pthread_cond_broadcast(*anchor); +} +#elif defined (_WIN32) +#include + +#include "../i_threads.h" +#include "../doomdef.h" +#include "../doomtype.h" + +typedef struct thread_s thread_t; + +struct thread_s +{ + thread_t *next; + void *userdata; + I_thread_fn func; + HANDLE thread; + DWORD thread_id; +}; + +// we use a linked list to avoid moving memory blocks when allocating new threads. +static thread_t *thread_list; +static CRITICAL_SECTION thread_lock; + +static DWORD __stdcall HandleThread(void *data) +{ + thread_t *thread = data; + thread->func(thread->userdata); + + EnterCriticalSection(&thread_lock); + thread->func = NULL; + LeaveCriticalSection(&thread_lock); + return 0; +} + +void I_spawn_thread(const char *name, I_thread_fn entry, void *userdata) +{ + thread_t *thread; + (void)name; + EnterCriticalSection(&thread_lock); + thread = thread_list; + while (thread != NULL) + { + if (thread->func == NULL) + { + CloseHandle(thread->thread); + break; + } + thread = thread->next; + } + if (thread == NULL) + { + thread = malloc(sizeof(thread_t)); + thread->next = thread_list; + thread_list = thread; + } + + thread->func = entry; + thread->userdata = userdata; + thread->thread = CreateThread(NULL, 0, HandleThread, thread, 0, &thread->thread_id); + LeaveCriticalSection(&thread_lock); +} + +int I_thread_is_stopped(void) +{ + thread_t *thread; + EnterCriticalSection(&thread_lock); + thread = thread_list; + while (thread != NULL) + { + if (thread->func != NULL) + { + LeaveCriticalSection(&thread_lock); + return false; + } + thread = thread->next; + } + LeaveCriticalSection(&thread_lock); + return true; +} + +void I_start_threads(void) +{ + InitializeCriticalSection(&thread_lock); +} + +void I_stop_threads(void) +{ + thread_t *thread = thread_list; + while (thread != NULL) + { + WaitForSingleObject(thread->thread, INFINITE); + CloseHandle(thread->thread); + thread = thread->next; + } + DeleteCriticalSection(&thread_lock); +} + +void I_lock_mutex(I_mutex *anchor) +{ + EnterCriticalSection(&thread_lock); + if (*anchor == NULL) + { + *anchor = malloc(sizeof(CRITICAL_SECTION)); + InitializeCriticalSection(*anchor); + } + LeaveCriticalSection(&thread_lock); + EnterCriticalSection(*anchor); +} + +void I_unlock_mutex(I_mutex id) +{ + LeaveCriticalSection(id); +} + +void I_hold_cond(I_cond *cond_anchor, I_mutex mutex_id) +{ + I_Assert(mutex_id != NULL); + EnterCriticalSection(&thread_lock); + if (*cond_anchor == NULL) + { + *cond_anchor = malloc(sizeof(CONDITION_VARIABLE)); + InitializeConditionVariable(*cond_anchor); + } + LeaveCriticalSection(&thread_lock); + SleepConditionVariableCS(*cond_anchor, mutex_id, INFINITE); +} + +void I_wake_one_cond(I_cond *anchor) +{ + EnterCriticalSection(&thread_lock); + if (*anchor == NULL) + { + *anchor = malloc(sizeof(CONDITION_VARIABLE)); + InitializeConditionVariable(*anchor); + } + LeaveCriticalSection(&thread_lock); + WakeConditionVariable(*anchor); +} + +void I_wake_all_cond(I_cond *anchor) +{ + EnterCriticalSection(&thread_lock); + if (*anchor == NULL) + { + *anchor = malloc(sizeof(CONDITION_VARIABLE)); + InitializeConditionVariable(*anchor); + } + LeaveCriticalSection(&thread_lock); + WakeAllConditionVariable(*anchor); +} +#else +void I_spawn_thread(const char *name, I_thread_fn entry, void *userdata) +{ + (void)name; + entry(userdata); +} + +int I_thread_is_stopped(void) +{ +} + +void I_start_threads(void) +{ +} + +void I_stop_threads(void) +{ +} + +void I_lock_mutex(I_mutex *anchor) +{ + (void)anchor; +} + +void I_unlock_mutex(I_mutex id) +{ + (void)id; +} + +void I_hold_cond(I_cond *cond_anchor, I_mutex mutex_id) +{ + (void)cond_anchor; + (void)mutex_id; +} + +void I_wake_one_cond(I_cond *anchor) +{ + (void)anchor; +} + +void I_wake_all_cond(I_cond *anchor) +{ + (void)anchor; +} +#endif diff --git a/src/dedicated/i_video.c b/src/dedicated/i_video.c new file mode 100644 index 000000000..6c0b6644a --- /dev/null +++ b/src/dedicated/i_video.c @@ -0,0 +1,154 @@ +// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 2014-2018 by Sonic Team Junior. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief SRB2 graphics stuff for dedicated + +#include "../doomdef.h" +#include "../i_system.h" +#include "../i_video.h" +#include "../console.h" +#include "../command.h" +#include "../i_system.h" +#include "../screen.h" + +rendermode_t rendermode = render_none; + +boolean highcolor = false; + +// synchronize page flipping with screen refresh +consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t keyboardlayout_cons_t[] = {{1,"Default US"}, {2, "Native"}, {3, "AZERTY"}, {0, NULL}}; +consvar_t cv_keyboardlayout = {"keyboardlayout", "Default US", CV_SAVE, keyboardlayout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +INT32 numcontrollers = 0; + +UINT8 graphics_started = 0; // Is used in console.c and screen.c + +// To disable fullscreen at startup; is set in VID_PrepareModeList +boolean allow_fullscreen = false; +UINT16 realwidth = BASEVIDWIDTH; +UINT16 realheight = BASEVIDHEIGHT; + +extern boolean consolevent; + +void I_GetConsoleEvents(void); + +void I_GetEvent(void) +{ +} + +void I_StartupMouse(void) +{ +} + +// +// I_OsPolling +// +void I_OsPolling(void) +{ + if (consolevent) + I_GetConsoleEvents(); +} + +// +// I_UpdateNoBlit +// +void I_UpdateNoBlit(void) +{ +} + +// +// I_FinishUpdate +// +void I_FinishUpdate(void) +{ +} + +// +// I_UpdateNoVsync +// +void I_UpdateNoVsync(void) +{ +} + +// +// I_ReadScreen +// +void I_ReadScreen(UINT8 *scr) +{ + (void)scr; +} + +// +// I_SetPalette +// +void I_SetPalette(RGBA_t *palette) +{ + (void)palette; +} + +// return number of fullscreen + X11 modes +INT32 VID_NumModes(void) +{ + return 0; +} + +const char *VID_GetModeName(INT32 modenum) +{ + (void)modenum; + return NULL; +} + +INT32 VID_GetModeForSize(INT32 w, INT32 h) +{ + (void)w; + (void)h; + return -1; +} + +void VID_PrepareModeList(void) +{ +} + +INT32 VID_SetMode(INT32 modeNum) +{ + (void)modeNum; + return true; +} + +void I_StartupGraphics(void) +{ +} + +void I_ShutdownGraphics(void) +{ +} + +UINT32 I_GetRefreshRate(void) +{ + return 0; +} + +boolean I_UseNativeKeyboard(void) +{ + return false; +} diff --git a/src/g_game.c b/src/g_game.c index 200ce7834..3d2f37fac 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -8117,9 +8117,6 @@ void G_SaveDemo(void) UINT8 *p = demobuf.buffer+16; // after version UINT32 length; -#ifdef NOMD5 - UINT8 i; -#endif // Ensure extrainfo pointer is always available, even if no info is present. if (demoinfo_p && *(UINT32 *)demoinfo_p == 0) @@ -8174,7 +8171,7 @@ void G_SaveDemo(void) length = *(UINT32 *)demoinfo_p; WRITEUINT32(demoinfo_p, length); #ifdef NOMD5 - for (i = 0; i < 16; i++, p++) + for (UINT8 k = 0; k < 16; k++, p++) *p = M_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. #else // Make a checksum of everything after the checksum in the file up to the end of the standard data. Extrainfo is freely modifiable. diff --git a/src/hardware/Sourcefile b/src/hardware/Sourcefile new file mode 100644 index 000000000..3114c975c --- /dev/null +++ b/src/hardware/Sourcefile @@ -0,0 +1,14 @@ +hw_bsp.c +hw_draw.c +hw_main.c +hw_clip.c +hw_md2.c +hw_cache.c +hw_md2load.c +hw_md3load.c +hw_model.c +hw_portal.c +hw_batching.c +hw_shaders.c +u_list.c +r_opengl/r_opengl.c diff --git a/src/m_menu.c b/src/m_menu.c index 2fb38a4d5..842f22d44 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7133,7 +7133,7 @@ static void DrawReplayHutReplayInfo(void) case MD_OUTDATED: V_DrawThinString(17, 64, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT|highlightflags, va("Recorded on an outdated version. %s", demolist[dir_on[menudepthleft]].version)); - /*fallthru*/ + /* FALLTHRU */ default: // Draw level stuff x = 15; y = 15; diff --git a/src/m_misc.c b/src/m_misc.c index c44086f4c..9455608cb 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -55,12 +55,13 @@ #ifdef HAVE_SDL #include "sdl/hwsym_sdl.h" +#endif + #ifdef __linux__ #ifndef _LARGEFILE64_SOURCE typedef off_t off64_t; #endif #endif -#endif #if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3)) && (__GNUC__ < 8) #define PRIdS "u" diff --git a/src/p_mobj.c b/src/p_mobj.c index 0157963f9..06cbd3b17 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7025,7 +7025,7 @@ void P_MobjThinker(mobj_t *mobj) P_RemoveMobj(mobj); return; } - // fallthru + /* FALLTHRU */ case MT_ORBINAUT_SHIELD: case MT_BANANA_SHIELD: case MT_EGGMANITEM_SHIELD: @@ -7035,7 +7035,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_JAWZ_DUD: if (P_IsObjectOnGround(mobj)) P_SetMobjState(mobj, mobj->info->xdeathstate); - // fallthru + /* FALLTHRU */ case MT_JAWZ_SHIELD: mobj->flags2 ^= MF2_DONTDRAW; break; diff --git a/src/sdl/Sourcefile b/src/sdl/Sourcefile new file mode 100644 index 000000000..82d5ce073 --- /dev/null +++ b/src/sdl/Sourcefile @@ -0,0 +1,7 @@ +i_net.c +i_system.c +i_main.c +i_video.c +dosstr.c +endtxt.c +hwsym_sdl.c diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index d6a007919..f033b678a 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -20,7 +20,7 @@ #include "../doomdef.h" #include "../m_argv.h" #include "../d_main.h" -#include "../m_misc.h"/* path shit */ +#include "../m_misc.h" /* path shit */ #include "../i_system.h" #if defined (__GNUC__) || defined (__unix__) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index b0890913a..afda0caa2 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -743,7 +743,7 @@ static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co) break; case VK_RETURN: entering_con_command = false; - // Fall through. + /* FALLTHRU */ default: //event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char event.data1 = evt.uChar.AsciiChar; diff --git a/src/w_wad.c b/src/w_wad.c index 0c7fdbaf0..ff2938c3e 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -724,7 +724,9 @@ UINT16 W_InitFile(const char *filename, boolean local) wadfile_t *wadfile; restype_t type; UINT16 numlumps = 0; +#ifndef NOMD5 size_t i; +#endif UINT8 md5sum[16]; boolean important; -- 2.54.0 From 8c316827230fa92530c4eac743449f62f6603881 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 15:43:21 +0200 Subject: [PATCH 02/35] smol adjustments for main --- src/Makefile.d/versions.mk | 4 ++++ src/Sourcefile | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk index 7c130d908..a3cdbbd4b 100644 --- a/src/Makefile.d/versions.mk +++ b/src/Makefile.d/versions.mk @@ -17,6 +17,10 @@ $(foreach v,$(join $(wordlist 2,$(_n),- $(gcc_versions)),\ $(eval $(call _predecessor,$(subst =, ,$(v)))))) # -W -Wno-unused + +ifdef GCC150 + opts+=-std=gnu17 +endif WFLAGS:=-Wall -Wno-trigraphs ifndef GCC295 #WFLAGS+=-Wno-packed diff --git a/src/Sourcefile b/src/Sourcefile index 4d117111d..227e6c95a 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -94,4 +94,3 @@ lua_skinlib.c lua_thinkerlib.c lua_udatalib.c lua_glib.c -hashtable.c -- 2.54.0 From 8b2e6ea17bed2ccb4be5083d6213bc628e999f20 Mon Sep 17 00:00:00 2001 From: Indev Date: Wed, 28 May 2025 16:54:37 +0300 Subject: [PATCH 03/35] libpeethread --- src/Makefile.d/dedicated.mk | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Makefile.d/dedicated.mk b/src/Makefile.d/dedicated.mk index 698ea5531..fef452467 100644 --- a/src/Makefile.d/dedicated.mk +++ b/src/Makefile.d/dedicated.mk @@ -4,10 +4,7 @@ sources+=$(call List,dedicated/Sourcefile) opts+=-DDEDICATED -ifdef FREEBSD -# on FreeBSD, we have to link to libpthread explicitly libs+=-lpthread -endif ifdef MINGW libs+=-mconsole -- 2.54.0 From 393ade780cc8b7193af238eea11d5a4f5ba3e895 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 14:42:42 +0100 Subject: [PATCH 04/35] add missing "time" include from dedi i_system --- src/dedicated/i_system.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index e568873f0..58840b1d3 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -131,6 +131,8 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #endif +#include + // Locations for searching the srb2.srb #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2Kart" -- 2.54.0 From b6923d0d0dc7e4ee18d4ac3a7507c7dbb0a95a63 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 16:18:13 +0200 Subject: [PATCH 05/35] readd flexible array for softwarepatch columnofs how did this ever work lel --- src/r_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_defs.h b/src/r_defs.h index 95f8a796d..a202b49ef 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -668,7 +668,7 @@ typedef struct INT16 height; INT16 leftoffset; // pixels to the left of origin INT16 topoffset; // pixels below the origin - INT32 columnofs[8]; // only [width] used + INT32 columnofs[]; // only [width] used // the [0] is &columnofs[width] } ATTRPACK softwarepatch_t; -- 2.54.0 From 1219ecf818581959f6afab9ced175904816c2f92 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 16:26:26 +0200 Subject: [PATCH 06/35] check for 32bit with __SIZEOF_POINTER__ for precip drawdistance thx @chromaticpipe for the tip! --- src/r_main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index 5a7d77acd..f16d138ee 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -125,16 +125,17 @@ static CV_PossibleValue_t drawdist_cons_t[] = { {8192, "8192"}, {12288, "12288"}, {20480, "20480"}, {24576, "24576"},{0, "Infinite"}, {0, NULL}}; -#if defined(__x86_64__) || defined(__amd64__) || defined(__aarch64__) || defined(__arm64__) // only for 64bit (idk how else to proper check lmao) +#if __SIZEOF_POINTER__ < 8 // only for 64bit static CV_PossibleValue_t drawdist_precip_cons_t[] = { - {256, "256"}, {512, "512"}, {768, "768"}, + {256, "256"}, {512, "512"}, {768, "768"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, - {3072, "3072"}, {4096, "4096"}, {0, "None"}, {0, NULL}}; + {0, "None"}, {0, NULL}}; + #else static CV_PossibleValue_t drawdist_precip_cons_t[] = { - {256, "256"}, {512, "512"}, {768, "768"}, - {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, - {0, "None"}, {0, NULL}}; + {256, "256"}, {512, "512"}, {768, "768"}, + {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, + {3072, "3072"}, {4096, "4096"}, {0, "None"}, {0, NULL}}; #endif static CV_PossibleValue_t maxinterpdist_cons_t[] = { -- 2.54.0 From 18914f22f20e204917d50824645639b6ee0418b0 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 18:29:18 +0200 Subject: [PATCH 07/35] remove crappy memcpy redifine from md5 --- src/md5.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/md5.c b/src/md5.c index 66d563666..8292fb9ee 100644 --- a/src/md5.c +++ b/src/md5.c @@ -26,12 +26,6 @@ #if defined (STDC_HEADERS) || defined (_LIBC) #include -#else - #ifndef HAVE_MEMCPY - #if !(defined (_WIN32) && !defined (__CYGWIN__)) && !defined (__APPLE__) - #define memcpy(d, s, n) bcopy ((s), (d), (n)) - #endif - #endif #endif #include "md5.h" -- 2.54.0 From 346dee019ca4e7571be7baf83104e2bd43c2b17b Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 18:30:26 +0200 Subject: [PATCH 08/35] fix compiler warning bout playeringame --- src/d_clisrv.c | 14 +++++++------- src/d_netcmd.c | 7 ++----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9625934fc..98b4b1e55 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1693,7 +1693,7 @@ static void SV_SendPlayerInfo(INT32 node) continue; } - if (playeringame[i] == UINT8_MAX || !playeringame[i]) + if (playernode[i] == UINT8_MAX || !playeringame[i]) { netbuffer->u.playerinfo[i].node = 255; // This slot is empty. continue; @@ -5324,18 +5324,18 @@ static void HandlePacketFromPlayer(SINT8 node) /// \todo Use a separate cvar for that kind of timeout? freezetimeout[node] = I_GetTime() + connectiontimeout; - // If we've alredy received a ticcmd for this tic, just submit it for the next one. - tic_t faketic = maketic; - if ((!!(netcmds[maketic % TICQUEUE][netconsole].angleturn & TICCMD_RECEIVED)) - && (maketic - firstticstosend < TICQUEUE - 1)) - faketic++; - // Don't do anything for packets of type NODEKEEPALIVE? // Sryder 2018/07/01: Update the freezetimeout still! if (netbuffer->packettype == PT_NODEKEEPALIVE || netbuffer->packettype == PT_NODEKEEPALIVEMIS) break; + // If we've alredy received a ticcmd for this tic, just submit it for the next one. + tic_t faketic = maketic; + if ((!!(netcmds[maketic % TICQUEUE][netconsole].angleturn & TICCMD_RECEIVED)) + && (maketic - firstticstosend < TICQUEUE - 1)) + faketic++; + // Copy ticcmd G_MoveTiccmd(&netcmds[faketic%TICQUEUE][netconsole], &netbuffer->u.clientpak.cmd, 1); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5b8a8c18b..862ebb679 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -216,11 +216,8 @@ static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2 static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; static CV_PossibleValue_t sleeping_cons_t[] = {{0, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Teleports"}, - {3, "None"}, {0, NULL}}; - -static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Non-Random"}, - {3, "None"}, {0, NULL}}; +static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Teleports"}, {3, "None"}, {0, NULL}}; +static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Non-Random"}, {3, "None"}, {0, NULL}}; //static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; static CV_PossibleValue_t match_scoring_cons_t[] = {{0, "Normal"}, {1, "Classic"}, {0, NULL}}; -- 2.54.0 From 19e5366c5bef6d2b98825a3fbc1847d614b2fa94 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 18:31:21 +0200 Subject: [PATCH 09/35] add wireframe mode for ogl --- src/hardware/hw_main.c | 20 ++++++++++++++++++-- src/hardware/hw_main.h | 2 ++ src/hardware/r_opengl/r_opengl.c | 7 +++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 94767ff5d..0f308017d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -226,6 +226,8 @@ consvar_t cv_glsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, consvar_t cv_glbatching = {"gr_batching", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_glwireframe = {"gr_wireframe", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_glrenderdistance = {"gr_renderdistance", "Max", CV_SAVE, glrenderdistance_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_glhorizonlines = {"gr_horizonlines", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -338,6 +340,12 @@ static void HWR_SetShaderState(void) GL_SetSpecialState(HWD_SET_SHADERS, HWR_UseShader() ? 1 : 0); } + +static boolean HWR_IsWireframeMode(void) +{ + return (cv_glwireframe.value /*&& cv_debug*/); +} + static boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel) { if (R_ThingIsFullBright(thing)) @@ -5259,6 +5267,9 @@ static void HWR_DrawSkyBackground(void) if (drewsky) return; + if (HWR_IsWireframeMode()) + return; + GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated); memcpy(&dometransform, &atransform, sizeof(FTransform)); @@ -5461,8 +5472,8 @@ void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *pl HWR_PortalClipping(rootportal); } - // Set transform. - GL_SetTransform(&atransform); + if (HWR_IsWireframeMode()) + GL_SetSpecialState(HWD_SET_WIREFRAME, 1); ps_numbspcalls.value.i = 0; ps_numpolyobjects.value.i = 0; @@ -5527,6 +5538,9 @@ void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *pl ps_hw_nodedrawtime.value.p = 0; HWR_RenderDrawNodes(); + if (HWR_IsWireframeMode()) + GL_SetSpecialState(HWD_SET_WIREFRAME, 0); + HWR_FreePortalList(portallist); } @@ -5801,6 +5815,8 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glbatching); + CV_RegisterVar(&cv_glwireframe); + CV_RegisterVar(&cv_glrenderdistance); CV_RegisterVar(&cv_glhorizonlines); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index b8d6ef939..87b1faaf4 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -202,6 +202,8 @@ extern consvar_t cv_glsolvetjoin; extern consvar_t cv_glbatching; +extern consvar_t cv_glwireframe; + extern consvar_t cv_glrenderdistance; extern consvar_t cv_glhorizonlines; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 12ec0cd97..07ceaf86f 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -350,6 +350,8 @@ typedef void (APIENTRY * PFNglDisable) (GLenum cap); static PFNglDisable pglDisable; typedef void (APIENTRY * PFNglGetFloatv) (GLenum pname, GLfloat *params); static PFNglGetFloatv pglGetFloatv; +typedef void (APIENTRY * PFNglPolygonMode) (GLenum, GLenum); +static PFNglPolygonMode pglPolygonMode; /* Depth Buffer */ typedef void (APIENTRY * PFNglClearDepth) (GLclampd depth); @@ -549,6 +551,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglGetFloatv, glGetFloatv) GETOPENGLFUNC(pglGetIntegerv, glGetIntegerv) GETOPENGLFUNC(pglGetString, glGetString) + GETOPENGLFUNC(pglPolygonMode, glPolygonMode) GETOPENGLFUNC(pglClearDepth, glClearDepth) GETOPENGLFUNC(pglDepthFunc, glDepthFunc) @@ -2364,6 +2367,10 @@ void GL_SetSpecialState(hwdspecialstate_t IdState, INT32 Value) GL_Flush(); //??? if we want to change filter mode by texture, remove this break; + case HWD_SET_WIREFRAME: + pglPolygonMode(GL_FRONT_AND_BACK, Value ? GL_LINE : GL_FILL); + break; + case HWD_SET_TEXTURE_FORMAT: gltexformat = (Value == 32) ? GL_RGBA : GL_RGB5_A1; GL_Flush(); -- 2.54.0 From f15d3be263cad5ee319646cad281ef89283ac730 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 16:37:37 +0100 Subject: [PATCH 10/35] forgor the hw state lel --- src/hardware/hw_defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 08cce42c9..1da42770a 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -318,6 +318,8 @@ enum hwdsetspecialstate HWD_SET_TEXTUREFILTERMODE, HWD_SET_TEXTUREANISOTROPICMODE, + HWD_SET_WIREFRAME, + HWD_SET_MSAA, HWD_SET_SCREEN_TEXTURES, -- 2.54.0 From ff474d18ee6a6c67ae315b55eba3b0177474f008 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 21:42:13 +0200 Subject: [PATCH 11/35] remove this prob wrong assumption, our netcode sucks massive ass --- src/d_clisrv.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 98b4b1e55..712cf8dc8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1687,13 +1687,7 @@ static void SV_SendPlayerInfo(INT32 node) for (i = 0; i < MSCOMPAT_MAXPLAYERS; i++) { - if (i >= MAXPLAYERS) - { - netbuffer->u.playerinfo[i].node = 255; - continue; - } - - if (playernode[i] == UINT8_MAX || !playeringame[i]) + if ((i >= MAXPLAYERS) || !playeringame[i]) { netbuffer->u.playerinfo[i].node = 255; // This slot is empty. continue; -- 2.54.0 From a6898bd1cd8c091e356d22dd8fec91559c35f991 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 22:11:46 +0200 Subject: [PATCH 12/35] this memset is incorrect and does nothing --- src/d_clisrv.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 712cf8dc8..4e5a1cd9a 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1068,6 +1068,7 @@ static void SV_RequireResynch(INT32 node) // Initial setup memset(resynch_sent[node], 0, MAXPLAYERS); + for (i = 0; i < MAXPLAYERS; ++i) { if (!playeringame[i]) // Player not in game so just drop it from required synch @@ -1772,8 +1773,6 @@ static boolean SV_SendServerConfig(INT32 node) memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins)); memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor)); - memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers)); - for (i = 0; i < MAXPLAYERS; i++) { netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i]; @@ -3269,7 +3268,7 @@ void CL_ClearPlayer(INT32 playernum) P_RemoveMobj(players[playernum].mo); } - memset(&players[playernum], 0, sizeof (player_t)); + memset(&players[playernum], 0, sizeof(player_t)); } // @@ -4278,14 +4277,14 @@ void SV_ResetServer(void) sprintf(player_names[i], "Player %d", i + 1); } - memset(player_name_changes, 0, sizeof player_name_changes); + memset(player_name_changes, 0, sizeof(player_name_changes)); - memset(playeringame, false, sizeof playeringame); - memset(playernode, UINT8_MAX, sizeof playernode); + memset(playeringame, false, sizeof(playeringame)); + memset(playernode, UINT8_MAX, sizeof(playernode)); pingmeasurecount = 1; - memset(realpingtable, 0, sizeof realpingtable); - memset(playerpingtable, 0, sizeof playerpingtable); + memset(realpingtable, 0, sizeof(realpingtable)); + memset(playerpingtable, 0, sizeof(playerpingtable)); ClearAdminPlayers(); -- 2.54.0 From 7c34733eea9aa8f6c00bf71ca923722b016584a4 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 23:57:53 +0200 Subject: [PATCH 13/35] add nofork parameter to dedibuild --- src/dedicated/i_system.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 58840b1d3..6ab748f86 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -1439,7 +1439,10 @@ INT32 I_StartupSystem(void) { I_StartupConsole(); #ifdef NEWSIGNALHANDLER - I_Fork(); + // This is useful when debugging. It lets GDB attach to + // the correct process easily. + if (!M_CheckParm("-nofork")) + I_Fork(); #endif #ifdef HAVE_THREADS I_start_threads(); -- 2.54.0 From fb9c459269aff534af9ef239bf62a19bb7af7c71 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 11:47:37 +0200 Subject: [PATCH 14/35] readd cubeapply check here --- src/v_video.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/v_video.c b/src/v_video.c index 0f3306696..7df5cacea 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -457,6 +457,9 @@ static void LoadPalette(const char *lumpname) #endif pLocalPalette[i].s.alpha = 0xFF; + if (!Cubeapply) + continue; + // lerp of colour cubing! if you want, make it smoother yourself V_CubeApply(&pLocalPalette[i].s.red, &pLocalPalette[i].s.green, &pLocalPalette[i].s.blue); } -- 2.54.0 From 5e532a76cfba090a8150d72c7ec0cb018cde4c39 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 11:49:43 +0200 Subject: [PATCH 15/35] reset the palette earlier during levelload generally make this behave like srb2/rr again --- src/p_setup.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index fe3a0d7fc..57894c074 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2807,6 +2807,10 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate) CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer + // Reset the palette + if (rendermode != render_none) + V_SetPaletteLump("PLAYPAL"); + // Initialize sector node list. P_Initsecnode(); @@ -2878,10 +2882,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate) // Reset the palette now all fades have been done if (rendermode != render_none) - { - //V_ResetPaletteCVars(); // dont carry over changed palettes - V_SetPaletteLump(GetPalette()); // Set the level palette - } + V_ReloadPalette(); // Set the level palette // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." /*if (rendermode != render_none) -- 2.54.0 From e88093d9cf2a129a26ae05049a79c32294c84fb1 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 11:50:08 +0200 Subject: [PATCH 16/35] no need for an else here --- src/p_setup.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 57894c074..47327e3ca 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2872,12 +2872,9 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate) F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); F_WipeEndScreen(); - F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false); - } - else //dedicated servers - { - F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false); } + + F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false); } // Reset the palette now all fades have been done -- 2.54.0 From a364068abbbe8f10316dc80f0c6cf6171e166363 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 13:26:52 +0200 Subject: [PATCH 17/35] add a bunch of checks for if G_BuildMapTitle returns NULL --- src/command.c | 1 - src/d_netcmd.c | 9 +++++++-- src/discord.c | 14 ++++++++++---- src/g_game.c | 11 +++++++---- src/m_menu.c | 52 +++++++++++++++++++++++++++++++++----------------- src/s_sound.c | 9 ++++++--- 6 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/command.c b/src/command.c index e7dd9cc01..4e43e2cb5 100644 --- a/src/command.c +++ b/src/command.c @@ -240,7 +240,6 @@ void COM_ImmedExecute(const char *ptext) while (i < strlen(ptext)) { - quotes = 0; for (j = 0; i < strlen(ptext); i++,j++) { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 862ebb679..1970b5323 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2774,7 +2774,7 @@ static void Command_Map_f(void) // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer else { - if (!mapheaderinfo[newmapnum-1] || mapheaderinfo[newmapnum-1] == NULL) + if (!mapheaderinfo[newmapnum-1]) { CONS_Alert(CONS_WARNING, M_GetText("Invalid mapheaderinfo for Course %s (%s)\n"), realmapname, G_BuildMapName(newmapnum)); Z_Free(realmapname); @@ -3028,9 +3028,14 @@ static void Command_ReplayMarker(void) adjustedleveltime = 0; char *title = G_BuildMapTitle(gamemap); - snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername); + if (title) + { + snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername); Z_Free(title); + } + else + snprintf(demo.titlename, 64, "[%i:%02d/%.5s]", G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername); CONS_Printf("Replay will be saved!\n"); } diff --git a/src/discord.c b/src/discord.c index cd7dafa8f..207a249a6 100644 --- a/src/discord.c +++ b/src/discord.c @@ -388,7 +388,7 @@ static void DRPC_GotServerIP(UINT32 address) --------------------------------------------------*/ static const char *DRPC_GetServerIP(void) { - const char *address; + const char *address; // If you're connected if (I_GetNodeAddress && (address = I_GetNodeAddress(servernode)) != NULL) @@ -489,7 +489,7 @@ void DRPC_UpdatePresence(void) { #endif discordPresence.state = "Private"; -#ifdef MASTERSERVER +#ifdef MASTERSERVER } #endif @@ -571,9 +571,15 @@ void DRPC_UpdatePresence(void) { // Map name on tool tip char *title = G_BuildMapTitle(gamemap); - snprintf(mapname, 48, "Map: %s", title); + if (title) + { + snprintf(mapname, 48, "Map: %s", title); + Z_Free(title); + } + else + snprintf(mapname, 48, "Map: UNKNOWN"); + discordPresence.largeImageText = mapname; - Z_Free(title); } if (gamestate == GS_LEVEL && Playing()) diff --git a/src/g_game.c b/src/g_game.c index 200ce7834..dd3823f8a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3998,7 +3998,6 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool } } - char *G_BuildMapTitle(INT32 mapnum) { char *title = NULL; @@ -6068,15 +6067,19 @@ void G_BeginRecording(void) char *title = G_BuildMapTitle(gamemap); // Print to a separate temp buffer instead of demo.titlename, so we can use it in M_TextInputSetString - snprintf(demotitlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername); + if (title) + { + snprintf(demotitlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername); + Z_Free(title); + } + else + snprintf(demotitlename, 64, "%s", modeattacking ? "Time Attack" : connectedservername); // Init just in case it isn't initialized already M_TextInputInit(&demo.titlenameinput, demo.titlename, sizeof(demo.titlename)); // This will indirectly assign to demo.titlename too M_TextInputSetString(&demo.titlenameinput, demotitlename); - - Z_Free(title); } // demo checksum diff --git a/src/m_menu.c b/src/m_menu.c index 2fb38a4d5..65dab3e6a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7167,8 +7167,11 @@ static void DrawReplayHutReplayInfo(void) if (mapheaderinfo[demolist[dir_on[menudepthleft]].map-1]) { char *title = G_BuildMapTitle(demolist[dir_on[menudepthleft]].map); - V_DrawString(x, y, V_SNAPTOTOP|MENUCAPS, title); - Z_Free(title); + if (title) + { + V_DrawString(x, y, V_SNAPTOTOP|MENUCAPS, title); + Z_Free(title); + } } else V_DrawString(x, y, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT, "Level is not loaded."); @@ -8120,6 +8123,9 @@ UINT8 skyRoomMenuTranslations[MAXUNLOCKABLES]; static char *M_GetConditionString(condition_t cond) { + char *title = NULL; + char *response = NULL; + switch(cond.type) { case UC_PLAYTIME: @@ -8146,33 +8152,45 @@ static char *M_GetConditionString(condition_t cond) G_TicsToSeconds(cond.requirement)); case UC_MAPVISITED: { - char *title = G_BuildMapTitle(cond.requirement-1); - char *response = va("Visit %s", title); - Z_Free(title); + title = G_BuildMapTitle(cond.requirement-1); + if (title) + { + response = va("Visit %s", title); + Z_Free(title); + } return response; } case UC_MAPBEATEN: { - char *title = G_BuildMapTitle(cond.requirement-1); - char *response = va("Beat %s", title); - Z_Free(title); + title = G_BuildMapTitle(cond.requirement-1); + if (title) + { + response = va("Beat %s", title); + Z_Free(title); + } return response; } case UC_MAPALLEMERALDS: { - char *title = G_BuildMapTitle(cond.requirement-1); - char *response = va("Beat %s w/ all emeralds", title); - Z_Free(title); + title = G_BuildMapTitle(cond.requirement-1); + if (title) + { + response = va("Beat %s w/ all emeralds", title); + Z_Free(title); + } return response; } case UC_MAPTIME: { - char *title = G_BuildMapTitle(cond.extrainfo1-1); - char *response = va("Beat %s in %i:%02i.%02i", title, - G_TicsToMinutes(cond.requirement, true), - G_TicsToSeconds(cond.requirement), - G_TicsToCentiseconds(cond.requirement)); - Z_Free(title); + title = G_BuildMapTitle(cond.extrainfo1-1); + if (title) + { + response = va("Beat %s in %i:%02i.%02i", title, + G_TicsToMinutes(cond.requirement, true), + G_TicsToSeconds(cond.requirement), + G_TicsToCentiseconds(cond.requirement)); + Z_Free(title); + } return response; } case UC_TOTALEMBLEMS: diff --git a/src/s_sound.c b/src/s_sound.c index 922d864d5..cf75df56a 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2042,9 +2042,12 @@ static boolean S_SkipIntroMusic(void) char *maptitle = G_BuildMapTitle(gamemap); // Zzz... - // check if menu music is playing, otherwise it may continue playing - if (!stricmp(music.name, "titles") || (maptitle && (!stricmp(maptitle, "Wandering Falls")))) // wandering balls changes its song when the race starts Zzz... - skip = false; + if (maptitle) + { + // check if menu music is playing, otherwise it may continue playing + if (!stricmp(music.name, "titles") || (maptitle && (!stricmp(maptitle, "Wandering Falls")))) // wandering balls changes its song when the race starts Zzz... + skip = false; + } Z_Free(maptitle); -- 2.54.0 From cf42c35b9fda511217a4dc72c58d8275cb6b5742 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 13:29:25 +0200 Subject: [PATCH 18/35] add mo checks to automap stuff --- src/am_map.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/am_map.c b/src/am_map.c index f91273e8b..11b3796b0 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -197,7 +197,7 @@ static fixed_t scale_mtof = (fixed_t)INITSCALEMTOF; // used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof) static fixed_t scale_ftom; -static player_t *plr; // the player represented by an arrow +static player_t *plr = NULL; // the player represented by an arrow static boolean followplayer = true; // specifies whether to follow the player around @@ -237,7 +237,7 @@ static inline void AM_restoreScaleAndLoc(void) m_x = old_m_x; m_y = old_m_y; } - else + else if (plr && plr->mo) { m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2; m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2; @@ -318,7 +318,8 @@ static void AM_initVariables(void) break; plr = &players[pnum]; - if (plr != NULL && plr->mo != NULL) + + if (plr && plr->mo) { m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2; m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2; @@ -597,6 +598,9 @@ static inline void AM_changeWindowScale(void) static inline void AM_doFollowPlayer(void) { + if (!plr || !plr->mo) + return; + if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y) { m_x = FTOM(MTOF(plr->mo->x >> FRACTOMAPBITS)) - m_w/2; -- 2.54.0 From eca9c60d9b8a9122fe9078462e615b8f9b3ba4dc Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 17:58:00 +0200 Subject: [PATCH 19/35] call HWR_LoadMapTextures in paletterender toggle callback from srb2 pr --- src/hardware/hw_batching.c | 2 +- src/hardware/hw_main.c | 4 ++-- src/st_stuff.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 3655beb8a..b8490f4ed 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -124,7 +124,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt polygonArray[polygonArraySize].numVerts = iNumPts; polygonArray[polygonArraySize].polyFlags = PolyFlags; polygonArray[polygonArraySize].texture = current_texture; - polygonArray[polygonArraySize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target; + polygonArray[polygonArraySize].shader = (shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target; polygonArray[polygonArraySize].horizonSpecial = horizonSpecial; polygonArraySize++; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0f308017d..51f3346dc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5764,7 +5764,7 @@ static void HWR_TogglePaletteRendering(void) // If the r_opengl "texture palette" stays the same during this switch, these textures // will not be cleared out. However they are still out of date since the // composite texture blending method has changed. Therefore they need to be cleared. - GL_ClearMipMapCache(); + HWR_LoadMapTextures(numtextures); } } else @@ -5778,7 +5778,7 @@ static void HWR_TogglePaletteRendering(void) // If the r_opengl "texture palette" stays the same during this switch, these textures // will not be cleared out. However they are still out of date since the // composite texture blending method has changed. Therefore they need to be cleared. - GL_ClearMipMapCache(); + HWR_LoadMapTextures(numtextures); } } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 04523f577..4f5401aae 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -187,7 +187,7 @@ void ST_doPaletteStuff(void) #ifdef HWRENDER if (rendermode == render_opengl && !HWR_PalRenderFlashpal()) - palette = 0; // No flashpals here in OpenGL + palette = 0; // Don't set the palette to a flashpal in OpenGL's truecolor mode #endif palette = min(max(palette, 0), 13); -- 2.54.0 From bf44a054a1a614d1756813fec90311d6e708897c Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 18:17:07 +0200 Subject: [PATCH 20/35] move HWR_GetTexturePalette calls to after early returns/where they are used --- src/hardware/hw_cache.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 85e50465a..36f6a57a5 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -46,12 +46,16 @@ RGBA_t *HWR_GetTexturePalette(void) static INT32 format2bpp(GLTextureFormat_t format) { - if (format == GL_TEXFMT_RGBA) - return 4; - else if (format == GL_TEXFMT_ALPHA_INTENSITY_88 || format == GL_TEXFMT_AP_88) - return 2; - else - return 1; + switch (format) + { + case GL_TEXFMT_RGBA: + return 4; + case GL_TEXFMT_ALPHA_INTENSITY_88: + case GL_TEXFMT_AP_88: + return 2; + default: + return 1; + } } // This code was originally placed directly in HWR_DrawPatchInCache. @@ -221,8 +225,6 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, if (texture->width <= 0 || texture->height <= 0) return; - palette = HWR_GetTexturePalette(); - x1 = patch->originx; width = SHORT(realpatch->width); height = SHORT(realpatch->height); @@ -234,6 +236,8 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, if (patch->originy > texture->height || (patch->originy + height) < 0) return; // patch not located within texture's y bounds, ignore + palette = HWR_GetTexturePalette(); + // patch is actually inside the texture! // now check if texture is partly off-screen and adjust accordingly @@ -323,7 +327,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe boolean skyspecial = false; // poor hack for Legacy large skies.. RGBA_t *palette; - palette = HWR_GetTexturePalette(); texture = textures[texnum]; @@ -361,6 +364,8 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe INT32 j; RGBA_t col; + palette = HWR_GetTexturePalette(); + col = palette[HWR_CHROMAKEY_EQUIVALENTCOLORINDEX]; for (idx = 0, j = 0; j < blockheight; j++) -- 2.54.0 From fe682a80712a4bc9a4d78a46539f5d1af0682caa Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 18:57:36 +0200 Subject: [PATCH 21/35] only make screentexture for postprocess if we need to gives quite a neat perfboost on the gpu side --- src/hardware/hw_main.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 51f3346dc..af8a6e160 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -340,7 +340,6 @@ static void HWR_SetShaderState(void) GL_SetSpecialState(HWD_SET_SHADERS, HWR_UseShader() ? 1 : 0); } - static boolean HWR_IsWireframeMode(void) { return (cv_glwireframe.value /*&& cv_debug*/); @@ -4235,7 +4234,6 @@ static void *HWR_CreateDrawNode(gl_drawnode_type_t type) Z_Realloc(drawnodes, alloceddrawnodes * sizeof(gl_drawnode_t), PU_LEVEL, &drawnodes); } - drawnode = &drawnodes[numdrawnodes++]; drawnode->type = type; @@ -5889,7 +5887,6 @@ static void COM_HWR_glinfo(void) CONS_Printf("Unrecognized argument: %s\n", argv); return; } - } CONS_Printf("\x88OpenGL %s\x80\n", gl_version); @@ -5983,7 +5980,7 @@ static void HWR_DoPostProcessor(player_t *player) // Armageddon Blast Flash! // Could this even be considered postprocessor? - if (!HWR_PalRenderFlashpal() && player->flashcount) + if (player->flashcount && !HWR_PalRenderFlashpal()) { FOutVector v[4]; FSurfaceInfo Surf; @@ -6009,19 +6006,19 @@ static void HWR_DoPostProcessor(player_t *player) if (cv_glscreentextures.value != 2) // screen textures are needed for the rest of the effects return; - // Capture the screen for intermission and screen waving - if (gamestate != GS_INTERMISSION) - GL_MakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1); - - if (splitscreen) // Not supported in splitscreen - someone want to add support? - return; - - //UINT8 viewnum = R_GetViewNumber(); // see above + //UINT8 viewnum = R_GetViewNumber(); // see below //camera_t *thiscam = &camera[viewnum]; camera_t *thiscam = &camera[0]; + // Not supported in splitscreen - someone want to add support? + const boolean screenwave = (!splitscreen && (thiscam->postimg & POSTIMG_WATER || thiscam->postimg & POSTIMG_HEAT)); + + // Capture the screen for intermission and screen waving + if ((lastdraw || screenwave) && gamestate != GS_INTERMISSION) + GL_MakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1); + // Drunken vision! WooOOooo~ - if (thiscam->postimg & POSTIMG_WATER || thiscam->postimg & POSTIMG_HEAT) + if (screenwave) { // 10 by 10 grid. 2 coordinates (xy) float v[SCREENVERTS][SCREENVERTS][2]; @@ -6055,6 +6052,7 @@ static void HWR_DoPostProcessor(player_t *player) v[x][y][1] = (y/((float)(SCREENVERTS-1.0f)/9.0f))-4.5f; } } + GL_PostImgRedraw(v); // Capture the screen again for screen waving on the intermission -- 2.54.0 From 57b2316c42074ce02eccfa2c71e06303fd98adfb Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 18:59:27 +0200 Subject: [PATCH 22/35] didnt mean to change this lel --- src/hardware/hw_main.c | 2 +- src/hardware/hw_main.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index af8a6e160..e25364bee 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5980,7 +5980,7 @@ static void HWR_DoPostProcessor(player_t *player) // Armageddon Blast Flash! // Could this even be considered postprocessor? - if (player->flashcount && !HWR_PalRenderFlashpal()) + if (!HWR_PalRenderFlashpal() && player->flashcount) { FOutVector v[4]; FSurfaceInfo Surf; diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 87b1faaf4..6dc0d23a6 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -225,7 +225,7 @@ FUNCINLINE static ATTRINLINE boolean HWR_ShouldUsePaletteRendering(void) FUNCINLINE static ATTRINLINE boolean HWR_PalRenderFlashpal(void) { - return (HWR_ShouldUsePaletteRendering() && cv_glflashpal.value); + return (cv_glflashpal.value && HWR_ShouldUsePaletteRendering()); } #endif -- 2.54.0 From c5b72f24b5ea6044047d240b5b422fed92624427 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 17:16:51 +0100 Subject: [PATCH 23/35] thanks windoze very cool --- src/Makefile.d/win32.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index 353c666ee..38b437fed 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -38,7 +38,7 @@ libs+=-lws2_32 endif ifndef MINGW64 -libs+=--large-address-aware +#libs+=--large-address-aware NOLIBBACKTRACE=1 endif -- 2.54.0 From f5cb473f3dbe6d1c669e657796e0720d4925a9eb Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 17:27:38 +0100 Subject: [PATCH 24/35] thanks windoze very cool part 2 --- src/Makefile.d/win32.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index 38b437fed..4946c4ca2 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -38,7 +38,7 @@ libs+=-lws2_32 endif ifndef MINGW64 -#libs+=--large-address-aware +libs+=-Wl,--large-address-aware NOLIBBACKTRACE=1 endif -- 2.54.0 From c05068f22fff7b0e7955221bf1f09cd1b85e6efe Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 19:35:15 +0200 Subject: [PATCH 25/35] why are those still here lel --- src/blua/Makefile.cfg | 55 --------------- src/sdl/MakeCYG.cfg | 16 ----- src/sdl/MakeNIX.cfg | 76 -------------------- src/sdl/Makefile.cfg | 106 ---------------------------- src/win32/Makefile.cfg | 154 ----------------------------------------- 5 files changed, 407 deletions(-) delete mode 100644 src/blua/Makefile.cfg delete mode 100644 src/sdl/MakeCYG.cfg delete mode 100644 src/sdl/MakeNIX.cfg delete mode 100644 src/sdl/Makefile.cfg delete mode 100644 src/win32/Makefile.cfg diff --git a/src/blua/Makefile.cfg b/src/blua/Makefile.cfg deleted file mode 100644 index f3d38fb70..000000000 --- a/src/blua/Makefile.cfg +++ /dev/null @@ -1,55 +0,0 @@ -ifdef UNIXCOMMON -LUA_CFLAGS+=-DLUA_USE_POSIX -endif -ifdef LINUX -LUA_CFLAGS+=-DLUA_USE_POSIX -endif -ifdef GCC43 -ifndef GCC44 -WFLAGS+=-Wno-logical-op -endif -endif - -OBJS:=$(OBJS) \ - $(OBJDIR)/lapi.o \ - $(OBJDIR)/lbaselib.o \ - $(OBJDIR)/ldo.o \ - $(OBJDIR)/ldblib.o \ - $(OBJDIR)/lfunc.o \ - $(OBJDIR)/linit.o \ - $(OBJDIR)/liolib.o \ - $(OBJDIR)/llex.o \ - $(OBJDIR)/lmem.o \ - $(OBJDIR)/lobject.o \ - $(OBJDIR)/lstate.o \ - $(OBJDIR)/lstrlib.o \ - $(OBJDIR)/ltablib.o \ - $(OBJDIR)/lundump.o \ - $(OBJDIR)/lzio.o \ - $(OBJDIR)/lauxlib.o \ - $(OBJDIR)/lcode.o \ - $(OBJDIR)/ldebug.o \ - $(OBJDIR)/ldump.o \ - $(OBJDIR)/lgc.o \ - $(OBJDIR)/lopcodes.o \ - $(OBJDIR)/lparser.o \ - $(OBJDIR)/lstring.o \ - $(OBJDIR)/ltable.o \ - $(OBJDIR)/ltm.o \ - $(OBJDIR)/lvm.o \ - $(OBJDIR)/lua_script.o \ - $(OBJDIR)/lua_baselib.o \ - $(OBJDIR)/lua_blockmaplib.o \ - $(OBJDIR)/lua_mathlib.o \ - $(OBJDIR)/lua_hooklib.o \ - $(OBJDIR)/lua_consolelib.o \ - $(OBJDIR)/lua_infolib.o \ - $(OBJDIR)/lua_mobjlib.o \ - $(OBJDIR)/lua_playerlib.o \ - $(OBJDIR)/lua_skinlib.o \ - $(OBJDIR)/lua_thinkerlib.o \ - $(OBJDIR)/lua_maplib.o \ - $(OBJDIR)/lua_hudlib.o \ - $(OBJDIR)/lua_hudlib_drawlist.o \ - $(OBJDIR)/lua_udatalib.o \ - $(OBJDIR)/lua_glib.o diff --git a/src/sdl/MakeCYG.cfg b/src/sdl/MakeCYG.cfg deleted file mode 100644 index b78316b00..000000000 --- a/src/sdl/MakeCYG.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# sdl/makeCYG.cfg for SRB2/Cygwin -# - -# -#Cygwin, for debugging - - NOHW=1 - NOHS=1 - - OPTS+=-DLINUX - - i_system_o+=$(OBJDIR)/SRB2.res - - # name of the exefile - EXENAME?=lsdlsrb2.exe diff --git a/src/sdl/MakeNIX.cfg b/src/sdl/MakeNIX.cfg deleted file mode 100644 index 81991793e..000000000 --- a/src/sdl/MakeNIX.cfg +++ /dev/null @@ -1,76 +0,0 @@ -# -# sdl/makeNIX.cfg for SRB2/?nix -# - -#Valgrind support -ifdef VALGRIND -VALGRIND_PKGCONFIG?=valgrind -VALGRIND_CFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --cflags) -VALGRIND_LDFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --libs) -ZDEBUG=1 -LIBS+=$(VALGRIND_LDFLAGS) -ifdef GCC46 -WFLAGS+=-Wno-error=unused-but-set-variable -WFLAGS+=-Wno-unused-but-set-variable -endif -endif - -# -#here is GNU/Linux and other -# - - OPTS=-DUNIXCOMMON - -#Use -rdynamic so a backtrace log shows function names instead of addresses - LDFLAGS+=-rdynamic - - #LDFLAGS = -L/usr/local/lib - LIBS=-lm -ifdef LINUX - LIBS+=-lrt -ifdef NOTERMIOS - OPTS+=-DNOTERMIOS -endif -endif - -ifdef LINUX64 - OPTS+=-DLINUX64 -endif - -# -#here is Solaris -# -ifdef SOLARIS - NOIPX=1 - OPTS+=-DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP - OPTS+=-I/usr/local/include -I/opt/sfw/include - LDFLAGS+=-L/opt/sfw/lib - LIBS+=-lsocket -lnsl -endif - -# -#here is FreeBSD -# -ifdef FREEBSD - OPTS+=-DLINUX -DFREEBSD -I/usr/X11R6/include - SDL_CONFIG?=sdl11-config - LDFLAGS+=-L/usr/X11R6/lib - LIBS+=-lkvm -lexecinfo -endif - -# -#here is Mac OS X -# -ifdef MACOSX - OBJS+=$(OBJDIR)/mac_resources.o - OBJS+=$(OBJDIR)/mac_alert.o - LIBS+=-framework CoreFoundation -endif - -ifndef NOHW - OPTS+=-I/usr/X11R6/include - LDFLAGS+=-L/usr/X11R6/lib -endif - - # name of the exefile - EXENAME?=lsdl2srb2kart diff --git a/src/sdl/Makefile.cfg b/src/sdl/Makefile.cfg deleted file mode 100644 index 3cf04509b..000000000 --- a/src/sdl/Makefile.cfg +++ /dev/null @@ -1,106 +0,0 @@ -# -# sdl/makefile.cfg for SRB2/SDL -# - -# -#SDL...., *looks at Alam*, THIS IS A MESS! -# - -ifdef UNIXCOMMON -include sdl/MakeNIX.cfg -endif - -ifdef PANDORA -include sdl/SRB2Pandora/Makefile.cfg -endif #ifdef PANDORA - -ifdef CYGWIN32 -include sdl/MakeCYG.cfg -endif #ifdef CYGWIN32 - -ifdef SDL_PKGCONFIG -SDL_CFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --cflags) -SDL_LDFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --libs) -else -ifdef PREFIX - SDL_CONFIG?=$(PREFIX)-sdl2-config -else - SDL_CONFIG?=sdl2-config -endif - -ifdef STATIC - SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) - SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --static-libs) -else - SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) - SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --libs) -endif -endif - - - OBJS+=$(OBJDIR)/i_video.o $(OBJDIR)/dosstr.o $(OBJDIR)/endtxt.o $(OBJDIR)/hwsym_sdl.o - - OPTS+=-DDIRECTFULLSCREEN -DHAVE_SDL - -ifndef NOHW - OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o -endif - -ifdef NOMIXER - i_sound_o=$(OBJDIR)/sdl_sound.o -else - i_sound_o=$(OBJDIR)/mixer_sound.o - OPTS+=-DHAVE_MIXER - SDL_LDFLAGS+=-lSDL2_mixer -endif - -ifndef NOTHREADS - OPTS+=-DHAVE_THREADS - OBJS+=$(OBJDIR)/i_threads.o -endif - -ifdef SDL_TTF - OPTS+=-DHAVE_TTF - SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz - OBJS+=$(OBJDIR)/i_ttf.o -endif - -ifdef SDL_IMAGE - OPTS+=-DHAVE_IMAGE - SDL_LDFLAGS+=-lSDL2_image -endif - -ifdef SDL_NET - OPTS+=-DHAVE_SDLNET - SDL_LDFLAGS+=-lSDL2_net -endif - -ifdef MINGW -ifndef NOSDLMAIN - SDLMAIN=1 -endif -endif - -ifdef SDLMAIN - OPTS+=-DSDLMAIN -else -ifdef MINGW - SDL_CFLAGS+=-Umain - SDL_LDFLAGS+=-mconsole -endif -endif - -ifndef NOLIBBACKTRACE - OPTS+=-DHAVE_LIBBACKTRACE -ifdef MINGW64 - CPPFLAGS+=-I../libs/libbacktrace/include - LDFLAGS+=-L../libs/libbacktrace/lib/x86_64 -endif - LIBS:=-lbacktrace $(LIBS) -endif - -CFLAGS+=$(SDL_CFLAGS) -LIBS:=$(SDL_LDFLAGS) $(LIBS) -ifdef STATIC - LIBS+=$(shell $(SDL_CONFIG) --static-libs) -endif diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg deleted file mode 100644 index 4f8b39485..000000000 --- a/src/win32/Makefile.cfg +++ /dev/null @@ -1,154 +0,0 @@ -# -# win32/Makefile.cfg for SRB2/Minwgw -# - -# -#Mingw, if you don't know, that's Win32/Win64 -# - -ifdef MINGW64 - HAVE_LIBGME=1 - LIBGME_CFLAGS=-I../libs/gme/include - LIBGME_LDFLAGS=-L../libs/gme/win64 -lgme -ifdef HAVE_OPENMPT - LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc - LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86_64 -lopenmpt -endif - - SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDL2_mixer/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -else - HAVE_LIBGME=1 - LIBGME_CFLAGS=-I../libs/gme/include - LIBGME_LDFLAGS=-L../libs/gme/win32 -lgme -ifdef HAVE_OPENMPT - LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc - LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86 -lopenmpt -endif - SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDL2_mixer/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -endif - -ifndef NONET -ifndef MINGW64 #miniupnc is broken with MINGW64 - HAVE_MINIUPNPC=1 -endif -endif - -ifndef NO_DISCORDRPC - HAVE_DISCORDRPC=1 -endif - - OPTS=-DSTDC_HEADERS - -ifndef GCC44 - #OPTS+=-mms-bitfields -endif - - OPTS+=-D__USE_MINGW_ANSI_STDIO=0 - - LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 -ifdef MINGW64 - LIBS+=-lws2_32 -else -ifdef NO_IPV6 - LIBS+=-lwsock32 -else - LIBS+=-lws2_32 -endif -endif - -ifndef MINGW64 - CPPFLAGS+=-I../libs/drmingw/include - LDFLAGS+=-L../libs/drmingw/lib/win32 - LIBS+=-lmgwhelp -lexchndl -endif - - # name of the exefile - EXENAME?=srb2kart-saturn.exe - - i_system_o+=$(OBJDIR)/SRB2.res - #i_main_o+=$(OBJDIR)/win_dbg.o -ifndef NOHW - OPTS+=-DUSE_WGL_SWAP -endif - -ZLIB_CFLAGS?=-I../libs/zlib -ifdef MINGW64 -ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz64 -else -ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz32 -endif - -ifndef NOPNG -ifndef PNG_CONFIG - PNG_CFLAGS?=-I../libs/libpng-src -ifdef MINGW64 - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng64 -else - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng32 -endif #MINGW64 -endif #PNG_CONFIG -endif #NOPNG - -ifdef GETTEXT -ifndef CCBS - MSGFMT?=../libs/gettext/bin32/msgfmt.exe -endif -ifdef MINGW64 - CPPFLAGS+=-I../libs/gettext/include64 - LDFLAGS+=-L../libs/gettext/lib64 - LIBS+=-lmingwex -else - CPPFLAGS+=-I../libs/gettext/include32 - LDFLAGS+=-L../libs/gettext/lib32 - STATIC_GETTEXT=1 -endif #MINGW64 -ifdef STATIC_GETTEXT - LIBS+=-lasprintf -lintl -else - LIBS+=-lintl.dll -endif #STATIC_GETTEXT -endif #GETTEXT - -ifdef HAVE_MINIUPNPC - CPPFLAGS+=-I../libs/ -DSTATIC_MINIUPNPC -ifdef MINGW64 - LDFLAGS+=-L../libs/miniupnpc/mingw64 -else - LDFLAGS+=-L../libs/miniupnpc/mingw32 -endif #MINGW64 -endif - -ifndef NOCURL - CURL_CFLAGS+=-I../libs/curl/include -ifdef MINGW64 - CURL_LDFLAGS+=-L../libs/curl/lib64 -lcurl -else - CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl -endif #MINGW64 -endif - -ifdef HAVE_DISCORDRPC -ifdef MINGW64 - CPPFLAGS+=-I../libs/discord-rpc/win64-dynamic/include - LDFLAGS+=-L../libs/discord-rpc/win64-dynamic/lib -else - CPPFLAGS+=-I../libs/discord-rpc/win32-dynamic/include - LDFLAGS+=-L../libs/discord-rpc/win32-dynamic/lib -endif - LIBS+=-ldiscord-rpc -endif - -ifndef MINGW64 - LDFLAGS+=-Wl,--large-address-aware -endif - -ifndef MINGW64 - NOLIBBACKTRACE=1 -endif - -# disable dynamicbase if under msys2 -ifdef MSYSTEM - LDFLAGS+=-Wl,--disable-dynamicbase -endif -- 2.54.0 From e47e58a98262c1666e8d85af68562efe24c545c1 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 29 May 2025 21:14:19 +0200 Subject: [PATCH 26/35] fixup ceepeepee support --- src/Makefile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Makefile b/src/Makefile index e995b3ccf..cac95d35b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -134,6 +134,7 @@ include Makefile.d/util.mk ifdef PREFIX CC:=$(PREFIX)-gcc +CXX:=$(PREFIX)-g++ endif OBJDUMP_OPTS?=--wide --source --line-numbers @@ -270,15 +271,21 @@ opts+=$(WFLAGS) $(CPPFLAGS) $(CFLAGS) libs+=$(LDFLAGS) -lstdc++ asflags:=$(ASFLAGS) -x assembler-with-cpp +cxxopts:=$(opts) +cxxopts+=-std=c++17 +cxxopts+=$(CXXFLAGS) + cc=$(CC) cxx=$(CXX) ifdef DISTCC cc=distcc $(CC) +cxx=distcc $(CXX) endif ifdef CCACHE cc=ccache $(CC) +cxx=ccache $(CXX) endif ifndef SILENT @@ -293,8 +300,12 @@ SHELL ..... $(SHELL) CC ........ $(cc) +CXX ....... $(cxx) + CFLAGS .... $(opts) +CXXFLAGS .. $(cxxopts) + LDFLAGS ... $(libs) endef @@ -372,6 +383,19 @@ endif $(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$< endef +# dependency recipe template (C++) +# 1: source file suffix +# 2: extra flags to gcc +define _recipecxx = +$(depdir)/%.d : %.$(1) | $$$$(@D)/ +ifndef WINDOWSHELL +ifdef Echo_name + @printf '%-20.20s\r' $$< +endif +endif + $(.)$(cxx) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$< +endef + $(eval $(call _recipe,c)) $(eval $(call _recipe,cpp)) $(eval $(call _recipe,s,$(asflags))) -- 2.54.0 From 201c725dc7d2f90e8b636304767410df3f4043da Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 30 May 2025 02:19:13 +0200 Subject: [PATCH 27/35] cleanup d_main a little --- src/d_main.c | 247 ++++++++++++++++++++++++++------------------------- 1 file changed, 125 insertions(+), 122 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 728a1a760..d10ba05ab 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -197,12 +197,10 @@ static void D_PadMenuScrollInput(UINT8 input) // and pass it to the eventlist static void D_GamePadMenuScrollTicker(void) { + UINT8 i; static UINT8 menuInputDelayTimer = 0; - if (dedicated) - return; - - for (UINT8 i = 0; i < 4; i++) + for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) { if (dpadscrollstate[i]) { @@ -222,10 +220,10 @@ static void D_GamePadMenuScrollTicker(void) static void D_DeviceLEDTick(void) { UINT8 i; - static UINT16 color[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0}; - static UINT16 curcolor[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0}; + static UINT16 color[MAXSPLITSCREENPLAYERS] = {0}; + static UINT16 curcolor[MAXSPLITSCREENPLAYERS] = {0}; - if (dedicated || numcontrollers == 0) + if (numcontrollers == 0) { return; } @@ -252,7 +250,6 @@ static void D_DeviceLEDTick(void) void D_ProcessEvents(void) { event_t *ev; - boolean eaten; for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) @@ -291,8 +288,10 @@ void D_ProcessEvents(void) // Demo input: if (demo.playback) + { if (M_DemoResponder(ev)) continue; // demo ate the event + } // console input #ifdef HAVE_THREADS @@ -317,6 +316,88 @@ void D_ProcessEvents(void) // draw current display, possibly wiping it from the previous // +static void D_Renderview(void) +{ + UINT8 i; + + if (automapactive) + return; + + R_ApplyLevelInterpolators(rendertimefrac); + + for (i = 0; i <= splitscreen; i++) + { + const boolean issplitscreen = (i > 0); + + if (!P_MobjWasRemoved(players[displayplayers[i]].mo) || players[displayplayers[i]].playerstate == PST_DEAD) + { + viewssnum = i; + + if (!issplitscreen) // Initialize for P1 + { + viewwindowy = viewwindowx = 0; + topleft = screens[0]; + objectsdrawn = 0; + } + +#ifdef HWRENDER + if (rendermode == render_opengl) + { + HWR_RenderPlayerView(); + R_RestoreLevelInterpolators(); + return; + } +#endif + if (issplitscreen) // Splitscreen-specific + { + const INT32 len = viewheight*sizeof(ylookup[0]); + + switch (i) + { + case 1: + if (splitscreen > 1) + { + viewwindowx = viewwidth; + viewwindowy = 0; + } + else + { + viewwindowx = 0; + viewwindowy = viewheight; + } + M_Memcpy(ylookup, ylookup2, len); + break; + case 2: + viewwindowx = 0; + viewwindowy = viewheight; + M_Memcpy(ylookup, ylookup3, len); + break; + case 3: + viewwindowx = viewwidth; + viewwindowy = viewheight; + M_Memcpy(ylookup, ylookup4, len); + default: + break; + } + + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + } + + R_RenderPlayerView(&players[displayplayers[i]]); + + if (issplitscreen) + M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + } + + if (!issplitscreen) + R_ApplyViewMorph(); + + V_DoPostProcessor(i, postimgparam[i]); + } + + R_RestoreLevelInterpolators(); +} + // wipegamestate can be set to -1 to force a wipe on the next draw // added comment : there is a wipe eatch change of the gamestate gamestate_t wipegamestate = GS_LEVEL; @@ -327,7 +408,6 @@ static boolean D_Display(void) boolean forcerefresh = false; static boolean wipe = false; INT32 wipedefindex = 0; - UINT8 i; if (!dedicated) { @@ -366,6 +446,7 @@ static boolean D_Display(void) { // set for all later wipedefindex = gamestate; // wipe_xxx_toblack + if (gamestate == GS_TITLESCREEN && wipegamestate != GS_INTRO) wipedefindex = wipe_timeattack_toblack; else if (gamestate == GS_INTERMISSION) @@ -378,26 +459,28 @@ static boolean D_Display(void) if (!dedicated) { - // Fade to black first - if (gamestate != GS_LEVEL // fades to black on its own timing, always - && wipedefs[wipedefindex] != UINT8_MAX) + if (gamestate != GS_LEVEL) { - F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - F_WipeEndScreen(); - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); - ranwipe = true; - } + // Fade to black first + if (wipedefs[wipedefindex] != UINT8_MAX) // fades to black on its own timing, always + { + F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); + ranwipe = true; + } - if (gamestate != GS_LEVEL && rendermode != render_none) - { - V_SetPaletteLump("PLAYPAL"); // Reset the palette - R_ReInitColormaps(0, LUMPERROR); + if (rendermode != render_none) + { + V_SetPaletteLump("PLAYPAL"); // Reset the palette + R_ReInitColormaps(0, LUMPERROR); + } } F_WipeStartScreen(); } - else //dedicated servers + else // dedicated servers { F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); ranwipe = true; @@ -405,7 +488,7 @@ static boolean D_Display(void) } } - if (dedicated) //bail out after wipe logic + if (dedicated) // bail out after wipe logic return false; // do buffered drawing @@ -430,9 +513,6 @@ static boolean D_Display(void) HU_Drawer(); break; - case GS_TIMEATTACK: - break; - case GS_INTRO: F_IntroDrawer(); if (wipegamestate == (gamestate_t)-1) @@ -484,6 +564,7 @@ static boolean D_Display(void) HU_Erase(); HU_Drawer(); } + case GS_TIMEATTACK: case GS_DEDICATEDSERVER: case GS_NULL: break; @@ -492,89 +573,10 @@ static boolean D_Display(void) if (gamestate == GS_LEVEL) { // draw the view directly - if (cv_renderview.value && !automapactive) + if (cv_renderview.value) { PS_START_TIMING(ps_rendercalltime); - - R_ApplyLevelInterpolators(rendertimefrac); - - for (i = 0; i <= splitscreen; i++) - { - if (!P_MobjWasRemoved(players[displayplayers[i]].mo) || players[displayplayers[i]].playerstate == PST_DEAD) - { - viewssnum = i; - - if (i == 0) // Initialize for P1 - { - viewwindowy = 0; - viewwindowx = 0; - - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; - objectsdrawn = 0; - } - -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_RenderPlayerView(); - else -#endif - if (rendermode != render_none) - { - if (i > 0) // Splitscreen-specific - { - switch (i) - { - case 1: - if (splitscreen > 1) - { - viewwindowx = viewwidth; - viewwindowy = 0; - } - else - { - viewwindowx = 0; - viewwindowy = viewheight; - } - M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); - break; - case 2: - viewwindowx = 0; - viewwindowy = viewheight; - M_Memcpy(ylookup, ylookup3, viewheight*sizeof (ylookup[0])); - break; - case 3: - viewwindowx = viewwidth; - viewwindowy = viewheight; - M_Memcpy(ylookup, ylookup4, viewheight*sizeof (ylookup[0])); - default: - break; - } - - - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; - } - - R_RenderPlayerView(&players[displayplayers[i]]); - - if (i > 0) - M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); - } - } - } - - if (rendermode == render_soft) - { - if (!splitscreen) - R_ApplyViewMorph(); - - for (i = 0; i <= splitscreen; i++) - { - V_DoPostProcessor(i, postimgparam[i]); - } - } - - R_RestoreLevelInterpolators(); - + D_Renderview(); PS_STOP_TIMING(ps_rendercalltime); } @@ -584,6 +586,7 @@ static boolean D_Display(void) { VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); } + lastdraw = false; } @@ -606,13 +609,8 @@ static boolean D_Display(void) // draw pause pic if (paused && cv_showhud.value && !demo.playback) { - INT32 py; - patch_t *patch; - if (automapactive) - py = 4; - else - py = viewwindowy + 4; - patch = W_CachePatchName("M_PAUSE", PU_PATCH); + INT32 py = (automapactive) ? 4 : (viewwindowy + 4); + patch_t *patch = W_CachePatchName("M_PAUSE", PU_PATCH); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - patch->width)/2, py, V_SNAPTOTOP, patch); } @@ -754,7 +752,7 @@ void D_SRB2Loop(void) // Casting the return value of a function is bad practice (apparently) double budget = ((R_GetFramerateCap() == 0) ? 0.0 : round((1.0 / R_GetFramerateCap()) * I_GetPrecisePrecision())); - capbudget = (precise_t) budget; + capbudget = (precise_t)budget; boolean ranwipe = false; @@ -824,12 +822,15 @@ void D_SRB2Loop(void) doDisplay = true; } - if (menuactive) + if (!dedicated) { - D_GamePadMenuScrollTicker(); - } + if (menuactive) + { + D_GamePadMenuScrollTicker(); + } - D_DeviceLEDTick(); + D_DeviceLEDTick(); + } } if (interp) @@ -841,7 +842,9 @@ void D_SRB2Loop(void) ps_interp_frac.value.p = (precise_t)((FIXED_TO_FLOAT(g_time.timefrac)) * 1000.0f); ps_interp_lag.value.p = (precise_t)((deltasecs) * 1000.0f); - if (!(paused || P_AutoPause()) && deltatics < 1.0 && !hu_stopped) + const boolean lagging = ((deltatics >= 1.0) || hu_stopped); + + if (!(paused || P_AutoPause()) && !lagging) { rendertimefrac = g_time.timefrac; } @@ -850,7 +853,7 @@ void D_SRB2Loop(void) rendertimefrac = FRACUNIT; } - if ((deltatics < 1.0) && !hu_stopped) + if (!lagging) { rendertimefrac_unpaused = g_time.timefrac; } -- 2.54.0 From 7d68c0598c89f66d2774c9b29d8a5bdb5300a209 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 30 May 2025 02:54:34 +0200 Subject: [PATCH 28/35] Fix underflow in consistancy checking code https://git.srb2.org/Hanicef/SRB2Classic/-/commit/9f5686ef48956cd64ef92f737e59cbbaa27d8cf9 --- src/d_clisrv.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4e5a1cd9a..0135c76cd 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5388,7 +5388,7 @@ static void HandlePacketFromPlayer(SINT8 node) // Check player consistancy during the level if (gamestate == GS_LEVEL - && (realstart > gametic - TICQUEUE+1 && realstart <= gametic) + && (realstart <= gametic && realstart + TICQUEUE - 1 > gametic) && consistancy[realstart%TICQUEUE] != SHORT(netbuffer->u.clientpak.consistancy) && (!UseSaturnSynch(node) || (!resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime() && !SV_ResendingSavegameToAnyone()))) { @@ -5418,10 +5418,13 @@ static void HandlePacketFromPlayer(SINT8 node) } if (cv_blamecfail.value) + { CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"), netconsole+1, player_names[netconsole], consistancy[realstart%TICQUEUE], SHORT(netbuffer->u.clientpak.consistancy)); + } + DEBFILE(va("Restoring player %d (synch failure) [%update] %d!=%d\n", netconsole, realstart, consistancy[realstart%TICQUEUE], SHORT(netbuffer->u.clientpak.consistancy))); @@ -5693,7 +5696,7 @@ static void HandlePacketFromPlayer(SINT8 node) break; } - //Update client ping table from the server. + // Update client ping table from the server. if (client) { UINT8 i; @@ -6503,7 +6506,6 @@ static inline void PingUpdate(void) if (pingtimeout[i] > 0) pingtimeout[i]--; } - } //kick lagging players... unless everyone but the server's ping sucks. -- 2.54.0 From 6617382f54298869c7a557bf2c7c69e04412543d Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 30 May 2025 23:59:08 +0200 Subject: [PATCH 29/35] Revert "reset the palette earlier during levelload" This reverts commit 5e532a76cfba090a8150d72c7ec0cb018cde4c39. --- src/p_setup.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 47327e3ca..0459a03f5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2807,10 +2807,6 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate) CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer - // Reset the palette - if (rendermode != render_none) - V_SetPaletteLump("PLAYPAL"); - // Initialize sector node list. P_Initsecnode(); @@ -2879,7 +2875,10 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate) // Reset the palette now all fades have been done if (rendermode != render_none) - V_ReloadPalette(); // Set the level palette + { + //V_ResetPaletteCVars(); // dont carry over changed palettes + V_SetPaletteLump(GetPalette()); // Set the level palette + } // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." /*if (rendermode != render_none) -- 2.54.0 From 55c6ba6d12fb4222e6baf15cbc85ea8d7dd2b6d2 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 31 May 2025 15:57:03 +0200 Subject: [PATCH 30/35] fix awayview join crash player->awayviewmobj may not exist yet in some cases --- src/r_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index f16d138ee..15f17db9d 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1063,7 +1063,7 @@ static void R_SetupCommonFrame(player_t * player, sector_t * sector) static void R_SetupAimingFrame(player_t *player, camera_t *thiscam) { - if (player->awayviewtics) + if (player->awayviewtics && player->awayviewmobj) { newview->aim = player->awayviewaiming; newview->angle = player->awayviewmobj->angle; @@ -1169,7 +1169,7 @@ void R_SkyboxFrame(int s) { mapheader_t *mh = mapheaderinfo[gamemap-1]; - if (player->awayviewtics) + if (player->awayviewtics && player->awayviewmobj) { SETUPSKYVIEW(player->awayviewmobj, (player->awayviewmobj->z + 20*FRACUNIT)); } @@ -1226,7 +1226,7 @@ void R_SetupFrame(int s, boolean skybox) R_SetupAimingFrame(player, thiscam); - if (player->awayviewtics) // cut-away view stuff + if (player->awayviewtics && player->awayviewmobj) // cut-away view stuff { viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN I_Assert(viewmobj != NULL); @@ -1235,7 +1235,7 @@ void R_SetupFrame(int s, boolean skybox) newview->y = viewmobj->y; newview->z = viewmobj->z + 20*FRACUNIT; - if (!P_MobjWasRemoved(viewmobj) && viewmobj->subsector && viewmobj->subsector->sector) + if (viewmobj->subsector && viewmobj->subsector->sector) sector = viewmobj->subsector->sector; R_SetupCommonFrame(player, sector); @@ -1253,7 +1253,7 @@ void R_SetupFrame(int s, boolean skybox) R_SetupCommonFrame(player, sector); } - else // use the player's eyes view + else if (player->mo) // use the player's eyes view { viewmobj = player->mo; I_Assert(viewmobj != NULL); @@ -1262,7 +1262,7 @@ void R_SetupFrame(int s, boolean skybox) newview->y = viewmobj->y; newview->z = player->viewz; - if (!P_MobjWasRemoved(viewmobj) && viewmobj->subsector && viewmobj->subsector->sector) + if (viewmobj->subsector && viewmobj->subsector->sector) sector = viewmobj->subsector->sector; R_SetupCommonFrame(player, sector); -- 2.54.0 From 5c53a90eea949af6f5316b260e78d1e297e0d494 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 31 May 2025 16:20:58 +0200 Subject: [PATCH 31/35] hack: reset musiccredits when changing gamestate otherwise they may persist if theyve been currently displayed --- src/g_game.c | 5 +++++ src/s_sound.c | 5 +++++ src/s_sound.h | 1 + 3 files changed, 11 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index dd3823f8a..31eed2fd4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -8234,6 +8234,11 @@ boolean G_DemoTitleResponder(event_t *ev) void G_SetGamestate(gamestate_t newstate) { gamestate = newstate; + + //HACK: reset musiccredits whenever we change gamestate + // since we allow them to run everywhere now + S_ResetMusicCredit(); + #ifdef HAVE_DISCORDRPC DRPC_UpdatePresence(); #endif diff --git a/src/s_sound.c b/src/s_sound.c index cf75df56a..2f79e0540 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1436,6 +1436,11 @@ musicdef_t *S_FindMusicCredit(const char *musname) return NULL; } +void S_ResetMusicCredit(void) +{ + memset(&cursongcredit, 0, sizeof(cursongcredit)); +} + // // S_ShowSpecifiedMusicCredit // diff --git a/src/s_sound.h b/src/s_sound.h index 92e206e1b..eec99d802 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -206,6 +206,7 @@ void S_InitMTDefs(void); musicdef_t *S_FindMusicCredit(const char *musname); void S_ShowSpecifiedMusicCredit(const char *musname); void S_ShowMusicCredit(void); +void S_ResetMusicCredit(void); boolean S_PrepareSoundTest(void); -- 2.54.0 From 0e9a825f63d989309ef75a540531259d86ae942e Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 30 May 2025 20:52:38 +0200 Subject: [PATCH 32/35] some crap from ceepeepeecheck --- src/g_game.c | 51 ++++++++++++++++++++++-------------------- src/g_input.c | 2 +- src/hardware/hw_main.c | 5 ++++- src/k_kart.c | 5 +++-- src/r_data.c | 21 ++++++++++++----- 5 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 31eed2fd4..a872fc571 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5464,33 +5464,36 @@ void G_GhostTicker(void) break; } } - if (type == MT_GHOST) + if (type != -1) { - mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us - mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK); - mobj->sprite = states[mobjinfo[type].spawnstate].sprite; - mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<tics = -1; // nope. - mobj->color = g->mo->color; - if (g->mo->eflags & MFE_VERTICALFLIP) + if (type == MT_GHOST) { - mobj->flags2 |= MF2_OBJECTFLIP; - mobj->eflags |= MFE_VERTICALFLIP; + mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us + mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<mo->scale); - mobj->destscale = g->mo->scale; + else + { + mobj = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK); + mobj->sprite = states[mobjinfo[type].spawnstate].sprite; + mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<tics = -1; // nope. + mobj->color = g->mo->color; + if (g->mo->eflags & MFE_VERTICALFLIP) + { + mobj->flags2 |= MF2_OBJECTFLIP; + mobj->eflags |= MFE_VERTICALFLIP; + } + P_SetScale(mobj, g->mo->scale); + mobj->destscale = g->mo->scale; + } + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_UnsetThingPosition(mobj); + mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... + P_SetThingPosition(mobj); + mobj->fuse = 8; + P_SetTarget(&mobj->target, g->mo); } - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_UnsetThingPosition(mobj); - mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... - P_SetThingPosition(mobj); - mobj->fuse = 8; - P_SetTarget(&mobj->target, g->mo); } if (ziptic & EZT_HIT) { // Spawn hit poofs for killing things! @@ -8143,7 +8146,7 @@ void G_SaveDemo(void) size_t i, strindex = 0; boolean dash = true; - for (i = 0; i < 127 && demo.titlename[i]; i++) + for (i = 0; demo.titlename[i] && i < 127; i++) { if ((demo.titlename[i] >= 'a' && demo.titlename[i] <= 'z') || (demo.titlename[i] >= '0' && demo.titlename[i] <= '9')) diff --git a/src/g_input.c b/src/g_input.c index 43b7f48ca..8d5b38bf2 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -1030,7 +1030,7 @@ INT32 G_KeyStringtoNum(const char *keystr) if (!keystr[0]) return 0; - if (!keystr[0] || (!keystr[1] && keystr[0] > ' ' && keystr[0] <= 'z')) + if (!keystr[1] && keystr[0] > ' ' && keystr[0] <= 'z') return keystr[0]; if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9') diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e25364bee..43cb25aed 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4464,7 +4464,10 @@ static void HWR_DrawModels(void) continue; } - if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + if (!spr->mobj) + continue; + + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { md2_t *md2; diff --git a/src/k_kart.c b/src/k_kart.c index c63433fb4..5589bdb6e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -10525,11 +10525,12 @@ static void K_drawKartWanted(void) { INT32 x = basex+(splitscreen > 1 ? 13 : 8), y = basey+(splitscreen > 1 ? 16 : 21); fixed_t scale = FRACUNIT/2; - player_t *p = &players[battlewanted[i]]; if (battlewanted[i] == -1) break; + player_t *p = &players[battlewanted[i]]; + if (numwanted == 1) scale = FRACUNIT; else @@ -10540,7 +10541,7 @@ static void K_drawKartWanted(void) y += 16; } - if (players[battlewanted[i]].skincolor) + if (p->skincolor) { colormap = R_GetTranslationColormap(TC_RAINBOW, p->skincolor, GTC_CACHE); V_DrawFixedPatch(x<8) + + if (texturesTokenLength > 8) { I_Error("Error parsing TEXTURES lump: Patch name \"%s\" exceeds 8 characters",texturesToken); } @@ -713,10 +716,12 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) // Comma 1 Z_Free(texturesToken); texturesToken = M_GetToken(NULL); + if (texturesToken == NULL) { I_Error("Error parsing TEXTURES lump: Unexpected end of file where comma after \"%s\"'s patch name should be",patchName); } + if (strcmp(texturesToken,",")!=0) { I_Error("Error parsing TEXTURES lump: Expected \",\" after %s's patch name, got \"%s\"",patchName,texturesToken); @@ -725,14 +730,17 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) // XPos Z_Free(texturesToken); texturesToken = M_GetToken(NULL); + if (texturesToken == NULL) { I_Error("Error parsing TEXTURES lump: Unexpected end of file where patch \"%s\"'s x coordinate should be",patchName); } + endPos = NULL; #ifndef AVOID_ERRNO errno = 0; #endif + patchXPos = strtol(texturesToken,&endPos,10); (void)patchXPos; //unused for now if (endPos == texturesToken // Empty string @@ -748,10 +756,12 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) // Comma 2 Z_Free(texturesToken); texturesToken = M_GetToken(NULL); + if (texturesToken == NULL) { I_Error("Error parsing TEXTURES lump: Unexpected end of file where comma after patch \"%s\"'s x coordinate should be",patchName); } + if (strcmp(texturesToken,",")!=0) { I_Error("Error parsing TEXTURES lump: Expected \",\" after patch \"%s\"'s x coordinate, got \"%s\"",patchName,texturesToken); @@ -760,6 +770,7 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) // YPos Z_Free(texturesToken); texturesToken = M_GetToken(NULL); + if (texturesToken == NULL) { I_Error("Error parsing TEXTURES lump: Unexpected end of file where patch \"%s\"'s y coordinate should be",patchName); @@ -1131,9 +1142,9 @@ static void R_InitExtraColormaps(void) lumpnum_t R_GetFlatNumForName(const char *name) { INT32 i; - lumpnum_t lump; - lumpnum_t start; - lumpnum_t end; + lumpnum_t lump = LUMPERROR; + lumpnum_t start = LUMPERROR; + lumpnum_t end = LUMPERROR; // Scan wad files backwards so patched flats take preference. for (i = numwadfiles - 1; i >= 0; i--) @@ -1608,7 +1619,7 @@ const char *R_ColormapNameForNum(INT32 num) if (num == -1) return "NONE"; - if (num < 0 || num > MAXCOLORMAPS) + if (num < 0 || num >= MAXCOLORMAPS) I_Error("R_ColormapNameForNum: num %d is invalid!\n", num); if (foundcolormaps[num] == LUMPERROR) -- 2.54.0 From f1f07822569149c6d94cd68c8c5c8b5f7ec2343d Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 30 May 2025 20:56:43 +0200 Subject: [PATCH 33/35] fix memoryleak in pk3 verify functions --- src/w_wad.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 0c7fdbaf0..305e4b3bd 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -2039,8 +2039,7 @@ static lumpchecklist_t folderblacklist[] = {NULL, 0}, }; -static int -W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) +static int W_VerifyPK3(FILE *fp, lumpchecklist_t *checklist, boolean status) { int verified = true; @@ -2082,7 +2081,10 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) char *cdir = (char*)(malloc(LONG(zend.cdirsize))); if (fread(cdir, 1, LONG(zend.cdirsize), fp) < (UINT32)(LONG(zend.cdirsize))) + { + free(cdir); return true; + } size_t offset = 0; @@ -2094,7 +2096,10 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) char* dotpos; if (memcmp(zentry->signature, pat_central, 4) != 0) + { + free(cdir); return true; + } if (verified == true) { @@ -2132,10 +2137,16 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) sizeof *zentry + SHORT(zentry->namelen) + SHORT(zentry->xtralen) + SHORT(zentry->commlen); if (fseek(fp, LONG(zentry->offset), SEEK_SET) != 0) + { + free(cdir); return true; + } if (fread(&zlentry, 1, sizeof(zlentry_t), fp) < sizeof (zlentry_t)) + { + free(cdir); return true; + } data_size += sizeof zlentry + SHORT(zlentry.namelen) + SHORT(zlentry.xtralen) + LONG(zlentry.compsize); @@ -2186,7 +2197,9 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist, goodfile = W_VerifyWAD(handle, checklist, status); } } + fclose(handle); + return goodfile; } @@ -2341,7 +2354,10 @@ static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist) char *cdir = (char*)(malloc(LONG(zend.cdirsize))); if (fread(cdir, 1, LONG(zend.cdirsize), fp) < (UINT32)(LONG(zend.cdirsize))) + { + free(cdir); return true; + } size_t offset = 0; @@ -2353,7 +2369,10 @@ static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist) char* dotpos; if (memcmp(zentry->signature, pat_central, 4) != 0) + { + free(cdir); return false; + } fullname = (char*)(malloc(SHORT(zentry->namelen) + 1)); strlcpy(fullname, (char*)(zentry + 1), SHORT(zentry->namelen) + 1); @@ -2373,11 +2392,19 @@ static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist) strncpy(lumpname, trimname, min(8, dotpos - trimname)); if (W_NameStartsWith(lumpname, checklist)) + { + free(fullname); + free(cdir); return true; + } } if (W_NameStartsWith(fullname, checklist)) + { + free(fullname); + free(cdir); return true; + } free(fullname); @@ -2387,10 +2414,16 @@ static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist) sizeof *zentry + SHORT(zentry->namelen) + SHORT(zentry->xtralen) + SHORT(zentry->commlen); if (fseek(fp, LONG(zentry->offset), SEEK_SET) != 0) + { + free(cdir); return false; + } if (fread(&zlentry, 1, sizeof(zlentry_t), fp) < sizeof (zlentry_t)) + { + free(cdir); return false; + } data_size += sizeof zlentry + SHORT(zlentry.namelen) + SHORT(zlentry.xtralen) + LONG(zlentry.compsize); -- 2.54.0 From 83d20a72ab3772f7a724c3f5b39d0e0eb2320756 Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 2 Jun 2025 20:05:09 +0200 Subject: [PATCH 34/35] delet this since its mostly wrong anyways --- src/Makefile | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Makefile b/src/Makefile index cac95d35b..56edb6db9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -116,8 +116,6 @@ # SDL_CONFIG= - sdl-config command. # SDL_CFLAGS=, SDL_LDFLAGS= -NOBLUAJIT=1 - clean_targets=cleandep clean distclean info .PHONY : $(clean_targets) all @@ -185,13 +183,8 @@ objdir:=$(makedir)/objs sources+=\ $(call List,Sourcefile) -ifdef NOBLUAJIT sources+=\ $(call List,blua/Sourcefile) -else -include bluajit/Makefile.cfg -include bluajit/Makefile.cfg2 -endif depends:=$(basename $(filter %.c %.cpp %.s,$(sources))) objects:=$(basename $(filter %.c %.cpp %.s %.nas,$(sources))) @@ -426,13 +419,6 @@ clean : distclean : $(call _rm,../bin ../objs ../dep ../make comptime.h) -ifndef NOBLUAJIT - $(call _rm,$(objdir)/buildvm* $(objdir)/minilua* $(objdir)/lj_vm*) - -cleanjit: - $(call _rm,$(objdir)/buildvm* $(objdir)/minilua* $(objdir)/lj_vm* $(ALL_HDRGEN) $(LJVMCORE_O) $(ALL_GEN)) -endif - info: ifdef WINDOWSHELL @REM -- 2.54.0 From be3e5a964d4fe198be2f5040ced511626ac74539 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 12 Jun 2025 23:33:22 +0200 Subject: [PATCH 35/35] pass -flto to linkerflags too lel forgor somehow this still worked anyways --- src/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile b/src/Makefile index 56edb6db9..9acfd6d3c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -246,6 +246,7 @@ opts+=-O3 ifdef USELTO # compile with LTO opts+=-flto=auto +libs+=-flto=auto endif endif -- 2.54.0