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..9acfd6d3c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,783 +1,430 @@ - -# 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... +clean_targets=cleandep clean distclean info - 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 +.PHONY : $(clean_targets) all - SDL=1 - WINDOWSHELL=1 - NOOBJDUMP=1 +goals:=$(or $(MAKECMDGOALS),all) +cleanonly:=$(filter $(clean_targets),$(goals)) +destructive:=$(filter-out info,$(cleanonly)) -else # if you on the *nix - system:=$(shell uname -s) - - 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 +CXX:=$(PREFIX)-g++ +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) + +sources+=\ + $(call List,blua/Sourcefile) + +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_CONFIG?=libpng-config +bin:=../bin endif -ifdef PNG_STATIC -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --static --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --static --ldflags) -else -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --ldflags) -endif -endif +# default EXENAME (usually set by platform) +EXENAME?=srb2kart +DBGNAME?=$(EXENAME).debug -ifdef LINUX -PNG_CFLAGS+=-D_LARGEFILE64_SOURCE -endif +exe:=$(bin)/$(EXENAME) +dbg:=$(bin)/$(DBGNAME) -LIBS+=$(PNG_LDFLAGS) -CFLAGS+=$(PNG_CFLAGS) +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 -# 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)/ -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 +# dependency recipe template (C++) +# 1: source file suffix +# 2: extra flags to gcc +define _recipecxx = +$(depdir)/%.d : %.$(1) | $$$$(@D)/ ifndef WINDOWSHELL - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt +ifdef Echo_name + @printf '%-20.20s\r' $$< endif +endif + $(.)$(cxx) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$< +endef -$(OBJDIR): - -$(MKDIR) $(OBJDIR) +$(eval $(call _recipe,c)) +$(eval $(call _recipe,cpp)) +$(eval $(call _recipe,s,$(asflags))) -ifndef SDL -ifdef NOHW -dll : +# 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) + +info: +ifdef WINDOWSHELL + @REM 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..fef452467 --- /dev/null +++ b/src/Makefile.d/dedicated.mk @@ -0,0 +1,21 @@ +makedir:=$(makedir)/Dedicated + +sources+=$(call List,dedicated/Sourcefile) + +opts+=-DDEDICATED + +libs+=-lpthread + +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..a3cdbbd4b --- /dev/null +++ b/src/Makefile.d/versions.mk @@ -0,0 +1,178 @@ +# +# 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 + +ifdef GCC150 + opts+=-std=gnu17 +endif +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..4946c4ca2 --- /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+=-Wl,--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..227e6c95a --- /dev/null +++ b/src/Sourcefile @@ -0,0 +1,96 @@ +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 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/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..6ab748f86 --- /dev/null +++ b/src/dedicated/i_system.c @@ -0,0 +1,2223 @@ +// 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 + +#include + +// 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 + // 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(); + 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/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/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; 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