Compare commits

..
Author SHA1 Message Date
Alug 3b07022379 remove spritecliphack shader and readd fickle fix
the shader aint working out that well so just do this for now
2024-06-22 20:43:27 +02:00
Alug a4fce0b3b1 add shader for shadows to also fix sprite shadows in pal render 2024-06-03 16:19:41 +02:00
Alug 79ad1f8d51 readd sprite shadows and give dropshadows their own cvar 2024-06-03 15:46:30 +02:00
Alug 73aef11554 make shadow hack less noticable lul 2024-06-03 15:24:59 +02:00
Alug 318916abc9 Merge branch 'Saturn-Next' into nomobjshadows 2024-06-03 15:24:54 +02:00
Alug 164a9d604a conflict moment 2024-06-02 22:15:58 +02:00
Alug 7696b115ae add maxinterpdist to shadows 2024-06-02 22:15:28 +02:00
Alug b8ecaf336c fix ogl shadows for the 500th time 2024-06-02 22:15:25 +02:00
Alug 1ea8ebf84c o 2024-06-02 22:15:23 +02:00
Alug 9f70fe5373 fix ogl whiteshadows 2024-06-02 22:15:20 +02:00
Alug 9695ede7c2 reenable shadow skewing in software 2024-06-02 22:15:17 +02:00
Alug a5cd72d5db smth smth shader 2024-06-02 22:15:14 +02:00
Alug f87e282981 readd shadowscale since some things need manual scale 2024-06-02 22:15:11 +02:00
Alug 4b15972543 make software shadows more opague 2024-06-02 22:15:09 +02:00
Alug d5753bb15a smol fix and dont colormap software shadows either 2024-06-02 22:15:06 +02:00
Alug a92e5b3f7b dont colourmap shadows
todo software renderer ugh
2024-06-02 22:14:56 +02:00
Alug 72d2357560 use shader to prevent sprite floor clipping
from durr lul
2024-06-02 22:14:53 +02:00
Alug d306b560b1 dont rotate shadows with sprite rotation off
theres prob a better way to get an interpolated floorz but this works
also adds a small offset to not let stuff clip into the ground
2024-06-02 22:14:42 +02:00
Alug 4d331d9c9f change shadowscale a little 2024-06-02 22:13:47 +02:00
indev 932f6d83f7 Allow all mobjs to have shadow 2024-06-02 22:13:45 +02:00
Alug d57783aa3a port neat render based shadows
what an absolute arsepain
shearing in software is disabled cause it is inverted for whatever reason
also if someone ever wants to reeimplement lua spawnshadows idk go ahead kek
2024-06-02 22:13:41 +02:00
Alug 1d79854d3b Merge branch 'Saturn-Next' into nomobjshadows 2024-06-02 22:13:30 +02:00
396 changed files with 67823 additions and 48535 deletions

No files matched your search

+7 -8
View File
@@ -13,17 +13,16 @@ Win32_LIB_ASM_Release
*.dgb
*.debug
*.debug.txt
/bin/VC10/
/objs/VC10/
*.user
*.db
*.opendb
/.vs
/debian
/assets/debian
/make
/bin
/build
/build/*
/CMakeUserPresets.json
/out
/objs/VC10
*.kate-swp
compile.sh
*.gz
.vscode/
out
build
-346
View File
@@ -1,346 +0,0 @@
#!/bin/bash
set -e # Enable auto-exit for debugging :))
# Make Linux AppImage program data
# https://docs.appimage.org/reference/appdir.html
# PWD: {repo_root}/build
# See deployer.sh for usage
# Terminal stuff
RESET="$(tput sgr0)" #"\e[0m" # Resets terminal colors
# Colors for various information types
FAILURE="$(tput setaf 1)" #"\e[91m"
SUCCESS="$(tput setaf 2)" #"\e[92m"
NOTICE="$(tput setaf 3)" #"\e[93m"
VERBOSE="$(tput setaf 4)" #"\e[94m"
verbosity=0 # By default don't print anything unless it's *ultra* important.
quiet=0 # Also don't print anything if they supplied the quiet argument
# URL from which to download appimagetool if there isn't one available in your $PATH
# at time of writing only aarch64, armhf, i686, and x86_64 versions are available via this method
# in those cases, and honestly even outside of those cases, it's better to just put a working one in your $PATH yourself..
url="https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$(uname -m).AppImage"
# A whitelist of libraries to include into SRB2's AppImage if SRB2 is dynamically linked.
# please don't add a newline at the end of this or i will cry :(
libraryWhitelist="
libbacktrace
libnsl
libSDL2
libSDL2_mixer
libgme
libopenmpt
libpng
libfluidsynth
libpulse
libmodplug
libvorbisfile
libopusfile
libFLAC
libmad
libmpg123
libvorbis
libpulsecommon
libsndfile
libsndio
libogg
libvorbisenc
libjson
libreadline
libwrap
libtinfo
libtirpc
libpng16"
# these kinda look like macros don't they
function print { (( "$quiet" == 0 )) && echo "$@" || :; } # echo if not quiet
function coloredText { printf "$1"; print "${@:2}"; printf "$RESET"; } # use print to inherit quiet
function success { coloredText "$SUCCESS" "$@"; } # use coloredText to inherit quiet
function important { coloredText "$NOTICE" "$@"; } # use coloredText to inherit quiet
function verboseOnly { (( "$verbosity" >= $1 )) && (coloredText "$VERBOSE" "${@:2}") || :; } # use coloredText to inherit quiet
# Parses an argument with a single dash
function parseSingleDashArg() {
while read -n 1 char; do
if [[ "$char" == '-' || "$char" == '' ]]; then
:
elif [[ "$char" == 'h' ]]; then
helppassed=1
elif [[ "$char" == 'q' ]]; then
quiet=1
elif [[ "$char" == 'v' ]]; then
verbosity="$((verbosity + 1))"
elif [[ "$char" == 'd' ]]; then
dry=1
elif [[ "$char" == 's' ]]; then
small=1
else
echo "$0: invalid option -- '$1'"
echo "Try '$0 --help' for more information."
return 1
fi
done <<<"$1"
}
# Simple help argument checker.
currentarg=1; # Which argument is --help...
# For $arg in the argument array...
for arg in "$@"; do
# Is it a help argument?
if [[ "$arg" == "--help" ]]; then
helppassed=1; # Help is passed, set $helppassed!
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}" # Remove argument from list
elif [[ "$arg" == "--quiet" ]]; then
quiet=1
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
elif [[ "$arg" == "--verbose" ]]; then
verbosity="$((verbosity + 1))" # Increase verbosity!
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
elif [[ "$arg" == "--dry" ]]; then
dry=1; # Show parameters instead of using them.
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
elif [[ "$arg" == "--small" ]]; then
small=1; # Don't copy assets to save on bandwidth.
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
elif [[ ! "$arg" == *'--'* && "$arg" == *'-'* ]]; then
parseSingleDashArg "$arg"
if [[ "$?" == 0 ]]; then
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}" # Remove argument from list
fi
elif [[ $arg == *'--'* ]]; then
print "$0: invalid option -- '$1'"
print "Try '$0 --help' for more information."
return 1
else
currentarg="$((currentarg+1))" # Increment current argument number otherwise...
fi
done
important "SRB2Kart AppImage Packager v1.0 modified for kart by NepDisk."
important "Orignal for SRB2 my mazmazz and Golden."
# Get root directory from the full path of this script.
__ROOT_DIR="$3"
if [[ -z "$3" ]]; then
# finds out where this script is and goes to that directory and goes up one for the root
scriptdir="$(dirname "${BASH_SOURCE[0]}")"
scriptbase="$(basename "${BASH_SOURCE[0]}")"
__ROOT_DIR="$(cd "$scriptdir" && pwd -P)"
fi
# If it starts with '.', put the current working directory behind it so things work.
if [[ "$__ROOT_DIR" == '.' || "$__ROOT_DIR" == '..' ]]; then
__ROOT_DIR="$PWD/$__ROOT_DIR"
fi
# Set up defaults
__PROGRAM_NAME="${PROGRAM_NAME:-"SRB2Kart Saturn"}"
__PROGRAM_DESCRIPTION="${PROGRAM_DESCRIPTION:-"Modded version of SRB2kart with more features."}"
__PROGRAM_FILENAME="${PROGRAM_FILENAME:-"lsdl2srb2kart"}"
__PROGRAM_ASSETS="${PROGRAM_ASSETS:-"$__ROOT_DIR/assets/installer"}"
__BUILD_DIR="${1:-"$__ROOT_DIR/bin"}"
__OUTPUT_FILENAME="${2:-"$__PROGRAM_FILENAME.AppImage"}"
__APPIMAGETOOL="${4:-"appimagetool"}"
if (! command -v "$__APPIMAGETOOL" &> /dev/null); then
__APPIMAGETOOL=
fi
# Stuff that prints and exits.
# Prints setup text using method given by arguments.
# Example: printSetup "print" # print "Setup for AppImage...
function printSetup {
$@ "Setup for AppImage in BUILD_DIR: '$__BUILD_DIR'..."
$@ "With the OUTPUT_FILENAME: '$__OUTPUT_FILENAME'"
$@ "And SRB2 Repository Root ROOT_DIR: '$__ROOT_DIR'"
$@ "Using APPIMAGETOOL: '$([ -z "$__APPIMAGETOOL" ] && echo '(download)' || echo $__APPIMAGETOOL)'"
$@ ""
$@ "This should be run from a Makefile or from the directory of the build. If it is not, then change to that directory or specify that directory as an argument."
$@ "If ROOT_DIR isn't SRB2's repository root, specify that as an argument too."
$@ "Make must have built the program before you run this script."
$@ ""
$@ "Make sure these Environment Variables are correct."
$@ "If not, then enter: export PROGRAM_VARIABLE=value"
$@ "PROGRAM_NAME: $__PROGRAM_NAME"
$@ "PROGRAM_DESCRIPTION: $__PROGRAM_DESCRIPTION"
$@ "PROGRAM_FILENAME: $__PROGRAM_FILENAME"
$@ "PROGRAM_ASSETS: $__PROGRAM_ASSETS"
}
if [[ "$helppassed" ]]; then
print "Usage: $(basename "$0") [OPTION]... [BUILD_DIR] [OUTPUT_NAME] [ROOT_DIR] [APPIMAGETOOL]"
print "Packages a SRB2 binary into an AppImage."
print "OPTIONs may be included anywhere within the arguments."
print ""
print "Arguments:"
print " -h, --help display this help and exit."
print " -q, --quiet don't display any text."
print " -v, --verbose make commands more verbose, will always print."
print " -s, --small don't copy SRB2 assets to save on bandwidth."
print " parameters regardless of --dry."
print " -d, --dry print parameters and exit."
print ""
if (( "$verbosity" > 0 )) || [[ "$dry" ]]; then
printSetup "print"
else
print "This should be run from a Makefile or from the directory of the build."
print "Make must have built the program before you run this script."
fi
exit;
fi
if (( "$verbosity" > 0 )) || [[ "$dry" ]]; then
printSetup "verboseOnly" "0"
verboseOnly 0 ""
if [[ "$dry" ]]; then
set -n # Enable debug mode and verbose for dry run.
fi
fi
# End stuff that prints and exits.
if (( "$verbosity" >= 4 )); then
set -v # Really verbose? Print *everything*!
fi
# Define AppDir structure
mkdir -p "$__BUILD_DIR/AppDir/usr/bin"
mkdir -p "$__BUILD_DIR/AppDir/lib"
mkdir -p "$__BUILD_DIR/AppDir/usr/share/applications"
mkdir -p "$__BUILD_DIR/AppDir/usr/share/icons/hicolor/256x256/apps"
# Copy program data
if [[ ! $small ]]; then
verboseOnly 1 "Packaging program assets..."
cp -r "$__PROGRAM_ASSETS"/* "$__BUILD_DIR/AppDir/usr/bin/"
cp -r "$__BUILD_DIR/$__PROGRAM_FILENAME" "$__BUILD_DIR/AppDir/usr/bin"
else
verboseOnly 1 "Skipping program asset packing, --small or -s passed..."
fi
verboseOnly 1 "Packaging SRB2..."
verboseOnly 1 "Assuming executable name $__PROGRAM_FILENAME"
cp -r "$__BUILD_DIR/$__PROGRAM_FILENAME" "$__BUILD_DIR/AppDir/usr/bin"
# Copy required dependencies, but only if the program is dynamically linked.
verboseOnly 1 "Testing if this build is dynamically linked..."
set +e # Disable auto-exit for ldd.
srb2Libraries="$(ldd "$__BUILD_DIR/$__PROGRAM_FILENAME")"
exitcode="$?"
set -e # Enable it again!
if (( $exitcode == 0 )); then
verboseOnly 1 "This build *is* dynamically linked! Packaging dependencies."
# read the dynamic libraries of srb2, trim off beginning whitespace, and get the third field seperated by spaces
# this gives us a newline-seperated list of libraries with their full paths.
srb2Libraries="$(echo "$srb2Libraries" | cut -f 2 | cut -d ' ' -f 3)"
# remove any extraneous newlines around the string
libraryWhitelist="$(echo $libraryWhitelist | head -c -1 | tr ' ' '\n')"
# replace e.g. 'abc' with '(/abc\b)', and replace newlines with '|'.
# this converts it into a grep regular expression to check for any whitelisted library names.
libraryWhitelist="$(printf "%s" "$libraryWhitelist" | sed 's|.*|(/\0\\b)|' | tr '\n' '|')"
# grab only the entries that match the regex
__LDD_LIST="$(printf "%s" "$srb2Libraries" | grep -E "$libraryWhitelist")"
# use echo to convert the newline-seperated list into an argument list
__LDD_LIST="$(echo $__LDD_LIST)"
# read into an array because i can't be bothered iterating the lines of a string today
# there's so many other things in this file that'd need to be adjusted to be POSIX-compliant anyway
IFS=' ' read -r -a paths <<< "$__LDD_LIST"
for path in "${paths[@]}"; do
if [ -f "$path" ]; then
verboseOnly 2 "Packaging dependency $(basename "$path")..."
cp "$path" $__BUILD_DIR/AppDir/lib/
else
verboseOnly 2 "Dependency $(basename "$path") not found"
fi
done
else
verboseOnly 1 "This SRB2 build is statically linked, skipping dependency packing."
fi
cd "$__BUILD_DIR/AppDir"
# Copy icons
verboseOnly 1 "Packaging resources..."
cp "$__ROOT_DIR/srb2.png" "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png"
ln -sf "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png" "./.DirIcon"
ln -sf "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png" "./$__PROGRAM_FILENAME.png"
# Make desktop descriptor
cat > "./usr/share/applications/$__PROGRAM_FILENAME.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=$__PROGRAM_NAME
Comment=$__PROGRAM_DESCRIPTION
Icon=$__PROGRAM_FILENAME
Exec=AppRun %F
Categories=Game;
EOF
ln -sf "./usr/share/applications/$__PROGRAM_FILENAME.desktop" "./$__PROGRAM_FILENAME.desktop"
# Make entry point
echo -e '#!'"$(dirname "$SHELL")/sh" > ./AppRun
echo -e 'HERE="$(dirname "$(readlink -f "${0}")")"' >> ./AppRun
echo -e 'SRB2WADDIR=$HERE/usr/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HERE/lib exec $HERE/usr/bin/'"$__PROGRAM_FILENAME"' "$@"' >> ./AppRun
chmod +x ./AppRun
cd .. # now in $__BUILD_DIR
# Package AppImage
if [ -z "$__APPIMAGETOOL" ]; then
verboseOnly 1 "No valid appimagetool path given or detected, downloading appimagetool..."
# Print notice for internet connection.
important "If the command hangs here, check your internet connection, or download appimagetool and add it to your \$PATH and try compiling again."
(( "$verbosity" >= 3 )) && wget "$url" || wget -q "$url"
APPIMAGETOOL="./$(basename "$url")"
chmod a+x "$APPIMAGETOOL"
else
verboseOnly 1 "appimagetool path given or detected, no download required."
APPIMAGETOOL="$__APPIMAGETOOL"
fi
verboseOnly 1 "Packing AppImage $__OUTPUT_FILENAME"
if (( verbosity >= 3 )); then
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME"
elif (( verbosity >= 2 )); then
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME" >/dev/null
else
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME" >/dev/null 2>&1
fi
success "AppImage ready!"
verboseOnly 1 "Cleaning up files..."
rm -r ./AppDir
if [ -z "$__APPIMAGETOOL" ]; then
rm "$APPIMAGETOOL"
fi
cd "$__ROOT_DIR" # snap back to reality
+1 -1
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine.
project(SRB2
-42
View File
@@ -28,10 +28,6 @@ exist.
Returns the values of the given HUD item's `xoffset`/`yoffset` cvars.
Available for any HUD item with offset cvars.
## patch = v.cachePatchRotated(name, rollangle)
Like v.cachePatch, it caches a new patch with the corresponding name. Unlike v.cachePatch, however,
a rollangle can be supplied to the function so that it returns a rotated patch instead.
## x, y, flags = v.getDrawInfo(item)
Returns the X, Y and flags where the given HUD item will be drawn for the current displayplayer.
@@ -134,41 +130,3 @@ if rawget(_G, "S_StopSoundByNum") ~= nil then
... -- Can use it
end
```
## addHook("ServerJoin", function())
ServerJoin hook called when client joins server (starting a listen server also calls it for host).
Generally it was made to make loading custom config files less hacky, but can be used for anything else too.
## player.viewrollangle field
Returns player's current view roll angle for the Screen Tilting feature, useful for HUD elements.
## G_SetPlayerGamepadIndicatorColor(player, skincolor)
Set a custom color for Supported Gamepads with RGB LED functionality.
To be used with Displayplayers.
Only takes Skincolors.
Best to be used in a Loop to ensure the color wont get overwritten by the game.
## G_PlayerDeviceRumble(player, low_strength, high_strength, -optional- duration)
Add Gamepad Rumble support for things.
To be used with Displayplayers.
Duration is in milliseconds and is optional to set, default value is 84ms.
## P_CheckSightFast(mo1, mo2)
Exactly same as P_CheckSight but uses cheaper algorithm, useful for things like nametags. Doesn't work exactly
like P_CheckSight so don't use it for anything gameplay-related.
# Other changes
## P_PlayRinglossSound(source, damager)
Add optional `damager` argument (should be `mobj_t`), which causes hurt sound also play for damager
if `karthitemdialog` option is enabled
## K_PlayHitEmSound(mobj, victim)
Add optional `victim` argument (should be a player's `mobj_t`), which causes "hit em" sound to be
delayed and played for victim too if `karthitemdialog` option is enabled
-8
View File
@@ -1,8 +0,0 @@
ifdef SILENT
MAKEFLAGS+=--no-print-directory
endif
all :
% ::
@$(MAKE) -C src $(MAKECMDGOALS)
+1 -1
View File
@@ -76,7 +76,7 @@ Crashlogs now contain alot more informations. and even more if your build has de
Also allows 64bit Windows builds to produce Crashlogs!
## MISC
- Bird's Camera Tilting feature is no longer turned on by default
- Bird's Camara Tilting feature is no longer turned on by default
- Bird's warning on the title screen has been removed
## Bugs
+5
View File
@@ -1726,6 +1726,11 @@ HW3SOUND for 3D hardware sound support
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/r_draw.h" />
<Unit filename="src/r_draw16.c">
<Option compilerVar="CC" />
<Option compile="0" />
<Option link="0" />
</Unit>
<Unit filename="src/r_draw8.c">
<Option compilerVar="CC" />
<Option compile="0" />
+10
View File
@@ -773,6 +773,16 @@ Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit79]
FileName=src\r_draw16.c
Folder=R_Rend
Compile=0
CompileCpp=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit80]
FileName=src\r_draw8.c
Folder=R_Rend
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+1
View File
@@ -0,0 +1 @@
/lsdlsrb2
+3
View File
@@ -0,0 +1,3 @@
/lsdlsrb2
/pnd
/*.mo
+1
View File
@@ -0,0 +1 @@
/lsdlsrb2
+1
View File
@@ -0,0 +1 @@
/lsdlsrb2
+4
View File
@@ -0,0 +1,4 @@
*.exe
*.mo
r_opengl.dll
*.bat
+4
View File
@@ -0,0 +1,4 @@
*.exe
*.mo
r_opengl.dll
*.bat
+3
View File
@@ -0,0 +1,3 @@
/srb2sdl.exe
/srb2win.exe
/r_opengl.dll
+4
View File
@@ -0,0 +1,4 @@
*.exe
*.mo
r_opengl.dll
*.bat
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+32 -32
View File
@@ -1,32 +1,32 @@
@echo off
set BRA=Unknown
set REV=illegal
copy nul: /b +%1\comptime.c tmp.$$$ > nul
move tmp.$$$ %1\comptime.c > nul
if exist .git goto gitrev
if exist ..\.git goto gitrev
if exist .svn goto svnrev
goto filwri
:gitrev
set GIT=%2
if "%GIT%"=="" set GIT=git
for /f "usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s
for /f "usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s
set REV=%REV:~0,8%
goto filwri
:svnrev
set BRA=Subversion
for /f "usebackq" %%s in (`svnversion .`) do @set REV=%%s
set REV=r%REV%
goto filwri
:filwri
echo // Do not edit! This file was autogenerated > %1\comptime.h
echo // by the %0 batch file >> %1\comptime.h
echo // >> %1\comptime.h
echo const char* compbranch = "%BRA%"; >> %1\comptime.h
echo const char* comprevision = "%REV%"; >> %1\comptime.h
@echo off
set BRA=Unknown
set REV=illegal
copy nul: /b +%1\comptime.c tmp.$$$ > nul
move tmp.$$$ %1\comptime.c > nul
if exist .git goto gitrev
if exist ..\.git goto gitrev
if exist .svn goto svnrev
goto filwri
:gitrev
set GIT=%2
if "%GIT%"=="" set GIT=git
for /f "usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s
for /f "usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s
set REV=%REV:~0,8%
goto filwri
:svnrev
set BRA=Subversion
for /f "usebackq" %%s in (`svnversion .`) do @set REV=%%s
set REV=r%REV%
goto filwri
:filwri
echo // Do not edit! This file was autogenerated > %1\comptime.h
echo // by the %0 batch file >> %1\comptime.h
echo // >> %1\comptime.h
echo const char* compbranch = "%BRA%"; >> %1\comptime.h
echo const char* comprevision = "%REV%"; >> %1\comptime.h
+1 -1
View File
@@ -17,7 +17,7 @@ EOF
versiongit() {
gitbranch="$(git rev-parse --abbrev-ref HEAD)"
gitversion="$(git show --pretty=format:'%h %s' -s HEAD | sed 's/"/\\"/g')"
gitversion="$(git rev-parse HEAD | cut -c -8)"
version "$gitbranch" "$gitversion";
exit 0
}
+8 -9
View File
@@ -1,5 +1,5 @@
/* backtrace.h -- Public header file for stack backtrace library.
Copyright (C) 2012-2024 Free Software Foundation, Inc.
Copyright (C) 2012-2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
Redistribution and use in source and binary forms, with or without
@@ -54,14 +54,13 @@ struct backtrace_state;
invalid after this function returns.
As a special case, the ERRNUM argument will be passed as -1 if no
debug info can be found for the executable, or if the debug info
exists but has an unsupported version, but the function requires
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
this case will be something along the lines of "no debug info".
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
but the function requires a symbol table (e.g., backtrace_syminfo).
This may be used as a signal that some other approach should be
tried. */
debug info can be found for the executable, but the function
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The
MSG in this case will be something along the lines of "no debug
info". Similarly, ERRNUM will be passed as -1 if there is no
symbol table, but the function requires a symbol table (e.g.,
backtrace_syminfo). This may be used as a signal that some other
approach should be tried. */
typedef void (*backtrace_error_callback) (void *data, const char *msg,
int errnum);
Binary file not shown.
+8
View File
@@ -0,0 +1,8 @@
#All folders
SRB2.res
depend.dep
depend.ped
*.o
#VC9 folder only
/VC9/Win32
/VC9/x64
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+2
View File
@@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing
+1 -2
View File
@@ -1,3 +1,2 @@
/cscope.out
*.json
*.idx
/srb2wii
-1
View File
@@ -28,7 +28,6 @@ LOCAL_SRC_FILES := am_map.c \
m_cheat.c \
m_fixed.c \
m_menu.c \
m_textinput.c \
m_misc.c \
m_queue.c \
m_random.c \
+551 -573
View File
File diff suppressed because it is too large. Load diff
+768 -354
View File
File diff suppressed because it is too large. Load diff
+18 -25
View File
@@ -12,8 +12,7 @@
# to avoid a false positive with the version detection...
SUPPORTED_GCC_VERSIONS:=\
151 150 15\
142 141 140 14\
141 14\
132 131 130 13\
123 122 121 120 12\
114 113 112 111 110 11\
@@ -25,7 +24,7 @@ SUPPORTED_GCC_VERSIONS:=\
55 54 53 52 51 50\
49 48 47 46 45 44 43 42 41 40
LATEST_GCC_VERSION=14.2.1
LATEST_GCC_VERSION=14.1
# gcc or g++
ifdef PREFIX
@@ -79,32 +78,12 @@ ifeq (,$(filter GCC%,$(.VARIABLES)))
endif
endif
ifdef GCC151
GCC150=1
endif
ifdef GCC15
GCC150=1
endif
ifdef GCC150
GCC142=1
endif
ifdef GCC142
ifdef GCC141
GCC141=1
endif
ifdef GCC141
GCC140=1
endif
ifdef GCC14
GCC140=1
endif
ifdef GCC140
GCC132=1
GCC14=1
endif
ifdef GCC132
@@ -458,6 +437,9 @@ endif
ifdef GCC44
WFLAGS+=-Wno-error=array-bounds
endif
ifdef GCC45
opts+=-fwrapv
endif
ifdef GCC46
WFLAGS+=-Wno-error=suggest-attribute=noreturn
endif
@@ -482,6 +464,7 @@ ifdef GCC81
WFLAGS+=-Wno-error=multistatement-macros
endif
#indicate platform and what interface use with
ifndef LINUX
ifndef FREEBSD
@@ -489,6 +472,7 @@ ifndef CYGWIN32
ifndef MINGW
ifndef MINGW64
ifndef SDL
ifndef DUMMY
$(error No interface or platform flag defined)
endif
endif
@@ -496,6 +480,7 @@ endif
endif
endif
endif
endif
#determine the interface directory (where you put all i_*.c)
i_net_o=$(OBJDIR)/i_net.o
@@ -520,6 +505,11 @@ UPX_OPTS+=-q
endif
#Interface Setup
ifdef DUMMY
INTERFACE=dummy
OBJDIR:=$(OBJDIR)/dummy
BIN:=$(BIN)/dummy
else
ifdef LINUX
SDL=1
ifdef LINUX64
@@ -566,6 +556,7 @@ endif
endif
endif
endif
endif
ifdef ARCHNAME
OBJDIR:=$(OBJDIR)/$(ARCHNAME)
@@ -580,6 +571,7 @@ ifdef SDL
OBJDIR:=$(OBJDIR)/SDL
endif
ifndef DUMMY
ifdef DEBUGMODE
OBJDIR:=$(OBJDIR)/Debug
BIN:=$(BIN)/Debug
@@ -587,3 +579,4 @@ else
OBJDIR:=$(OBJDIR)/Release
BIN:=$(BIN)/Release
endif
endif
-19
View File
@@ -1,19 +0,0 @@
makedir:=$(makedir)/Dedicated
sources+=$(call List,dedicated/Sourcefile)
opts+=-DDEDICATED
ifdef MINGW
libs+=-mconsole
endif
ifndef NOTHREADS
opts+=-DHAVE_THREADS
sources+=dedicated/i_threads.c
endif
NOOPENMPT=1
NOGME=1
NOHW=1
NOUPNP=1
-124
View File
@@ -1,124 +0,0 @@
#
# 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
-106
View File
@@ -1,106 +0,0 @@
#
# 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))))
-71
View File
@@ -1,71 +0,0 @@
#
# 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))
-47
View File
@@ -1,47 +0,0 @@
#
# 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
-16
View File
@@ -1,16 +0,0 @@
#
# 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
-76
View File
@@ -1,76 +0,0 @@
#
# 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
-71
View File
@@ -1,71 +0,0 @@
#
# Makefile options for SDL2 backend.
#
#
# SDL...., *looks at Alam*, THIS IS A MESS!
#
# ...a little bird flexes its muscles...
#
makedir:=$(makedir)/SDL
opts+=-DDIRECTFULLSCREEN -DHAVE_SDL
sources+=$(call List,sdl/Sourcefile)
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
-93
View File
@@ -1,93 +0,0 @@
#
# 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,@)
-181
View File
@@ -1,181 +0,0 @@
#
# 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))))))
# aggregate returns seem to happen alot in c++ so just supress em lel
CXXFLAGS+= -Wno-aggregate-return
# -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
-124
View File
@@ -1,124 +0,0 @@
#
# 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))
-97
View File
@@ -1,97 +0,0 @@
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.cpp
r_patch.c
r_patchrotation.c
r_plane.cpp
r_segs.cpp
r_skins.c
r_sky.c
r_splats.c
r_things.cpp
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
+137 -474
View File
@@ -1,10 +1,8 @@
// SONIC ROBO BLAST 2 KART
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 2024 by Vivian "toastergrl" Grannell.
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -35,31 +33,36 @@ static const UINT8 GRAYSRANGE = 16;
static const UINT8 BROWNS = (3*16);
static const UINT8 YELLOWS = (7*16);
static const UINT8 GREENS = (10*16);
//static const UINT8 CYANS = (13*16);
static const UINT8 BLUES = (14*16);
static const UINT8 DBLACK = 31;
static const UINT8 DWHITE = 0;
static const UINT8 NOCLIMBREDS = 248;
static const UINT8 NOCLIMBREDRANGE = 8;
static const UINT8 NOCLIMBGRAYS = 204;
static const UINT8 NOCLIMBBROWNS = (2*16);
static const UINT8 NOCLIMBYELLOWS = (11*16);
// Automap colors
#define BACKGROUND DBLACK
#define WALLCOLORS (REDS + REDRANGE/2)
#define WALLRANGE (REDRANGE/2)
#define NOCLIMBWALLCOLORS (NOCLIMBREDS + NOCLIMBREDRANGE/2)
#define NOCLIMBWALLRANGE (NOCLIMBREDRANGE/2)
#define THOKWALLCOLORS REDS
#define THOKWALLRANGE REDRANGE
#define TSWALLCOLORS DWHITE
#define TSFINISHLINE (GREENS + 2)
#define TSFOFINFO (BLUES + 4)
#define NOCLIMBTHOKWALLCOLORS NOCLIMBREDS
#define NOCLIMBTHOKWALLRANGE NOCLIMBREDRANGE
#define TSWALLCOLORS GRAYS
#define TSWALLRANGE GRAYSRANGE
#define NOCLIMBTSWALLCOLORS NOCLIMBGRAYS
#define FDWALLCOLORS BROWNS
#define NOCLIMBFDWALLCOLORS NOCLIMBBROWNS
#define CDWALLCOLORS YELLOWS
#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS
#define THINGCOLORS GREENS
#define GRIDCOLORS (GRAYS + GRAYSRANGE/2)
#define XHAIRCOLORS GRAYS
// Automap passes
#define PASS_SOLID 1
#define PASS_INTANGIBLE 2
#define PASS_FOF 4
// controls
#define AM_PANUPKEY KEY_UPARROW
#define AM_PANDOWNKEY KEY_DOWNARROW
@@ -107,6 +110,11 @@ typedef struct
mpoint_t a, b;
} mline_t;
typedef struct
{
fixed_t slp, islp;
} islope_t;
//
// The vector graphics for the automap.
// A line drawing of the player pointing right,
@@ -128,14 +136,16 @@ static const mline_t player_arrow[] = {
#undef R
#define NUMPLYRLINES (sizeof (player_arrow)/sizeof (mline_t))
#if 0
#define R (FRACUNIT)
static const mline_t cross_mark[] =
{
{ { -R, 0 }, { R, 0} },
{ { 0, -R }, { 0, R } },
static mline_t triangle_guy[] = {
{ { (fixed_t)-.867f*R, (fixed_t)-.5f*R }, { (fixed_t) .867f*R, (fixed_t)-.5f*R } },
{ { (fixed_t) .867f*R, (fixed_t)-.5f*R }, { (fixed_t) 0, (fixed_t) R } },
{ { (fixed_t) 0, (fixed_t) R }, { (fixed_t)-.867f*R, (fixed_t)-.5f*R } }
};
#undef R
#define NUMCROSSMARKLINES (sizeof(cross_mark)/sizeof(mline_t))
#define NUMTRIANGLEGUYLINES (sizeof (triangle_guy)/sizeof (mline_t))
#endif
#define R (FRACUNIT)
static const mline_t thintriangle_guy[] = {
@@ -152,14 +162,10 @@ static boolean draw_grid = false;
boolean automapactive = false;
boolean am_recalc = false; //added : 05-02-98 : true when screen size changes
static boolean am_stopped = true;
static boolean am_minigen = false;
static UINT8 *am_buf = NULL;
static INT32 f_x, f_y; // location of window on screen (always zero for both)
static INT32 f_w, f_h; // size of window on screen (always the screen width and height respectively)
static boolean m_keydown[4]; // which window panning keys are being pressed down?
static mpoint_t m_paninc; // how far the window pans each tic (map coords)
static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords)
static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords)
@@ -197,15 +203,14 @@ static fixed_t scale_mtof = (fixed_t)INITSCALEMTOF;
// used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof)
static fixed_t scale_ftom;
static player_t *plr = NULL; // the player represented by an arrow
static player_t *plr; // the player represented by an arrow
static boolean followplayer = true; // specifies whether to follow the player around
static INT32 followplayer = true; // specifies whether to follow the player around
// function for drawing lines, depends on rendermode
typedef void (*AMDRAWFLINEFUNC) (const fline_t *fl, INT32 color);
static AMDRAWFLINEFUNC AM_drawFline;
static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc);
static void AM_drawFline_soft(const fline_t *fl, INT32 color);
static void AM_activateNewScale(void)
@@ -237,7 +242,7 @@ static inline void AM_restoreScaleAndLoc(void)
m_x = old_m_x;
m_y = old_m_y;
}
else if (plr && plr->mo)
else
{
m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;
m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2;
@@ -255,15 +260,28 @@ static inline void AM_restoreScaleAndLoc(void)
*/
static void AM_findMinMaxBoundaries(void)
{
fixed_t a, b;
size_t i;
fixed_t a;
fixed_t b;
min_x = minimapinfo.min_x << MAPBITS;
max_x = minimapinfo.max_x << MAPBITS;
min_y = minimapinfo.min_y << MAPBITS;
max_y = minimapinfo.max_y << MAPBITS;
min_x = min_y = +INT32_MAX;
max_x = max_y = -INT32_MAX;
max_w = minimapinfo.map_w << MAPBITS;
max_h = minimapinfo.map_h << MAPBITS;
for (i = 0; i < numvertexes; i++)
{
if (vertexes[i].x < min_x)
min_x = vertexes[i].x;
else if (vertexes[i].x > max_x)
max_x = vertexes[i].x;
if (vertexes[i].y < min_y)
min_y = vertexes[i].y;
else if (vertexes[i].y > max_y)
max_y = vertexes[i].y;
}
max_w = (max_x >>= FRACTOMAPBITS) - (min_x >>= FRACTOMAPBITS);
max_h = (max_y >>= FRACTOMAPBITS) - (min_y >>= FRACTOMAPBITS);
a = FixedDiv(f_w<<FRACBITS, max_w);
b = FixedDiv(f_h<<FRACBITS, max_h);
@@ -318,8 +336,7 @@ static void AM_initVariables(void)
break;
plr = &players[pnum];
if (plr && plr->mo)
if (plr != NULL && plr->mo != NULL)
{
m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;
m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2;
@@ -333,23 +350,22 @@ static void AM_initVariables(void)
old_m_h = m_h;
}
//
// Called when the screen size changes.
//
static void AM_FrameBufferInit(void)
{
f_x = f_y = 0;
f_w = vid.width;
f_h = vid.height;
am_buf = vid.screens[0];
}
//
// should be called at the start of every level
// right now, i figure it out myself
//
static void AM_LevelInit(void)
{
f_x = f_y = 0;
f_w = vid.width;
f_h = vid.height;
AM_drawFline = AM_drawFline_soft;
#ifdef HWRENDER
if (rendermode == render_opengl)
AM_drawFline = HWR_drawAMline;
#endif
AM_findMinMaxBoundaries();
scale_mtof = FixedDiv(min_scale_mtof*10, 7*FRACUNIT);
if (scale_mtof > max_scale_mtof)
@@ -371,7 +387,7 @@ void AM_Stop(void)
*
* \sa AM_Stop
*/
void AM_Start(void)
static inline void AM_Start(void)
{
static INT32 lastlevel = -1;
@@ -380,12 +396,8 @@ void AM_Start(void)
am_stopped = false;
if (lastlevel != gamemap || am_recalc) // screen size changed
{
AM_FrameBufferInit();
if (lastlevel != gamemap)
{
AM_LevelInit();
lastlevel = gamemap;
}
AM_LevelInit();
lastlevel = gamemap;
am_recalc = false;
}
AM_initVariables();
@@ -411,28 +423,6 @@ static void AM_maxOutWindowScale(void)
AM_activateNewScale();
}
//
// set window panning
//
static void AM_setWindowPanning(void)
{
// up and down
if (m_keydown[2]) // pan up
m_paninc.y = FTOM(F_PANINC);
else if (m_keydown[3]) // pan down
m_paninc.y = -FTOM(F_PANINC);
else
m_paninc.y = 0;
// left and right
if (m_keydown[0]) // pan right
m_paninc.x = FTOM(F_PANINC);
else if (m_keydown[1]) // pan left
m_paninc.x = -FTOM(F_PANINC);
else
m_paninc.x = 0;
}
/** Responds to user inputs in automap mode.
*
* \param ev Event to possibly respond to.
@@ -465,49 +455,35 @@ boolean AM_Responder(event_t *ev)
{
case AM_PANRIGHTKEY: // pan right
if (!followplayer)
{
m_keydown[0] = true;
AM_setWindowPanning();
}
m_paninc.x = FTOM(F_PANINC);
else
rc = false;
break;
case AM_PANLEFTKEY: // pan left
if (!followplayer)
{
m_keydown[1] = true;
AM_setWindowPanning();
}
m_paninc.x = -FTOM(F_PANINC);
else
rc = false;
break;
case AM_PANUPKEY: // pan up
if (!followplayer)
{
m_keydown[2] = true;
AM_setWindowPanning();
}
m_paninc.y = FTOM(F_PANINC);
else
rc = false;
break;
case AM_PANDOWNKEY: // pan down
if (!followplayer)
{
m_keydown[3] = true;
AM_setWindowPanning();
}
m_paninc.y = -FTOM(F_PANINC);
else
rc = false;
break;
case AM_ZOOMOUTKEY: // zoom out
mtof_zoommul = M_ZOOMOUT;
ftom_zoommul = M_ZOOMIN;
AM_setWindowPanning();
break;
case AM_ZOOMINKEY: // zoom in
mtof_zoommul = M_ZOOMIN;
ftom_zoommul = M_ZOOMOUT;
AM_setWindowPanning();
break;
case AM_TOGGLEKEY:
AM_Stop();
@@ -521,7 +497,6 @@ boolean AM_Responder(event_t *ev)
}
else
AM_restoreScaleAndLoc();
AM_setWindowPanning();
break;
case AM_FOLLOWKEY:
followplayer = !followplayer;
@@ -541,32 +516,14 @@ boolean AM_Responder(event_t *ev)
switch (ev->data1)
{
case AM_PANRIGHTKEY:
if (!followplayer)
{
m_keydown[0] = false;
AM_setWindowPanning();
}
break;
case AM_PANLEFTKEY:
if (!followplayer)
{
m_keydown[1] = false;
AM_setWindowPanning();
}
m_paninc.x = 0;
break;
case AM_PANUPKEY:
if (!followplayer)
{
m_keydown[2] = false;
AM_setWindowPanning();
}
break;
case AM_PANDOWNKEY:
if (!followplayer)
{
m_keydown[3] = false;
AM_setWindowPanning();
}
m_paninc.y = 0;
break;
case AM_ZOOMOUTKEY:
case AM_ZOOMINKEY:
@@ -598,9 +555,6 @@ static inline void AM_changeWindowScale(void)
static inline void AM_doFollowPlayer(void)
{
if (!plr || !plr->mo)
return;
if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y)
{
m_x = FTOM(MTOF(plr->mo->x >> FRACTOMAPBITS)) - m_w/2;
@@ -770,16 +724,6 @@ static boolean AM_clipMline(const mline_t *ml, fline_t *fl)
}
#undef DOOUTCODE
//
// Draws a pixel.
//
static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc)
{
if (xx < 0 || yy < 0 || xx >= f_w || yy >= f_h)
return; // off the screen
am_buf[(yy*f_w) + xx] = cc;
}
//
// Classic Bresenham w/ whatever optimizations needed for speed
//
@@ -801,6 +745,8 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
}
#endif
#define PUTDOT(xx,yy,cc) V_DrawFill(xx,yy,1,1,cc|V_NOSCALESTART);
dx = fl->b.x - fl->a.x;
ax = 2 * (dx < 0 ? -dx : dx);
sx = dx < 0 ? -1 : 1;
@@ -817,7 +763,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d = ay - ax/2;
for (;;)
{
AM_drawPixel(x, y, color);
PUTDOT(x, y, color)
if (x == fl->b.x)
return;
if (d >= 0)
@@ -834,7 +780,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d = ax - ay/2;
for (;;)
{
AM_drawPixel(x, y, color);
PUTDOT(x, y, color)
if (y == fl->b.y)
return;
if (d >= 0)
@@ -846,6 +792,8 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d += ax;
}
}
#undef PUTDOT
}
//
@@ -867,18 +815,17 @@ static void AM_drawGrid(INT32 color)
fixed_t x, y;
fixed_t start, end;
mline_t ml;
fixed_t gridsize = (MAPBLOCKUNITS<<MAPBITS);
// Figure out start of vertical gridlines
start = m_x;
if ((start - (bmaporgx>>FRACTOMAPBITS)) % gridsize)
start += gridsize - ((start - (bmaporgx>>FRACTOMAPBITS)) % gridsize);
if ((start - bmaporgx) % (MAPBLOCKUNITS<<FRACBITS))
start += (MAPBLOCKUNITS<<FRACBITS) - ((start - bmaporgx) % (MAPBLOCKUNITS<<FRACBITS));
end = m_x + m_w;
// draw vertical gridlines
ml.a.y = m_y;
ml.b.y = m_y + m_h;
for (x = start; x < end; x += gridsize)
for (x = start; x < end; x += (MAPBLOCKUNITS<<FRACBITS))
{
ml.a.x = x;
ml.b.x = x;
@@ -887,14 +834,14 @@ static void AM_drawGrid(INT32 color)
// Figure out start of horizontal gridlines
start = m_y;
if ((start - (bmaporgy>>FRACTOMAPBITS)) % gridsize)
start += gridsize - ((start - (bmaporgy>>FRACTOMAPBITS)) % gridsize);
if ((start - bmaporgy) % (MAPBLOCKUNITS<<FRACBITS))
start += (MAPBLOCKUNITS<<FRACBITS) - ((start - bmaporgy) % (MAPBLOCKUNITS<<FRACBITS));
end = m_y + m_h;
// draw horizontal gridlines
ml.a.x = m_x;
ml.b.x = m_x + m_w;
for (y = start; y < end; y += gridsize)
for (y = start; y < end; y += (MAPBLOCKUNITS<<FRACBITS))
{
ml.a.y = y;
ml.b.y = y;
@@ -902,118 +849,14 @@ static void AM_drawGrid(INT32 color)
}
}
static INT32 GetDamage(INT32 special)
{
switch (special)
{
case 1: // Damage (Generic)
return 1;
case 6: // Death Pit (Camera Tilt)
return 6;
case 7: // Death Pit (No Camera Tilt)
return 7;
case 8: // Instant Kill
return 8;
default:
return 0;
}
}
static INT32 GetOffroad(INT32 special)
{
switch (special)
{
case 2: // Offroad (Weak)
return 2;
case 3: // Offroad
return 3;
case 4: // Offroad (Strong)
return 4;
default:
return 0;
}
}
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
end1 = (P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, ((normalheight + FRACUNIT/2) >> FRACBITS)) + FRACUNIT/2) >> FRACBITS; \
end2 = (P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, ((normalheight + FRACUNIT/2) >> FRACBITS)) + FRACUNIT/2) >> FRACBITS;
static ffloor_t *AM_CompareFOFs(size_t i, ffloor_t *rover, ffloor_t *secondarystore)
{
ffloor_t *secondaryrover = NULL;
for (; rover; rover = rover->next)
{
fixed_t rovt1, rovt2;
fixed_t rovb1, rovb2;
if (!(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_BLOCKPLAYER))
continue;
SLOPEPARAMS(*rover->t_slope, rovt1, rovt2, *rover->topheight)
SLOPEPARAMS(*rover->b_slope, rovb1, rovb2, *rover->bottomheight)
for (secondaryrover = secondarystore; secondaryrover; secondaryrover = secondaryrover->next)
{
fixed_t sect1, sect2;
fixed_t secb1, secb2;
if (!(secondaryrover->flags & FF_EXISTS))
continue;
if (!(secondaryrover->flags & FF_BLOCKPLAYER))
continue;
if (secondaryrover->secnum == rover->secnum)
break;
SLOPEPARAMS(*secondaryrover->t_slope, sect1, sect2, *secondaryrover->topheight)
SLOPEPARAMS(*secondaryrover->b_slope, secb1, secb2, *secondaryrover->bottomheight)
if (rovt1 != sect1)
continue;
if (rovt2 != sect2)
continue;
if (rovb1 != secb1)
continue;
if (rovb2 != secb2)
continue;
// this is fucking horrible
INT32 damage1, damage2;
INT32 offroad1, offroad2;
INT32 special1, special2;
special1 = GETSECSPECIAL(sectors[rover->secnum].special, 1);
special2 = GETSECSPECIAL(sectors[secondaryrover->secnum].special, 1);
damage1 = GetDamage(special1);
damage2 = GetDamage(special2);
offroad1 = GetOffroad(special1);
offroad2 = GetOffroad(special2);
if (damage1 != damage2
//|| sectors[rover->secnum].friction != sectors[secondaryrover->secnum].friction
|| offroad1 != offroad2)
continue;
break;
}
if (secondaryrover == NULL)
break;
}
return rover;
}
//
// Determines visible lines, draws them.
// This is LineDef based, not LineSeg based.
//
static void AM_drawWalls(UINT8 pass)
static inline void AM_drawWalls(void)
{
size_t i;
static mline_t l;
const fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale)>>FRACBITS;
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends
@@ -1023,142 +866,74 @@ static void AM_drawWalls(UINT8 pass)
l.a.y = lines[i].v1->y >> FRACTOMAPBITS;
l.b.x = lines[i].v2->x >> FRACTOMAPBITS;
l.b.y = lines[i].v2->y >> FRACTOMAPBITS;
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \
end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y); \
end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight)
SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight)
if (lines[i].backsector) {
SLOPEPARAMS(lines[i].backsector->f_slope, backf1, backf2, lines[i].backsector->floorheight)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
}
#undef SLOPEPARAMS
if (!lines[i].backsector) // 1-sided
{
if (!(pass & PASS_SOLID))
;
else if (frontf1 != frontc1 || frontf2 != frontc2 || lines[i].frontsector->f_slope)
{
AM_drawMline(&l, TSWALLCOLORS);
}
else if (!am_minigen)
{
if (lines[i].flags & ML_NOCLIMB)
AM_drawMline(&l, NOCLIMBWALLCOLORS);
else
AM_drawMline(&l, WALLCOLORS);
}
continue;
}
SLOPEPARAMS(lines[i].backsector->f_slope, backf1, backf2, lines[i].backsector->floorheight)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
|| (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier
{
if (backf1 == backc1 && backf2 == backc2
&& frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers
{
if (!am_minigen && (pass & PASS_INTANGIBLE))
{
AM_drawMline(&l, GRIDCOLORS);
}
if (lines[i].flags & ML_NOCLIMB)
AM_drawMline(&l, NOCLIMBTSWALLCOLORS);
else
AM_drawMline(&l, TSWALLCOLORS);
}
else if (pass & PASS_SOLID)
else
{
AM_drawMline(&l, TSWALLCOLORS);
if (lines[i].flags & ML_NOCLIMB)
AM_drawMline(&l, NOCLIMBTHOKWALLCOLORS);
else
AM_drawMline(&l, THOKWALLCOLORS);
}
}
else
{
if (lines[i].flags & ML_IMPASSIBLE) // (ML_IMPASSABLE|ML_BLOCKPLAYERS)
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSWALLCOLORS); // Completely solid course boundary
}
else if ((lines[i].flags & ML_EFFECT4) // ML_MIDSOLID
&& sides[lines->sidenum[0]].midtexture)
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSWALLCOLORS); // solid midtexture, likely a course boundary
}
if ((backf1 != frontf1 && abs(backf1 - frontf1) > maxstep)
|| (backf2 != frontf2 && abs(backf2 - frontf2) > maxstep))
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSWALLCOLORS); // floor-wall, likely a course boundary
}
else if (GETSECSPECIAL(lines[i].frontsector->special, 4) == 10 || GETSECSPECIAL(lines[i].backsector->special, 4) == 10)
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSFINISHLINE); // finish line
}
else if (backf1 != frontf1 || backf2 != frontf2)
{
if (pass & PASS_INTANGIBLE)
AM_drawMline(&l, FDWALLCOLORS); // floorlevel change
}
else if (backc1 != frontc1 || backc2 != frontc2)
{
if (!(pass & PASS_INTANGIBLE))
;
else if (abs(backc1 - frontc1) < maxstep
|| abs(backc2 - frontc2) < maxstep)
{
AM_drawMline(&l, CDWALLCOLORS); // ceilinglevel change
if (lines[i].flags & ML_NOCLIMB) {
if (backf1 != frontf1 || backf2 != frontf2) {
AM_drawMline(&l, NOCLIMBFDWALLCOLORS); // floor level change
}
else if (backc1 != frontc1 || backc2 != frontc2) {
AM_drawMline(&l, NOCLIMBCDWALLCOLORS); // ceiling level change
}
else
{
AM_drawMline(&l, GRIDCOLORS); // ceiling-wall, not likely to be a course boundary but flagged up just in case
}
AM_drawMline(&l, NOCLIMBTSWALLCOLORS);
}
else
{
ffloor_t *rover = NULL;
if (lines[i].frontsector->ffloors || lines[i].backsector->ffloors)
{
if (lines[i].backsector->ffloors == NULL)
{
// Check frontside for one solid
for (rover = lines[i].frontsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_BLOCKPLAYER))
continue;
break;
}
}
else if (lines[i].frontsector->ffloors == NULL)
{
// Check backside for one solid
for (rover = lines[i].backsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_BLOCKPLAYER))
continue;
break;
}
}
else
{
// Check to see if any secnums exist in one but not the other.
rover = AM_CompareFOFs(i, lines[i].frontsector->ffloors, lines[i].backsector->ffloors);
if (rover == NULL)
rover = AM_CompareFOFs(i, lines[i].backsector->ffloors, lines[i].frontsector->ffloors);
}
if (backf1 != frontf1 || backf2 != frontf2) {
AM_drawMline(&l, FDWALLCOLORS); // floor level change
}
if (rover != NULL)
{
if (pass & PASS_FOF)
AM_drawMline(&l, TSFOFINFO); // a FOF is here but we don't know how to distinguish them yet
}
else if (!am_minigen)
{
if (pass & PASS_INTANGIBLE)
AM_drawMline(&l, GRIDCOLORS); // likely low-relevance line
else if (backc1 != frontc1 || backc2 != frontc2) {
AM_drawMline(&l, CDWALLCOLORS); // ceiling level change
}
else
AM_drawMline(&l, TSWALLCOLORS);
}
}
}
}
#undef SLOPEPARAMS
//
// Rotation in 2D.
// Used to rotate player arrow line character.
@@ -1229,19 +1004,23 @@ static inline void AM_drawPlayers(void)
player_t *p;
INT32 color = GREENS;
if (!multiplayer)
{
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y);
return;
}
// multiplayer (how??)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (!players[i].mo)
continue;
p = &players[i];
if (p->skincolor > 0)
color = R_GetTranslationColormap(TC_DEFAULT, p->skincolor, GTC_CACHE)[GREENS + 8];
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 16<<FRACBITS, p->mo->angle, color, p->mo->x, p->mo->y);
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, p->mo->angle, color, p->mo->x, p->mo->y);
}
}
@@ -1255,65 +1034,19 @@ static inline void AM_drawThings(UINT8 colors)
t = sectors[i].thinglist;
while (t)
{
if (!t->player)
AM_drawLineCharacter(thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<<FRACBITS, t->angle, colors, t->x, t->y);
AM_drawLineCharacter(thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<<FRACBITS, t->angle, colors, t->x, t->y);
t = t->snext;
}
}
}
static inline void AM_drawSpecialThingsOnly(UINT8 colors)
{
size_t i;
for (i = 0; i < numsectors; i++)
{
mobj_t *t = NULL;
// this is fucking horrible
const INT32 special = GETSECSPECIAL(sectors[i].special, 1);
if (GetDamage(special) != 0
//|| sectors[i].friction < ORIG_FRICTION
|| GetOffroad(special) != 0)
continue;
t = sectors[i].thinglist;
while (t)
{
if (t->type == MT_RANDOMITEM
|| t->type == MT_STARPOST
|| (t->flags & MF_SPRING))
AM_drawLineCharacter(thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<<FRACBITS, t->angle, colors, t->x, t->y);
t = t->snext;
}
}
}
/** Draws the crosshair.
/** Draws the crosshair, actually just a dot in software mode.
*
* \param color Color for the crosshair.
*/
static inline void AM_drawCrosshair(UINT8 color)
{
const fixed_t scale = 4<<FRACBITS;
size_t i;
fline_t fl;
for (i = 0; i < NUMCROSSMARKLINES; i++)
{
fl.a.x = FixedMul(cross_mark[i].a.x, scale) >> FRACBITS;
fl.a.y = FixedMul(cross_mark[i].a.y, scale) >> FRACBITS;
fl.b.x = FixedMul(cross_mark[i].b.x, scale) >> FRACBITS;
fl.b.y = FixedMul(cross_mark[i].b.y, scale) >> FRACBITS;
fl.a.x += f_x + (f_w / 2);
fl.a.y += f_y + (f_h / 2);
fl.b.x += f_x + (f_w / 2);
fl.b.y += f_y + (f_h / 2);
AM_drawFline(&fl, color);
}
V_DrawFill(f_w/2 + f_x, f_h/2 + f_y, 1, 1, color|V_NOSCALESTART);
}
/** Draws the automap.
@@ -1323,81 +1056,11 @@ void AM_Drawer(void)
if (!automapactive)
return;
AM_drawFline = AM_drawFline_soft;
#ifdef HWRENDER
if (rendermode == render_opengl)
AM_drawFline = HWR_drawAMline;
#endif
AM_clearFB(BACKGROUND);
if (draw_grid) AM_drawGrid(GRIDCOLORS);
AM_drawWalls(PASS_FOF|PASS_INTANGIBLE|PASS_SOLID);
AM_drawThings(THINGCOLORS);
AM_drawWalls();
AM_drawPlayers();
AM_drawThings(THINGCOLORS);
if (!followplayer) AM_drawCrosshair(XHAIRCOLORS);
}
minigen_t *AM_MinimapGenerate(INT32 mul)
{
static minigen_t ret = {0};
if (automapactive)
return NULL;
am_minigen = true;
AM_drawFline = AM_drawFline_soft; // yes, even in GL
//AM_FrameBufferInit();
f_x = f_y = 0;
ret.w = f_w = minimapinfo.minimap_w * mul;
ret.h = f_h = minimapinfo.minimap_h * mul;
am_buf = ret.buf = NULL;
//AM_LevelInit();
AM_findMinMaxBoundaries();
scale_mtof = min_scale_mtof - (min_scale_mtof/20);
scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
//AM_initVariables();
f_oldloc.x = INT32_MAX;
m_paninc.x = m_paninc.y = 0;
ftom_zoommul = FRACUNIT;
mtof_zoommul = FRACUNIT;
m_w = FTOM(f_w);
m_h = FTOM(f_h);
//AM_changeWindowLoc();
m_x = min_x - FixedMul(m_w, FRACUNIT/40);
m_y = min_y - FixedMul(m_h, FRACUNIT/40);
m_x2 = m_x + m_w;
m_y2 = m_y + m_h;
// for saving & restoring
old_m_x = m_x;
old_m_y = m_y;
old_m_w = m_w;
old_m_h = m_h;
am_buf = ret.buf = malloc((f_w*f_h));
if (ret.buf == NULL)
return NULL;
//AM_clearFB(BACKGROUND);
memset(am_buf, 0xff, (f_w*f_h));
AM_drawSpecialThingsOnly(BACKGROUND);
AM_drawWalls(PASS_FOF);
AM_drawWalls(PASS_INTANGIBLE);
AM_drawWalls(PASS_SOLID);
am_buf = NULL;
am_recalc = true;
am_minigen = false;
return &ret;
AM_drawCrosshair(XHAIRCOLORS);
}
+8 -17
View File
@@ -1,10 +1,8 @@
// SONIC ROBO BLAST 2 KART
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 2024 by Vivian "toastergrl" Grannell.
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -28,6 +26,11 @@ typedef struct
fpoint_t a, b;
} fline_t;
// Used by ST StatusBar stuff.
#define AM_MSGHEADER (('a'<<24)+('m'<<16))
#define AM_MSGENTERED (AM_MSGHEADER | ('e'<<8))
#define AM_MSGEXITED (AM_MSGHEADER | ('x'<<8))
extern boolean am_recalc; // true if screen size changes
extern boolean automapactive; // In AutoMap mode?
@@ -40,19 +43,7 @@ void AM_Ticker(void);
// Called by main loop, instead of view drawer if automap is active.
void AM_Drawer(void);
// Enables the automap.
void AM_Start(void);
// Called to force the automap to quit if the level is completed while it is up.
void AM_Stop(void);
typedef struct
{
INT32 w, h;
UINT8 *buf;
} minigen_t;
// Minimap generation
minigen_t *AM_MinimapGenerate(INT32 mul);
#endif
+4
View File
@@ -184,6 +184,8 @@ void I_OutputMsg(const char *fmt, ...)
void I_StartupMouse(void){}
void I_StartupMouse2(void){}
void I_StartupKeyboard(void){}
INT32 I_GetKey(void)
@@ -240,6 +242,8 @@ void I_GetJoystickEvents(void){}
void I_GetJoystick2Events(void){}
void I_GetMouseEvents(void){}
char *I_GetEnv(const char *name)
{
LOGW("I_GetEnv() called?!");
+1
View File
@@ -46,6 +46,7 @@ INT32 VID_SetMode(INT32 modenum)
vid.modenum = 0;
vid.width = 320;
vid.height = 240;
vid.bpp = 1;
vid.buffer = android_surface;
return 0;
}
+5 -2
View File
@@ -36,7 +36,7 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm
return;
// Lua can handle it!
if (LUA_HookBotAI(sonic, tails, cmd))
if (LUAh_BotAI(sonic, tails, cmd))
return;
if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
@@ -118,8 +118,11 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
return;
}
// Bot AI isn't programmed in analog.
//CV_SetValue(&cv_analog2, false);
// Let Lua scripts build ticcmds
if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd)))
if (LUAh_BotTiccmd(player, cmd))
return;
// We don't have any main character AI, sorry. D:
+55
View File
@@ -0,0 +1,55 @@
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
-26
View File
@@ -1,26 +0,0 @@
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
+23 -30
View File
@@ -1,7 +1,7 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2024 by Sonic Team Junior.
// Copyright (C) 1999-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -11,9 +11,6 @@
/// \brief Macros to read/write from/to a UINT8 *,
/// used for packet creation and such
#ifndef __BYTEPTR_H__
#define __BYTEPTR_H__
#if defined (__alpha__) || defined (__arm__) || defined (__mips__) || defined (__ia64__) || defined (__clang__)
#define DEALIGNED
#endif
@@ -28,7 +25,6 @@
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = (void *)p; const UINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITESINT8(p,b) do { SINT8 *p_tmp = (void *)p; const SINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT16(p,b) do { INT16 *p_tmp = (void *)p; const INT16 tv = ( INT16)(b); memcpy(p, &tv, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT16_2(p,b) do { INT16 *p_tmp = ( INT16 *)p; const INT16 tv = ( INT16)(b); memcpy(p, &tv, sizeof( INT16)); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0) // dumb hack for mumble
#define WRITEUINT16(p,b) do { UINT16 *p_tmp = (void *)p; const UINT16 tv = ( UINT16)(b); memcpy(p, &tv, sizeof( UINT16)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT32(p,b) do { INT32 *p_tmp = (void *)p; const INT32 tv = ( INT32)(b); memcpy(p, &tv, sizeof( INT32)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEUINT32(p,b) do { UINT32 *p_tmp = (void *)p; const UINT32 tv = ( UINT32)(b); memcpy(p, &tv, sizeof( UINT32)); p_tmp++; p = (void *)p_tmp; } while (0)
@@ -39,7 +35,6 @@
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = ( UINT8 *)p; *p_tmp = ( UINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITESINT8(p,b) do { SINT8 *p_tmp = ( SINT8 *)p; *p_tmp = ( SINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT16(p,b) do { INT16 *p_tmp = ( INT16 *)p; *p_tmp = ( INT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT16_2(p,b) do { INT16 *p_tmp = ( INT16 *)p; *p_tmp = ( INT16)(b); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0) // dumb hack for mumble
#define WRITEUINT16(p,b) do { UINT16 *p_tmp = ( UINT16 *)p; *p_tmp = ( UINT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT32(p,b) do { INT32 *p_tmp = ( INT32 *)p; *p_tmp = ( INT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEUINT32(p,b) do { UINT32 *p_tmp = ( UINT32 *)p; *p_tmp = ( UINT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
@@ -155,7 +150,7 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
#undef DEALIGNED
#define WRITESTRINGN(p, s, n) do { \
#define WRITESTRINGN(p, s, n) ({ \
size_t tmp_i; \
\
for (tmp_i = 0; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) \
@@ -163,72 +158,70 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
\
if (tmp_i < n) \
WRITECHAR(p, '\0'); \
} while (0)
})
#define WRITESTRINGL(p, s, n) do { \
#define WRITESTRINGL(p, s, n) ({ \
size_t tmp_i; \
\
for (tmp_i = 0; tmp_i < n - 1 && s[tmp_i] != '\0'; tmp_i++) \
WRITECHAR(p, s[tmp_i]); \
\
WRITECHAR(p, '\0'); \
} while (0)
})
#define WRITESTRING(p, s) do { \
#define WRITESTRING(p, s) ({ \
size_t tmp_i; \
\
for (tmp_i = 0; s[tmp_i] != '\0'; tmp_i++) \
WRITECHAR(p, s[tmp_i]); \
\
WRITECHAR(p, '\0'); \
} while (0)
})
#define WRITEMEM(p, s, n) do { \
memcpy(p, s, n); \
p += n; \
} while (0)
#define WRITEMEM(p, s, n) ({ \
memcpy(p, s, n); \
p += n; \
})
#define SKIPSTRING(p) while (READCHAR(p) != '\0')
#define SKIPSTRINGN(p, n) do { \
#define SKIPSTRINGN(p, n) ({ \
size_t tmp_i = 0; \
\
while (tmp_i < n && READCHAR(p) != '\0') \
tmp_i++; \
} while (0)
})
#define SKIPSTRINGL(p, n) SKIPSTRINGN(p, n)
#define READSTRINGN(p, s, n) do { \
#define READSTRINGN(p, s, n) ({ \
size_t tmp_i = 0; \
\
while (tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
} while (0)
})
#define READSTRINGL(p, s, n) do { \
#define READSTRINGL(p, s, n) ({ \
size_t tmp_i = 0; \
\
while (tmp_i < n - 1 && (s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
} while (0)
})
#define READSTRING(p, s) do { \
#define READSTRING(p, s) ({ \
size_t tmp_i = 0; \
\
while ((s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
} while (0)
})
#define READMEM(p, s, n) do { \
memcpy(s, p, n); \
p += n; \
} while (0)
#endif // __BYTEPTR_H__
#define READMEM(p, s, n) ({ \
memcpy(s, p, n); \
p += n; \
})
+31 -38
View File
@@ -240,6 +240,7 @@ void COM_ImmedExecute(const char *ptext)
while (i < strlen(ptext))
{
quotes = 0;
for (j = 0; i < strlen(ptext); i++,j++)
{
@@ -627,7 +628,7 @@ static void COM_ExecuteString(char *ptext)
// check cvars
// Hurdler: added at Ebola's request ;)
// (don't flood the console in software mode with bad gl_xxx command)
// (don't flood the console in software mode with bad gr_xxx command)
if (!CV_Command() && con_destlines)
CONS_Printf(M_GetText("Unknown command '%s'\n"), COM_Argv(0));
}
@@ -816,17 +817,12 @@ static void COM_Help_f(void)
cvar = CV_FindVar(help);
if (cvar)
{
boolean floatmode = false;
const char *cvalue = NULL;
CONS_Printf("\x82""Variable %s:\n", cvar->name);
CONS_Printf(M_GetText(" flags: "));
if (cvar->flags & CV_SAVE)
CONS_Printf("AUTOSAVE ");
if (cvar->flags & CV_FLOAT)
{
CONS_Printf("FLOAT ");
floatmode = true;
}
if (cvar->flags & CV_NETVAR)
CONS_Printf("NETVAR ");
if (cvar->flags & CV_CALL)
@@ -836,43 +832,30 @@ static void COM_Help_f(void)
CONS_Printf("\n");
if (cvar->PossibleValue)
{
if (!stricmp(cvar->PossibleValue[0].strvalue, "MIN") && !stricmp(cvar->PossibleValue[1].strvalue, "MAX"))
{
if (!stricmp(cvar->PossibleValue[0].strvalue, "MIN") && !stricmp(cvar->PossibleValue[1].strvalue, "MAX"))
{
if (floatmode)
{
float fu = FIXED_TO_FLOAT(cvar->PossibleValue[0].value);
float ck = FIXED_TO_FLOAT(cvar->PossibleValue[1].value);
CONS_Printf(" range from %ld%s to %ld%s\n",
(long)fu, M_Ftrim(fu),
(long)ck, M_Ftrim(ck));
}
else
CONS_Printf(" range from %d to %d\n", cvar->PossibleValue[0].value,
cvar->PossibleValue[1].value);
i = 2;
}
CONS_Printf(" range from %d to %d\n", cvar->PossibleValue[0].value,
cvar->PossibleValue[1].value);
i = 2;
}
{
const char *cvalue = NULL;
//CONS_Printf(M_GetText(" possible value : %s\n"), cvar->name);
while (cvar->PossibleValue[i].strvalue)
{
if (floatmode)
CONS_Printf(" %-2f : %s\n", FIXED_TO_FLOAT(cvar->PossibleValue[i].value),
cvar->PossibleValue[i].strvalue);
else
CONS_Printf(" %-2d : %s\n", cvar->PossibleValue[i].value,
cvar->PossibleValue[i].strvalue);
CONS_Printf(" %-2d : %s\n", cvar->PossibleValue[i].value,
cvar->PossibleValue[i].strvalue);
if (cvar->PossibleValue[i].value == cvar->value)
cvalue = cvar->PossibleValue[i].strvalue;
i++;
}
if (cvalue)
CONS_Printf(" Current value: %s\n", cvalue);
else
CONS_Printf(" Current value: %d\n", cvar->value);
}
}
if (cvalue)
CONS_Printf(" Current value: %s\n", cvalue);
else if (cvar->string)
CONS_Printf(" Current value: %s\n", cvar->string);
else
CONS_Printf(" Current value: %d\n", cvar->value);
}
@@ -1043,10 +1026,7 @@ static void COM_Add_f(void)
}
if (( cvar->flags & CV_FLOAT ))
{
float n =FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2));
CV_Set(cvar, va("%ld%s", (long)n, M_Ftrim(n)));
}
CV_Set(cvar, va("%f", FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2))));
else
CV_AddValue(cvar, atoi(COM_Argv(2)));
}
@@ -1513,7 +1493,11 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
if (server)
{
SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return;
}
@@ -2004,7 +1988,7 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
return true;
}
// Block the Xbox DInput default axes and reset to the current defaults
// Block the Xbox DInput default axes and reset to the current defaults
static boolean CV_FilterJoyAxisVars2(consvar_t *v, const char *valstr)
{
if (!stricmp(v->name, "joyaxis_turn") && !stricmp(valstr, "X-Axis"))
@@ -2061,6 +2045,15 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
if (GETMAJOREXECVERSION(cv_execversion.value) < 2) // 2 = 1.0.2
{
#if 0
// We don't have changed saved cvars yet
if (!stricmp(v->name, "alwaysmlook")
|| !stricmp(v->name, "alwaysmlook2")
|| !stricmp(v->name, "mousemove")
|| !stricmp(v->name, "mousemove2"))
return false;
#endif
// axis defaults were changed to be friendly to 360 controllers
// if ALL axis settings are defaults, then change them to new values
if (!CV_FilterJoyAxisVars(v, valstr))
-8
View File
@@ -13,10 +13,6 @@
#ifndef __COMMAND_H__
#define __COMMAND_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include "doomdef.h"
@@ -193,8 +189,4 @@ UINT8 CV_CheatsEnabled(void);
// Returns cvar by name. Exposed here for Lua.
consvar_t *CV_FindVar(const char *name);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __COMMAND_H__
+294 -98
View File
@@ -32,7 +32,6 @@
#include "i_threads.h"
#include "d_main.h"
#include "m_menu.h"
#include "m_textinput.h"
#include "filesrch.h"
#ifdef HWRENDER
@@ -44,12 +43,8 @@
#ifdef HAVE_THREADS
I_mutex con_mutex;
// g_in_exiting_signal_handler is an evil hack
// to avoid infinite SIGABRT recursion in the signal handler
// due to poisoned locks or mach-o kernel not supporting locks in signals
// or something like that. idk
# define Lock_state() if (!g_in_exiting_signal_handler) { I_lock_mutex(&con_mutex); }
# define Unlock_state() if (!g_in_exiting_signal_handler) { I_unlock_mutex(con_mutex); }
# define Lock_state() I_lock_mutex(&con_mutex)
# define Unlock_state() I_unlock_mutex(con_mutex)
#else/*HAVE_THREADS*/
# define Lock_state()
# define Unlock_state()
@@ -98,7 +93,9 @@ static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines
static INT32 inputline; // current input line number
static INT32 inputhist; // line number of history input line to restore
static textinput_t input;
static size_t input_cur; // position of cursor in line
static size_t input_sel; // position of selection marker (I.E.: anything between this and input_cur is "selected")
static size_t input_len; // length of current line, used to bound cursor and such
// notice: input does NOT include the "$" at the start of the line. - 11/3/16
// protos.
@@ -275,28 +272,29 @@ void CON_SetupBackColormap(void)
switch (cons_backcolor.value)
{
case 0: palindex = 15; break; // White
case 1: palindex = 31; break; // Gray
case 2: palindex = 47; break; // Sepia
case 3: palindex = 63; break; // Brown
case 4: palindex = 150; shift = 7; break; // Pink
case 5: palindex = 127; shift = 7; break; // Raspberry
case 6: palindex = 143; break; // Red
case 7: palindex = 86; shift = 7; break; // Creamsicle
case 8: palindex = 95; break; // Orange
case 9: palindex = 119; shift = 7; break; // Gold
case 10: palindex = 111; break; // Yellow
case 11: palindex = 191; shift = 7; break; // Emerald
case 12: palindex = 175; break; // Green
case 13: palindex = 219; break; // Cyan
case 14: palindex = 207; shift = 7; break; // Steel
case 15: palindex = 230; shift = 7; break; // Periwinkle
case 16: palindex = 239; break; // Blue
case 17: palindex = 199; shift = 7; break; // Purple
case 18: palindex = 255; shift = 7; break; // Lavender
case 0: palindex = 15; break; // White
case 1: palindex = 31; break; // Gray
case 2: palindex = 47; break; // Sepia
case 3: palindex = 63; break; // Brown
case 4: palindex = 150; shift = 7; break; // Pink
case 5: palindex = 127; shift = 7; break; // Raspberry
case 6: palindex = 143; break; // Red
case 7: palindex = 86; shift = 7; break; // Creamsicle
case 8: palindex = 95; break; // Orange
case 9: palindex = 119; shift = 7; break; // Gold
case 10: palindex = 111; break; // Yellow
case 11: palindex = 191; shift = 7; break; // Emerald
case 12: palindex = 175; break; // Green
case 13: palindex = 219; break; // Cyan
case 14: palindex = 207; shift = 7; break; // Steel
case 15: palindex = 230; shift = 7; break; // Periwinkle
case 16: palindex = 239; break; // Blue
case 17: palindex = 199; shift = 7; break; // Purple
case 18: palindex = 255; shift = 7; break; // Lavender
// Default green
default: palindex = 175; break;
}
}
// setup background colormap
for (i = 0, j = 0; i < 768; i += 3, j++)
@@ -456,8 +454,7 @@ static void CON_InputInit(void)
// prepare the first prompt line
memset(inputlines, 0, sizeof (inputlines));
inputline = 0;
M_TextInputInit(&input, inputlines[inputline], CON_MAXPROMPTCHARS);
input_cur = input_sel = input_len = 0;
Unlock_state();
}
@@ -607,7 +604,7 @@ static void CON_MoveConsole(void)
}
// Not instant - Increment fracmovement fractionally
fracmovement += FixedMul(cons_speed.value*vid.fdupy, (cv_uncappedhud.value ? renderdeltatics : FRACUNIT));
fracmovement += FixedMul(cons_speed.value*vid.fdupy, renderdeltatics);
if (con_curlines < con_destlines) // Move the console downwards
{
@@ -620,11 +617,11 @@ static void CON_MoveConsole(void)
con_curlines -= FixedInt(fracmovement);
if (con_curlines < con_destlines)
con_curlines = con_destlines;
if (con_destlines == 0) // If the console is being closed, not just moved up...
con_tick = 0; // ...don't show the blinking cursor
}
fracmovement %= FRACUNIT; // Reset fracmovement's integer value, but keep the fraction
Unlock_state();
@@ -634,7 +631,7 @@ INT32 CON_ShiftChar(INT32 ch)
{
if (I_UseNativeKeyboard())
return ch;
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
{
if (cv_keyboardlayout.value == 3)
@@ -801,6 +798,113 @@ void CON_Ticker(void)
Unlock_state();
}
//
// ----
//
// Shortcuts for adding and deleting characters, strings, and sections
// Necessary due to moving cursor
//
static void CON_InputClear(void)
{
Lock_state();
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
input_cur = input_sel = input_len = 0;
Unlock_state();
}
static void CON_InputSetString(const char *c)
{
Lock_state();
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
strcpy(inputlines[inputline], c);
input_cur = input_sel = input_len = strlen(c);
Unlock_state();
}
static void CON_InputAddString(const char *c)
{
size_t csize = strlen(c);
Lock_state();
if (input_len + csize > CON_MAXPROMPTCHARS-1)
{
Unlock_state();
return;
}
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur+csize], &inputlines[inputline][input_cur], input_len-input_cur);
memcpy(&inputlines[inputline][input_cur], c, csize);
input_len += csize;
input_sel = (input_cur += csize);
Unlock_state();
}
static void CON_InputDelSelection(void)
{
size_t start, end, len;
Lock_state();
if (input_cur > input_sel)
{
start = input_sel;
end = input_cur;
}
else
{
start = input_cur;
end = input_sel;
}
len = (end - start);
if (end != input_len)
memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-end);
memset(&inputlines[inputline][input_len - len], 0, len);
input_len -= len;
input_sel = input_cur = start;
Unlock_state();
}
static void CON_InputAddChar(char c)
{
if (input_len >= CON_MAXPROMPTCHARS-1)
return;
Lock_state();
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur+1], &inputlines[inputline][input_cur], input_len-input_cur);
inputlines[inputline][input_cur++] = c;
inputlines[inputline][++input_len] = 0;
input_sel = input_cur;
Unlock_state();
}
static void CON_InputDelChar(void)
{
if (!input_cur)
return;
Lock_state();
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur-1], &inputlines[inputline][input_cur], input_len-input_cur);
inputlines[inputline][--input_len] = 0;
input_sel = --input_cur;
Unlock_state();
}
//
// ----
//
@@ -826,7 +930,7 @@ boolean CON_Responder(event_t *ev)
// let go keyup events, don't eat them
if (ev->type != ev_keydown && ev->type != ev_console)
{
if (ev->data1 == gamecontrol[0][gc_console][0] || ev->data1 == gamecontrol[0][gc_console][1])
if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1])
consdown = false;
return false;
}
@@ -844,7 +948,7 @@ boolean CON_Responder(event_t *ev)
INT32 i;
for (i = 0; i < num_gamecontrols; i++)
{
if (gamecontrol[0][i][0] == ev->data1 || gamecontrol[0][i][1] == ev->data1)
if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1)
break;
}
@@ -852,7 +956,7 @@ boolean CON_Responder(event_t *ev)
return false;
}
if (key == gamecontrol[0][gc_console][0] || key == gamecontrol[0][gc_console][1])
if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])
{
if (consdown) // ignore repeat
return true;
@@ -881,10 +985,6 @@ boolean CON_Responder(event_t *ev)
}
}
Lock_state();
M_TextInputHandle(&input, key);
Unlock_state();
// Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas
if (key == KEY_LSHIFT || key == KEY_RSHIFT
|| key == KEY_LCTRL || key == KEY_RCTRL
@@ -897,11 +997,12 @@ boolean CON_Responder(event_t *ev)
// show all cvars/commands that match what we have inputted
if (key == KEY_TAB)
{
if (!completion[0])
{
if (!input.length || input.length >= 40 || strchr(input.buffer, ' '))
if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' '))
return true;
strcpy(completion, input.buffer);
strcpy(completion, inputlines[inputline]);
comskips = varskips = 0;
}
@@ -922,9 +1023,42 @@ boolean CON_Responder(event_t *ev)
return true;
}
// Those are already handled in M_TextInputHandle, but they do extra logic... Maybe textinput_t should have some sort of callbacks?
if (key == 'x' || key == 'X' || key == 'v' || key == 'V')
if (key == 'x' || key == 'X')
{
if (input_sel > input_cur)
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
else
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
CON_InputDelSelection();
completion[0] = 0;
return true;
}
else if (key == 'c' || key == 'C')
{
if (input_sel > input_cur)
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
else
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
return true;
}
else if (key == 'v' || key == 'V')
{
const char *paste = I_ClipboardPaste();
if (input_sel != input_cur)
CON_InputDelSelection();
if (paste != NULL)
CON_InputAddString(paste);
completion[0] = 0;
return true;
}
// Select all
if (key == 'a' || key == 'A')
{
input_sel = 0;
input_cur = input_len;
return true;
}
// ...why shouldn't it eat the key? if it doesn't, it just means you
// can control Sonic from the console, which is silly
@@ -939,9 +1073,9 @@ boolean CON_Responder(event_t *ev)
// remember typing for several completions (a-la-4dos)
if (!completion[0])
{
if (!input.length || input.length >= 40 || strchr(input.buffer, ' '))
if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' '))
return true;
strcpy(completion, input.buffer);
strcpy(completion, inputlines[inputline]);
comskips = varskips = 0;
}
else
@@ -972,11 +1106,7 @@ boolean CON_Responder(event_t *ev)
cmd = CV_CompleteVar(completion, varskips);
if (cmd)
{
Lock_state();
M_TextInputSetString(&input, va("%s ", cmd));
Unlock_state();
}
CON_InputSetString(va("%s ", cmd));
else
{
if (comskips > 0)
@@ -1002,6 +1132,37 @@ boolean CON_Responder(event_t *ev)
return true;
}
if (key == KEY_LEFTARROW)
{
if (input_cur != 0)
--input_cur;
if (!shiftdown)
input_sel = input_cur;
return true;
}
else if (key == KEY_RIGHTARROW)
{
if (input_cur < input_len)
++input_cur;
if (!shiftdown)
input_sel = input_cur;
return true;
}
else if (key == KEY_HOME)
{
input_cur = 0;
if (!shiftdown)
input_sel = input_cur;
return true;
}
else if (key == KEY_END)
{
input_cur = input_len;
if (!shiftdown)
input_sel = input_cur;
return true;
}
// At this point we're messing with input
// Clear completion
completion[0] = 0;
@@ -1009,29 +1170,45 @@ boolean CON_Responder(event_t *ev)
// command enter
if (key == KEY_ENTER)
{
if (!input.length)
if (!input_len)
return true;
// push the command
COM_BufAddText(input.buffer);
COM_BufAddText(inputlines[inputline]);
COM_BufAddText("\n");
CONS_Printf("\x86""%c""\x80""%s\n", CON_PROMPTCHAR, inputlines[inputline]);
Lock_state();
// Only add command to history if it differs from previous one
if (strcmp(input.buffer, inputlines[(inputline-1) & 31]))
{
if (strcmp(inputlines[inputline], inputlines[(inputline-1) & 31]))
inputline = (inputline+1) & 31;
M_TextInputInit(&input, inputlines[inputline], CON_MAXPROMPTCHARS);
}
inputhist = inputline;
M_TextInputClear(&input);
CON_InputClear();
Unlock_state();
return true;
}
// backspace and delete command prompt
if (input_sel != input_cur)
{
if (key == KEY_BACKSPACE || key == KEY_DEL)
{
CON_InputDelSelection();
return true;
}
}
else if (key == KEY_BACKSPACE)
{
CON_InputDelChar();
return true;
}
else if (key == KEY_DEL)
{
if (input_cur == input_len)
return true;
++input_cur;
CON_InputDelChar();
return true;
}
@@ -1048,9 +1225,7 @@ boolean CON_Responder(event_t *ev)
if (inputhist == inputline)
inputhist = (inputline + 1) & 31;
Lock_state();
M_TextInputSetString(&input, inputlines[inputhist]);
Unlock_state();
CON_InputSetString(inputlines[inputhist]);
return true;
}
@@ -1064,16 +1239,41 @@ boolean CON_Responder(event_t *ev)
while (inputhist != inputline && !inputlines[inputhist][0]);
// back to currentline
Lock_state();
if (inputhist == inputline)
M_TextInputClear(&input);
CON_InputClear();
else
M_TextInputSetString(&input, inputlines[inputhist]);
Unlock_state();
CON_InputSetString(inputlines[inputhist]);
return true;
}
// allow people to use keypad in console (good for typing IP addresses) - Calum
if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL)
{
char keypad_translation[] = {'7','8','9','-',
'4','5','6','+',
'1','2','3',
'0','.'};
key = keypad_translation[key - KEY_KEYPAD7];
}
else if (key == KEY_KPADSLASH)
key = '/';
// same capslock code as hu_stuff.c's HU_responder. Check there for details.
key = CON_ShiftChar(key);
// enter a char into the command prompt
if (key < 32 || key > 127)
return true;
// add key to cmd line here
if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers
key = key + 'a' - 'A';
if (input_sel != input_cur)
CON_InputDelSelection();
CON_InputAddChar(key);
return true;
}
@@ -1235,7 +1435,7 @@ void CONS_Printf(const char *fmt, ...)
txt = malloc(8192);
va_start(argptr, fmt);
vsnprintf(txt, 8192, fmt, argptr);
vsprintf(txt, fmt, argptr);
va_end(argptr);
// echo console prints to log file
@@ -1243,7 +1443,7 @@ void CONS_Printf(const char *fmt, ...)
if (con_started)
CON_Print(txt);
CON_LogMessage(txt);
Lock_state();
@@ -1321,17 +1521,19 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...)
//
void CONS_Error(const char *msg)
{
#ifdef RPC_NO_WINDOWS_H
if (!graphics_started)
{
MessageBoxA(vid.WndParent, msg, "SRB2Kart Warning", MB_OK);
return;
}
#endif
CONS_Printf("\x82%s", msg); // write error msg in different colour
CONS_Printf(M_GetText("Press ENTER to continue\n"));
// dirty quick hack, but for the good cause
while (I_GetKey() != KEY_ENTER)
{
// Sleep so we don't take too much of cpu usage
I_Sleep(1.f/TICRATE*1000);
I_OsPolling();
}
}
//======================================================================
@@ -1353,16 +1555,16 @@ static void CON_DrawInput(void)
clen = con_width-13;
if (input.length <= clen)
if (input_len <= clen)
{
c = 0;
clen = input.length;
clen = input_len;
}
else // input line scrolls left if it gets too long
{
clen -= 2; // There will always be some extra truncation -- but where is what we'll find out
if (input.cursor <= clen/2)
if (input_cur <= clen/2)
{
// Close enough to right edge to show all
c = 0;
@@ -1373,15 +1575,15 @@ static void CON_DrawInput(void)
{
// Cursor in the middle (or right side) of input
// Move over for the ellipsis
c = input.cursor - (clen/2) + 2;
c = input_cur - (clen/2) + 2;
x += charwidth*2;
lellip = 1;
if (c + clen >= input.length)
if (c + clen >= input_len)
{
// Cursor in the right side of input
// We were too far over, so move back
c = input.length - clen;
c = input_len - clen;
}
else
{
@@ -1395,7 +1597,7 @@ static void CON_DrawInput(void)
if (lellip)
{
x -= charwidth*3;
if (input.select < c)
if (input_sel < c)
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART);
for (i = 0; i < 3; ++i, x += charwidth)
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
@@ -1405,7 +1607,7 @@ static void CON_DrawInput(void)
for (cend = c + clen; c < cend; ++c, x += charwidth)
{
if ((input.select > c && input.cursor <= c) || (input.select <= c && input.cursor > c))
if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c))
{
V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 107 | V_NOSCALESTART);
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value);
@@ -1413,14 +1615,14 @@ static void CON_DrawInput(void)
else
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
if (c == input.cursor && con_tick >= 4)
if (c == input_cur && con_tick >= 4)
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
if (cend == input.cursor && con_tick >= 4)
if (cend == input_cur && con_tick >= 4)
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
if (rellip)
{
if (input.select > cend)
if (input_sel > cend)
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART);
for (i = 0; i < 3; ++i, x += charwidth)
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
@@ -1463,15 +1665,12 @@ static void CON_DrawHudlines(void)
{
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
c++;
}
if (c >= con_width)
break;
if (*p < HU_FONTSTART)
;//charwidth = 4 * con_scalefactor;
else
{
//charwidth = hu_font['A'-HU_FONTSTART]->width * con_scalefactor;
//charwidth = SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
}
@@ -1506,7 +1705,7 @@ static void CON_DrawConsole(void)
// draw console background
if (cons_backpic.value || con_forcepic)
{
patch_t *con_backpic = W_CachePatchName("KARTKREW", PU_PATCH_LOWPRIORITY);
patch_t *con_backpic = W_CachePatchName("KARTKREW", PU_CACHE);
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
V_DrawFixedPatch(0, 0, FRACUNIT/2, 0, con_backpic, NULL);
@@ -1546,10 +1745,7 @@ static void CON_DrawConsole(void)
{
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
c++;
}
if (c >= con_width)
break;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
}
@@ -1574,11 +1770,11 @@ void CON_Drawer(void)
if (con_recalc)
{
CON_RecalcSize();
if (con_curlines <= 0)
CON_ClearHUD();
}
// console movement
if (con_curlines != con_destlines)
CON_MoveConsole();
-1
View File
@@ -1 +0,0 @@
target_sourcefile(cpp)
-2
View File
@@ -1,2 +0,0 @@
memory.cpp
thread_pool.cpp
-71
View File
@@ -1,71 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#include "memory.h"
#include <array>
#include <new>
#include "../z_zone.h"
namespace
{
class LinearMemory
{
size_t size_;
size_t height_;
void* memory_;
public:
constexpr explicit LinearMemory(size_t size) noexcept;
void* allocate(size_t size);
void reset() noexcept;
};
constexpr LinearMemory::LinearMemory(size_t size) noexcept : size_(size), height_{0}, memory_{nullptr} {}
void* LinearMemory::allocate(size_t size)
{
size_t aligned_size = (size + 15) & ~15;
if (height_ + aligned_size > size_)
{
throw std::bad_alloc();
}
if (memory_ == nullptr)
{
memory_ = Z_Malloc(size_, PU_STATIC, nullptr);
}
void* ptr = (void*)((uintptr_t)(memory_) + height_);
height_ += aligned_size;
return ptr;
}
void LinearMemory::reset() noexcept
{
height_ = 0;
}
} // namespace
static LinearMemory g_frame_memory {4 * 1024 * 1024};
void* Z_Frame_Alloc(size_t size)
{
return g_frame_memory.allocate(size);
}
void Z_Frame_Reset()
{
g_frame_memory.reset();
}
-32
View File
@@ -1,32 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef __SRB2_CORE_MEMORY_H__
#define __SRB2_CORE_MEMORY_H__
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif // __cpluspplus
/// @brief Allocate a block of memory with a lifespan of the current main-thread frame.
/// This function is NOT thread-safe, but the allocated memory may be used across threads.
/// @return a pointer to a block of memory aligned with libc malloc alignment, or null if allocation fails
void* Z_Frame_Alloc(size_t size);
/// @brief Resets per-frame memory. Not thread safe.
void Z_Frame_Reset(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // __SRB2_CORE_MEMORY_H__
-192
View File
@@ -1,192 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
// This class is derived from Conor Williams' implementation of a concurrent deque
// https://github.com/ConorWilliams/ConcurrentDeque
// Copyright (C) 2021 Conor Williams
// The original version was for C++23. This one has been shrunk slightly and adapted to our conventions.
#ifndef __SRB2_CORE_SPMC_QUEUE_HPP__
#define __SRB2_CORE_SPMC_QUEUE_HPP__
#include <array>
#include <atomic>
#include <cstddef>
#include <memory>
#include <optional>
//#include <tracy/tracy/Tracy.hpp>
#include "../cxxutil.hpp"
namespace srb2
{
template <typename T>
class SpMcQueue
{
struct RingBuff {
public:
explicit RingBuff(int64_t cap) : _cap{cap}, _mask{cap - 1}
{
SRB2_ASSERT(cap && (!(cap & (cap - 1))) && "Capacity must be buf power of 2!");
_buff = std::unique_ptr<T[]>(new T[_cap]);
}
std::int64_t capacity() const noexcept { return _cap; }
// Store (copy) at modulo index
void store(int64_t i, T&& x) noexcept
{
_buff[i & _mask] = std::move(x);
}
// Load (copy) at modulo index
T load(int64_t i) const noexcept
{
return _buff[i & _mask];
}
// Allocates and returns a new ring buffer, copies elements in range [b, t) into the new buffer.
RingBuff* resize(std::int64_t b, std::int64_t t) const
{
//ZoneScoped;
RingBuff* ptr = new RingBuff{2 * _cap};
for (std::int64_t i = t; i != b; ++i) {
ptr->store(i, load(i));
}
return ptr;
}
private:
int64_t _cap; // Capacity of the buffer
int64_t _mask; // Bit mask to perform modulo capacity operations
std::unique_ptr<T[]> _buff;
};
alignas(64) std::atomic<int64_t> bottom_;
alignas(64) std::atomic<int64_t> top_;
alignas(64) std::atomic<RingBuff*> buffer_;
std::vector<std::unique_ptr<RingBuff>> garbage_;
public:
SpMcQueue(size_t capacity) : bottom_(0), top_(0), buffer_(new RingBuff(capacity))
{
garbage_.reserve(32);
}
~SpMcQueue() noexcept
{
delete buffer_.load(std::memory_order_relaxed);
};
size_t size() const noexcept
{
int64_t bottom = bottom_.load(std::memory_order_relaxed);
int64_t top = top_.load(std::memory_order_relaxed);
return static_cast<size_t>(bottom >= top ? bottom - top : 0);
}
bool empty() const noexcept
{
return size() == 0;
}
void push(T&& v) noexcept
{
int64_t bottom = bottom_.load(std::memory_order_relaxed);
int64_t top = top_.load(std::memory_order_acquire);
RingBuff* buf = buffer_.load(std::memory_order_relaxed);
if (buf->capacity() < (bottom - top) + 1)
{
// Queue is full, build a new one
RingBuff* newbuf = buf->resize(bottom, top);
garbage_.emplace_back(buf);
buffer_.store(newbuf, std::memory_order_relaxed);
buf = newbuf;
}
// Construct new object, this does not have to be atomic as no one can steal this item until after we
// store the new value of bottom, ordering is maintained by surrounding atomics.
buf->store(bottom, std::move(v));
std::atomic_thread_fence(std::memory_order_release);
bottom_.store(bottom + 1, std::memory_order_relaxed);
}
std::optional<T> pop() noexcept
{
int64_t bottom = bottom_.load(std::memory_order_relaxed) - 1;
RingBuff* buf = buffer_.load(std::memory_order_relaxed);
bottom_.store(bottom, std::memory_order_relaxed); // Stealers can no longer steal
std::atomic_thread_fence(std::memory_order_seq_cst);
int64_t top = top_.load(std::memory_order_relaxed);
if (top <= bottom)
{
// Non-empty deque
if (top == bottom)
{
// The last item could get stolen, by a stealer that loaded bottom before our write above
if (!top_.compare_exchange_strong(top, top + 1, std::memory_order_seq_cst, std::memory_order_relaxed))
{
// Failed race, thief got the last item.
bottom_.store(bottom + 1, std::memory_order_relaxed);
return std::nullopt;
}
bottom_.store(bottom + 1, std::memory_order_relaxed);
}
// Can delay load until after acquiring slot as only this thread can push(), this load is not
// required to be atomic as we are the exclusive writer.
return buf->load(bottom);
}
else
{
bottom_.store(bottom + 1, std::memory_order_relaxed);
return std::nullopt;
}
}
std::optional<T> steal() noexcept
{
int64_t top = top_.load(std::memory_order_acquire);
std::atomic_thread_fence(std::memory_order_seq_cst);
int64_t bottom = bottom_.load(std::memory_order_acquire);
if (top < bottom)
{
// Must load *before* acquiring the slot as slot may be overwritten immediately after acquiring.
// This load is NOT required to be atomic even-though it may race with an overrite as we only
// return the value if we win the race below garanteeing we had no race during our read. If we
// loose the race then 'x' could be corrupt due to read-during-write race but as T is trivially
// destructible this does not matter.
T x = buffer_.load(std::memory_order_consume)->load(top);
if (!top_.compare_exchange_strong(top, top + 1, std::memory_order_seq_cst, std::memory_order_relaxed))
{
return std::nullopt;
}
return x;
}
else
{
return std::nullopt;
}
}
};
} // namespace srb2
#endif // __SRB2_CORE_SPMC_QUEUE_HPP__
-255
View File
@@ -1,255 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef __SRB2_CORE_STATIC_VEC_HPP__
#define __SRB2_CORE_STATIC_VEC_HPP__
#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <iterator>
#include <stdexcept>
#include <type_traits>
#include "../cxxutil.hpp"
namespace srb2
{
template <typename T, size_t Limit>
class StaticVec;
template <typename T, size_t Limit>
class StaticVec
{
std::array<T, Limit> arr_ {{}};
size_t size_ = 0;
public:
using value_type = T;
constexpr StaticVec() {}
StaticVec(const StaticVec& rhs)
{
for (size_t i = size_; i > 0; i--)
{
arr_[i] = T();
}
size_ = rhs.size();
for (size_t i = 0; i < size_; i++)
{
arr_[i] = rhs.arr_[i];
}
}
StaticVec(StaticVec&& rhs) noexcept(std::is_nothrow_move_assignable_v<T>)
{
for (size_t i = size_; i > 0; i--)
{
arr_[i] = T();
}
size_ = rhs.size();
for (size_t i = 0; i < size_; i++)
{
arr_[i] = std::move(rhs.arr_[i]);
}
while (rhs.size() > 0)
{
rhs.pop_back();
}
}
constexpr StaticVec(std::initializer_list<T> list) noexcept(std::is_nothrow_move_assignable_v<T>)
{
size_ = list.size();
size_t i = 0;
for (auto itr = list.begin(); itr != list.end(); itr++)
{
arr_[i] = *itr;
i++;
}
}
~StaticVec() = default;
StaticVec& operator=(const StaticVec& rhs)
{
for (size_t i = size_; i > 0; i--)
{
arr_[i] = T();
}
size_ = rhs.size();
for (size_t i = 0; i < size_; i++)
{
arr_[i] = rhs.arr_[i];
}
return *this;
}
StaticVec& operator=(StaticVec&& rhs) noexcept(std::is_nothrow_move_constructible_v<T>)
{
for (size_t i = size_; i > 0; i--)
{
arr_[i] = T();
}
size_ = rhs.size();
for (size_t i = 0; i < size_; i++)
{
arr_[i] = std::move(rhs.arr_[i]);
}
while (rhs.size() > 0)
{
rhs.pop_back();
}
return *this;
}
void push_back(const T& value) { arr_[size_++] = value; }
void pop_back() { arr_[--size_] = T(); }
void resize(size_t size, T value = T())
{
if (size >= Limit)
{
throw std::length_error("new size >= Capacity");
}
if (size == size_)
{
return;
}
else if (size < size_)
{
while (size_ > size)
{
pop_back();
}
}
else
{
while (size_ < size)
{
push_back(value);
}
}
}
void clear()
{
arr_ = {{}};
size_ = 0;
}
using iterator = typename std::array<T, Limit>::iterator;
using const_iterator = typename std::array<T, Limit>::const_iterator;
constexpr iterator begin() noexcept { return arr_.begin(); }
constexpr const_iterator begin() const noexcept { return arr_.cbegin(); }
constexpr const_iterator cbegin() const noexcept { return arr_.cbegin(); }
constexpr iterator end() noexcept { return std::next(arr_.begin(), size_); }
constexpr const_iterator end() const noexcept { return cend(); }
constexpr const_iterator cend() const noexcept { return std::next(arr_.cbegin(), size_); }
constexpr std::reverse_iterator<iterator> rbegin() noexcept { return std::reverse_iterator(this->end()); }
constexpr std::reverse_iterator<const_iterator> crbegin() const noexcept { return std::reverse_iterator(this->cend()); }
constexpr std::reverse_iterator<iterator> rend() noexcept { return std::reverse_iterator(this->begin()); }
constexpr std::reverse_iterator<const_iterator> crend() const noexcept { return std::reverse_iterator(this->cbegin()); }
constexpr bool empty() const noexcept { return size_ == 0; }
constexpr size_t size() const noexcept { return size_; }
constexpr size_t capacity() const noexcept { return Limit; }
constexpr size_t max_size() const noexcept { return Limit; }
constexpr T& operator[](size_t index) noexcept { return arr_[index]; }
T& at(size_t index)
{
if (index >= size_)
{
throw std::out_of_range("index >= size");
}
return this[index];
}
constexpr const T& operator[](size_t index) const noexcept { return arr_[index]; }
const T& at(size_t index) const
{
if (index >= size_)
{
throw std::out_of_range("index >= size");
}
return this[index];
}
T& front() { return *arr_[0]; }
T& back() { return *arr_[size_ - 1]; }
};
} // namespace srb2
template <typename T, size_t L1, size_t L2>
bool operator==(const srb2::StaticVec<T, L1>& lhs, const srb2::StaticVec<T, L2>& rhs)
{
const size_t size = lhs.size();
if (size != rhs.size())
{
return false;
}
for (size_t i = 0; i < lhs; i++)
{
if (rhs[i] != lhs[i])
{
return false;
}
}
return true;
}
template <typename T, size_t L1, size_t L2>
bool operator!=(const srb2::StaticVec<T, L1>& lhs, const srb2::StaticVec<T, L2>& rhs)
{
return !(lhs == rhs);
}
template <typename T, size_t Limit>
struct std::hash<srb2::StaticVec<T, Limit>>
{
size_t operator()(const srb2::StaticVec<T, Limit>& input) const
{
constexpr size_t prime = sizeof(size_t) == 8 ? 0x00000100000001B3 : 0x01000193;
constexpr size_t basis = sizeof(size_t) == 8 ? 0xcbf29ce484222325 : 0x811c9dc5;
size_t ret = basis;
for (auto itr = input.begin(); itr != input.end(); itr++)
{
ret = (ret * prime) ^ std::hash<T>(*itr);
}
return ret;
}
};
#endif // __SRB2_CORE_STATIC_VEC_HPP__
-346
View File
@@ -1,346 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#include "thread_pool.h"
#include <algorithm>
#include <condition_variable>
#include <exception>
#include <mutex>
#include <string>
#include <system_error>
//#include <fmt/format.h>
//#include <tracy/tracy/Tracy.hpp>
#include "../cxxutil.hpp"
#include "../m_argv.h"
using namespace srb2;
static void do_work(ThreadPool::Task& work)
{
try
{
//ZoneScoped;
(work.thunk)(work.raw.data());
}
catch (...)
{
// can't do anything
}
(work.deleter)(work.raw.data());
if (work.pseudosema)
{
work.pseudosema->fetch_sub(1, std::memory_order_relaxed);
}
}
static void pool_executor(
//int thread_index,
std::shared_ptr<std::atomic<bool>> pool_alive,
std::shared_ptr<std::mutex> worker_ready_mutex,
std::shared_ptr<std::condition_variable> worker_ready_condvar,
std::shared_ptr<ThreadPool::Queue> my_wq,
std::vector<std::shared_ptr<ThreadPool::Queue>> other_wqs
)
{
{
//std::string thread_name = fmt::format("Thread Pool Thread {}", thread_index);
//tracy::SetThreadName(thread_name.c_str());
}
int spins = 0;
while (true)
{
std::optional<ThreadPool::Task> work = my_wq->steal();
bool did_work = false;
if (work)
{
do_work(*work);
did_work = true;
spins = 0;
}
else
{
for (auto& q : other_wqs)
{
work = q->steal();
if (work)
{
do_work(*work);
did_work = true;
spins = 0;
// We only want to steal one work item at a time, to prioritize our own queue
break;
}
}
}
if (!did_work)
{
// Spin a few loops to avoid yielding, then wait for the ready lock
spins += 1;
if (spins > 100)
{
std::unique_lock<std::mutex> ready_lock {*worker_ready_mutex};
while (my_wq->empty() && pool_alive->load())
{
worker_ready_condvar->wait(ready_lock);
}
if (!pool_alive->load())
{
break;
}
}
}
}
}
ThreadPool::ThreadPool()
{
immediate_mode_ = true;
}
ThreadPool::ThreadPool(size_t threads)
{
next_queue_index_ = 0;
pool_alive_ = std::make_shared<std::atomic<bool>>(true);
for (size_t i = 0; i < threads; i++)
{
std::shared_ptr<Queue> wsq = std::make_shared<Queue>(2048);
work_queues_.push_back(wsq);
std::shared_ptr<std::mutex> mutex = std::make_shared<std::mutex>();
worker_ready_mutexes_.push_back(std::move(mutex));
std::shared_ptr<std::condition_variable> condvar = std::make_shared<std::condition_variable>();
worker_ready_condvars_.push_back(std::move(condvar));
}
for (size_t i = 0; i < threads; i++)
{
std::shared_ptr<Queue> my_queue = work_queues_[i];
std::vector<std::shared_ptr<Queue>> other_queues;
for (size_t j = 0; j < threads; j++)
{
// Order the other queues starting from the next adjacent worker
// i.e. if this is worker 2 of 8, then other queues is 3, 4, 5, 6, 7, 0, 1
// This tries to balance out work stealing behavior
size_t other_index = j + i;
if (other_index >= threads)
{
other_index -= threads;
}
if (other_index != i)
{
other_queues.push_back(work_queues_[other_index]);
}
}
std::thread thread;
try
{
thread = std::thread
{
pool_executor,
//i,
pool_alive_,
worker_ready_mutexes_[i],
worker_ready_condvars_[i],
my_queue,
other_queues
};
}
catch (const std::system_error& error)
{
// Safe shutdown and rethrow
pool_alive_->store(false);
for (auto& t : threads_)
{
t.join();
}
throw error;
}
threads_.push_back(std::move(thread));
}
}
ThreadPool::ThreadPool(ThreadPool&&) = default;
ThreadPool::~ThreadPool() = default;
ThreadPool& ThreadPool::operator=(ThreadPool&&) = default;
void ThreadPool::begin_sema()
{
sema_begun_ = true;
}
ThreadPool::Sema ThreadPool::end_sema()
{
Sema ret = Sema(std::move(cur_sema_));
cur_sema_ = nullptr;
sema_begun_ = false;
return ret;
}
void ThreadPool::notify()
{
for (size_t i = 0; i < work_queues_.size(); i++)
{
auto& q = work_queues_[i];
size_t count = q->size();
if (count > 0)
{
worker_ready_condvars_[i]->notify_one();
}
}
}
void ThreadPool::notify_sema(const ThreadPool::Sema& sema)
{
if (!sema.pseudosema_)
{
return;
}
notify();
}
void ThreadPool::wait_idle()
{
if (immediate_mode_)
{
return;
}
//ZoneScoped;
for (size_t i = 0; i < work_queues_.size(); i++)
{
auto& q = work_queues_[i];
std::optional<Task> work;
while ((work = q->pop()).has_value())
{
do_work(*work);
}
}
}
void ThreadPool::wait_sema(const Sema& sema)
{
if (!sema.pseudosema_)
{
return;
}
//ZoneScoped;
while (sema.pseudosema_->load(std::memory_order_seq_cst) > 0)
{
// spin to win
for (size_t i = 0; i < work_queues_.size(); i++)
{
auto& q = work_queues_[i];
std::optional<Task> work;
if ((work = q->pop()).has_value())
{
do_work(*work);
break;
}
}
}
if (sema.pseudosema_->load(std::memory_order_seq_cst) != 0)
{
throw std::exception();
}
}
void ThreadPool::shutdown()
{
if (immediate_mode_)
{
return;
}
wait_idle();
pool_alive_->store(false);
for (auto& condvar : worker_ready_condvars_)
{
condvar->notify_all();
}
for (auto& t : threads_)
{
t.join();
}
}
std::unique_ptr<ThreadPool> srb2::g_main_threadpool;
void I_ThreadPoolInit(void)
{
SRB2_ASSERT(g_main_threadpool == nullptr);
size_t thread_count = std::min(static_cast<unsigned int>(9), std::thread::hardware_concurrency());
if (thread_count > 1)
{
// The main thread will act as a worker when waiting for pool idle
// Make one less worker thread to avoid unnecessary context switching
thread_count -= 1;
}
if (M_CheckParm("-singlethreaded"))
{
g_main_threadpool = std::make_unique<ThreadPool>();
}
else
{
g_main_threadpool = std::make_unique<ThreadPool>(thread_count);
}
}
void I_ThreadPoolShutdown(void)
{
if (!g_main_threadpool)
{
return;
}
g_main_threadpool->shutdown();
g_main_threadpool = nullptr;
}
void I_ThreadPoolSubmit(srb2cthunk_t thunk, void* data)
{
SRB2_ASSERT(g_main_threadpool != nullptr);
g_main_threadpool->schedule([=]() {
(thunk)(data);
});
g_main_threadpool->notify();
}
void I_ThreadPoolWaitIdle(void)
{
SRB2_ASSERT(g_main_threadpool != nullptr);
g_main_threadpool->wait_idle();
}
-163
View File
@@ -1,163 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef __SRB2_CORE_THREAD_POOL_H__
#define __SRB2_CORE_THREAD_POOL_H__
#include <stddef.h>
#ifdef __cplusplus
#include <condition_variable>
#include <cstddef>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
#include <utility>
#include <vector>
#include "spmc_queue.hpp"
namespace srb2
{
class ThreadPool
{
public:
struct Task
{
void (*thunk)(void*);
void (*deleter)(void*);
std::shared_ptr<std::atomic<uint32_t>> pseudosema;
std::array<std::byte, 512 - sizeof(void(*)(void*)) * 2 - sizeof(std::shared_ptr<std::atomic<uint32_t>>)> raw;
};
using Queue = SpMcQueue<Task>;
class Sema
{
std::shared_ptr<std::atomic<uint32_t>> pseudosema_;
explicit Sema(std::shared_ptr<std::atomic<uint32_t>> sema) : pseudosema_(sema) {}
friend class ThreadPool;
public:
Sema() = default;
};
private:
std::shared_ptr<std::atomic<bool>> pool_alive_;
std::vector<std::shared_ptr<std::mutex>> worker_ready_mutexes_;
std::vector<std::shared_ptr<std::condition_variable>> worker_ready_condvars_;
std::vector<std::shared_ptr<Queue>> work_queues_;
std::vector<std::thread> threads_;
size_t next_queue_index_ = 0;
std::shared_ptr<std::atomic<uint32_t>> cur_sema_;
bool immediate_mode_ = false;
bool sema_begun_ = false;
public:
ThreadPool();
explicit ThreadPool(size_t threads);
ThreadPool(const ThreadPool&) = delete;
ThreadPool(ThreadPool&&);
~ThreadPool();
ThreadPool& operator=(const ThreadPool&) = delete;
ThreadPool& operator=(ThreadPool&&);
void begin_sema();
ThreadPool::Sema end_sema();
/// Enqueue but don't notify
template <typename T> void schedule(T&& thunk);
/// Notify threads after several schedules
void notify();
void notify_sema(const Sema& sema);
void wait_idle();
void wait_sema(const Sema& sema);
void shutdown();
};
extern std::unique_ptr<ThreadPool> g_main_threadpool;
template <typename F>
void callable_caller(F* f)
{
(*f)();
}
template <typename F>
void callable_destroyer(F* f)
{
f->~F();
}
template <typename T>
void ThreadPool::schedule(T&& thunk)
{
static_assert(sizeof(T) <= sizeof(std::declval<Task>().raw));
if (immediate_mode_)
{
(thunk)();
return;
}
if (sema_begun_)
{
if (cur_sema_ == nullptr)
{
cur_sema_ = std::make_shared<std::atomic<uint32_t>>(0);
}
cur_sema_->fetch_add(1, std::memory_order_relaxed);
}
size_t qi = next_queue_index_;
{
std::shared_ptr<Queue> q = work_queues_[qi];
Task task;
task.thunk = reinterpret_cast<void(*)(void*)>(callable_caller<T>);
task.deleter = reinterpret_cast<void(*)(void*)>(callable_destroyer<T>);
task.pseudosema = cur_sema_;
new (reinterpret_cast<T*>(task.raw.data())) T(std::move(thunk));
q->push(std::move(task));
}
// worker_ready_condvars_[qi]->notify_one();
next_queue_index_ += 1;
if (next_queue_index_ >= threads_.size())
{
next_queue_index_ = 0;
}
}
} // namespace srb2
extern "C" {
#endif // __cplusplus
typedef void (*srb2cthunk_t)(void*);
void I_ThreadPoolInit(void);
void I_ThreadPoolShutdown(void);
void I_ThreadPoolSubmit(srb2cthunk_t thunk, void* data);
void I_ThreadPoolWaitIdle(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __SRB2_CORE_THREAD_POOL_H__
-152
View File
@@ -1,152 +0,0 @@
#ifndef __SRB2_CXXUTIL_HPP__
#define __SRB2_CXXUTIL_HPP__
#include <cstdlib>
#include <type_traits>
#include <utility>
#include "doomdef.h"
namespace srb2 {
template <class F>
class Finally {
public:
explicit Finally(const F& f) noexcept : f_(f) {}
explicit Finally(F&& f) noexcept : f_(f) {}
Finally(Finally&& from) noexcept : f_(std::move(from.f_)), call_(std::exchange(from.call_, false)) {}
Finally(const Finally& from) = delete;
void operator=(const Finally& from) = delete;
void operator=(Finally&& from) = delete;
~Finally() noexcept {
if (call_)
f_();
}
private:
F f_;
bool call_ = true;
};
template <class F>
Finally<std::decay_t<F>> finally(F&& f) noexcept {
return Finally {std::forward<F>(f)};
}
struct SourceLocation {
const char* file_name;
unsigned int line_number;
};
#define SRB2_SOURCE_LOCATION \
srb2::SourceLocation { __FILE__, __LINE__ }
#ifndef SRB2_ASSERT_HANDLER
#define SRB2_ASSERT_HANDLER srb2::IErrorAssertHandler
#endif
#if !defined(NDEBUG) || defined(PARANOIA)
// An assertion level of 2 will activate all invocations of the SRB2_ASSERT macro
#define SRB2_ASSERTION_LEVEL 2
#else
// The minimum assertion level is 1
#define SRB2_ASSERTION_LEVEL 1
#endif
/// Assert a precondition expression in debug builds.
#define SRB2_ASSERT(expr) srb2::do_assert<2, SRB2_ASSERT_HANDLER>([&] { return (expr); }, SRB2_SOURCE_LOCATION, #expr)
class IErrorAssertHandler {
public:
static void handle(const SourceLocation& source_location, const char* expression) {
I_Error("Assertion failed at %s:%u: %s != true",
source_location.file_name,
source_location.line_number,
expression);
}
};
class NoOpAssertHandler {
public:
static void handle(const SourceLocation& source_location, const char* expression) {(void)source_location; (void)expression;}
};
/// @brief Assert a precondition expression, aborting the application if it fails.
/// @tparam Expr
/// @tparam Level the level of this assertion; if it is less than or equal to SRB2_ASSERTION_LEVEL, this overload will
/// activate.
/// @param expr a callable which returns a bool
/// @param source_location a struct containing the source location of the assertion, e.g. SRB2_SOURCE_LOCATION
/// @param expression the expression evaluated in the expression callable
/// @param message an optional message to display for the assertion
template <unsigned int Level, class Handler, class Expr>
std::enable_if_t<(Level <= SRB2_ASSERTION_LEVEL), void>
do_assert(const Expr& expr, const SourceLocation& source_location, const char* expression = "") noexcept {
static_assert(Level > 0, "level of an assertion must not be 0");
if (!expr()) {
Handler::handle(source_location, expression);
std::abort();
}
}
template <unsigned int Level, class, class Expr>
std::enable_if_t<(Level > SRB2_ASSERTION_LEVEL), void>
do_assert(const Expr&, const SourceLocation&, const char* = "") noexcept {
}
template <typename T>
class NotNull final {
T ptr_;
public:
static_assert(std::is_convertible_v<decltype(std::declval<T>() != nullptr), bool>,
"T is not comparable with nullptr_t");
/// @brief Move-construct from the pointer value U, asserting that it is not null. Allows construction of a
/// NotNull<T> from any compatible pointer U, for example with polymorphic classes.
template <typename U, typename = std::enable_if_t<std::is_convertible_v<U, T>>>
constexpr NotNull(U&& rhs) : ptr_(std::forward<U>(rhs)) {
SRB2_ASSERT(ptr_ != nullptr);
}
/// @brief Wrap the pointer type T, asserting that the pointer is not null.
template <typename = std::enable_if_t<!std::is_same_v<std::nullptr_t, T>>>
constexpr NotNull(T rhs) : ptr_(std::move(rhs)) {
SRB2_ASSERT(ptr_ != nullptr);
}
/// @brief Copy construction from NotNull of convertible type U. Only if the incoming pointer is NotNull already.
template <typename U, typename = std::enable_if_t<std::is_convertible_v<U, T>>>
constexpr NotNull(const NotNull<U>& rhs) : NotNull(rhs.get()) {
// Value is guaranteed to be not null by construction; no assertion necessary
}
NotNull(const NotNull& rhs) = default;
NotNull& operator=(const NotNull& rhs) = default;
/// @brief Get the stored pointer.
constexpr T get() const { return ptr_; }
/// @brief Convert to T (the pointer type).
constexpr operator T() const { return get(); }
/// @brief Arrow-dereference to *T (the actual value pointed to).
constexpr decltype(auto) operator->() const { return get(); }
/// @brief Dereference to *T (the actual value pointed to).
constexpr decltype(auto) operator*() const { return *get(); }
// It is not allowed to construct NotNull<T> with nullptr regardless of T.
NotNull(std::nullptr_t) = delete;
NotNull& operator=(std::nullptr_t) = delete;
};
template <class T>
NotNull(T) -> NotNull<T>;
} // namespace srb2
#endif // __SRB2_CXXUTIL_HPP__
+653 -1191
View File
File diff suppressed because it is too large. Load diff
+8 -63
View File
@@ -13,10 +13,6 @@
#ifndef __D_CLISRV__
#define __D_CLISRV__
#ifdef __cplusplus
extern "C" {
#endif
#include "d_ticcmd.h"
#include "d_net.h"
#include "d_netcmd.h"
@@ -45,15 +41,6 @@ applications may follow different packet versions.
#define BACKUPTICS 32
#define TICQUEUE 512 // more than enough for most timeouts....
#define MAXTEXTCMD 256
// No. of tics your controls can be delayed by.
// TODO: Instead of storing a ton of extra cmds for gentlemens' delay,
// keep them in a linked-list, with timestamps to discard everything that's older than already sent.
// That will support any amount of lag, and be less wasteful for clients who don't use it.
// This just works as a quick implementation.
#define MAXGENTLEMENDELAY TICRATE
//
// Packet structure
//
@@ -111,15 +98,6 @@ typedef enum
PT_MOREFILESNEEDED, // Server, to client: "you need these (+ more on top of those)"
PT_PING, // Packet sent to tell clients the other client's latency to server.
#ifdef SATURNPAK
PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate!
PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead.
PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again!
PT_ISSATURN, // Saturn specific identifier packet
#endif
NUMPACKETTYPE
} packettype_t;
@@ -385,9 +363,6 @@ typedef struct
UINT8 subversion; // Contains build version
UINT8 localplayers; // number of splitscreen players
UINT8 mode;
#ifdef SATURNJOIN
UINT8 issaturn;
#endif
} ATTRPACK clientconfig_pak;
#define SV_SPEEDMASK 0x03 // used to send kartspeed
@@ -397,7 +372,6 @@ typedef struct
#define MAXSERVERNAME 32
#define MAXFILENEEDED 915
#define MAX_MIRROR_LENGTH 256
// This packet is too large
typedef struct
{
@@ -581,9 +555,6 @@ extern boolean acceptnewnode;
extern SINT8 servernode;
extern char connectedservername[MAXSERVERNAME+1];
extern plrinfo playerinfo[MAXPLAYERS];
extern SINT8 joinnode;
void Command_Ping_f(void);
extern tic_t connectiontimeout;
extern tic_t jointimeout;
@@ -592,40 +563,26 @@ extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
extern boolean server_lagless;
extern tic_t simulated_lag;
extern tic_t lowest_lag;
extern consvar_t cv_mindelay, cv_gentlemens;
extern consvar_t
#ifdef VANILLAJOINNEXTROUND
cv_joinnextround,
#endif
cv_netticbuffer, cv_allownewplayer,
#ifdef SATURNJOIN
cv_allownewsaturnplayer,
#endif
cv_joinrefusemessage, cv_maxplayers, cv_resynchattempts,
#ifdef SATURNPAK
cv_resynchcooldown, cv_gamestateattempts,
#endif
cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
cv_netticbuffer, cv_allownewplayer, cv_joinrefusemessage, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
extern consvar_t cv_connectawaittime;
extern consvar_t cv_discordinvites;
extern consvar_t cv_serverinfoscreen;
// Used in d_net, the only dependence
//tic_t ExpandTics(INT32 low, tic_t basetic);
tic_t ExpandTics(INT32 low, tic_t basetic);
void D_ClientServerInit(void);
// Initialise the other field
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
void SendNetXCmdForPlayer(UINT8 playerid, netxcmd_t id, const void *param, size_t nparam);
#define SendNetXCmd(id, param, nparam) SendNetXCmdForPlayer(0, id, param, nparam) // Shortcut for P1
void SendKick(UINT8 playernum, UINT8 msg);
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam);
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player
void SendNetXCmd3(netxcmd_t id, const void *param, size_t nparam); // splitsreen3 player
void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam); // splitsreen4 player
// Create any new ticcmds and broadcast to other players.
void NetKeepAlive(void);
@@ -644,9 +601,6 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason);
void CL_QueryServerList(msg_server_t *list);
void CL_UpdateServerList(void);
void CL_TimeoutServerList(void);
void CL_AbortConnection(void);
// Is there a game running
boolean Playing(void);
@@ -672,17 +626,13 @@ extern char motd[254], server_context[8];
extern UINT8 playernode[MAXPLAYERS];
INT32 D_NumPlayers(void);
void D_ResetTiccmds(void);
tic_t GetLag(INT32 node);
//UINT8 GetFreeXCmdSize(UINT8 playerid);
UINT8 GetFreeXCmdSize(void);
extern UINT8 hu_resynching;
#ifdef SATURNPAK
extern UINT8 hu_redownloadinggamestate;
#endif
extern boolean hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
typedef struct rewind_s {
UINT8 savebuffer[(768*1024)];
@@ -698,9 +648,4 @@ typedef struct rewind_s {
void CL_ClearRewinds(void);
rewind_t *CL_SaveRewindPoint(size_t demopos);
rewind_t *CL_RewindToTime(tic_t time);
#ifdef __cplusplus
} // extern "C"
#endif
#endif
+1
View File
@@ -25,6 +25,7 @@ typedef enum
ev_console,
ev_mouse,
ev_joystick,
ev_mouse2,
ev_joystick2,
ev_joystick3,
ev_joystick4,
+365 -620
View File
File diff suppressed because it is too large. Load diff
+14 -38
View File
@@ -14,61 +14,41 @@
#ifndef __D_MAIN__
#define __D_MAIN__
#ifdef __cplusplus
extern "C" {
#endif
#include "d_event.h"
#include "w_wad.h" // for MAX_WADFILES
extern tic_t rendergametic;
// make sure not to write back the config until it's been correctly loaded
extern boolean loaded_config;
extern tic_t rendergametic;
extern char srb2home[256]; //Alam: My Home
extern boolean usehome; //Alam: which path?
extern const char *pandf; //Alam: how to path?
extern char srb2path[256]; //Alam: SRB2's Home
// extra graphic patches for saturn specific thingies
extern boolean found_extra_kart; // for use in k_kart.c
extern boolean found_extra2_kart; // for use in k_kart.c
extern boolean found_extra3_kart; // for use in k_kart.c
extern boolean xtra_speedo; // extra speedometer check
extern boolean xtra_speedo_clr; // extra speedometer colour check
extern boolean xtra_speedo3; // 80x11 extra speedometer check
extern boolean xtra_speedo_clr3; // 80x11 extra speedometer colour check
extern boolean achi_speedo; // achiiro speedometer check
extern boolean achi_speedo_clr; // extra speedometer colour check
extern boolean dial_speedo; // dial speedometer check
extern boolean dial_speedo_clr; // dial speedometer colour check
extern boolean kartz_speedo; // kartZ speedo
extern boolean kartz_speedo_smol; // kartZ speedo but smol
extern boolean xtra_speedo; // extra speedometer check
extern boolean xtra_speedo_clr; // extra speedometer colour check
extern boolean xtra_speedo3; // 80x11 extra speedometer check
extern boolean xtra_speedo_clr3; // 80x11 extra speedometer colour check
extern boolean achi_speedo; // achiiro speedometer check
extern boolean achi_speedo_clr; // extra speedometer colour check
extern boolean clr_hud; // colour hud check
extern boolean big_lap; // bigger lap counter
extern boolean big_lap_color; // bigger lap counter but colour
extern boolean kartzspeedo; // kartZ speedo
extern boolean statdp; // stat display for extended player setup
extern boolean nametaggfx; // Nametag stuffs
extern boolean driftgaugegfx;
extern boolean clr_hud; // colour hud check
extern boolean driftgaugegfx_clr; // driftgauge colour check
extern boolean big_lap; // bigger lap counter
extern boolean big_lap_color; // bigger lap counter but colour
extern boolean statdp; // stat display for extended player setup
extern boolean nametaggfx; // Nametag stuffs
extern boolean driftgaugegfx; // Driftgauge stuffs
extern boolean multiitem_icon; // Extra icons for Sneakers, Banana and Jawz
extern boolean joystickicon; // Extra icons for the joystick input display
extern boolean minidoticon; // Dot icon for minimap player angle display
extern boolean minilighticon; // mkwii-style minimap headlight
//
// autoload stuff
extern boolean autoloading;
extern boolean autoloaded;
extern boolean postautoloaded;
void D_AddPostloadFiles(void);
extern char *autoloadwadfilespost[MAX_WADFILES];
extern char *autoloadwadfiles[MAX_WADFILES];
// the infinite loop of D_SRB2Loop() called from win_main for windows version
void D_SRB2Loop(void) FUNCNORETURN;
@@ -94,8 +74,4 @@ const char *D_Home(void);
//
void D_StartTitle(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif //__D_MAIN__
+105 -81
View File
@@ -64,11 +64,16 @@ static doomdata_t reboundstore[MAXREBOUND];
static INT16 reboundsize[MAXREBOUND];
static INT32 rebound_head, rebound_tail;
/// \brief bandwith of netgame
INT32 net_bandwidth;
/// \brief max length per packet
INT16 hardware_MAXPACKETLENGTH;
boolean (*I_NetGet)(void) = NULL;
void (*I_NetSend)(void) = NULL;
boolean (*I_NetCanSend)(void) = NULL;
boolean (*I_NetCanGet)(void) = NULL;
void (*I_NetCloseSocket)(void) = NULL;
void (*I_NetFreeNodenum)(INT32 nodenum) = NULL;
SINT8 (*I_NetMakeNodewPort)(const char *address, const char* port) = NULL;
@@ -109,24 +114,20 @@ boolean Net_GetNetStat(void)
{
const tic_t t = I_GetTime();
static INT64 oldsendbyte = 0;
if (statstarttic+STATLENGTH <= t)
{
const tic_t df = t-statstarttic;
const INT64 newsendbyte = sendbytes - oldsendbyte;
sendbps = (INT32)(newsendbyte*TICRATE)/df;
getbps = (getbytes*TICRATE)/df;
if (sendackpacket)
lostpercent = 100.0f*(float)retransmit/(float)sendackpacket;
else
lostpercent = 0.0f;
if (getackpacket)
duppercent = 100.0f*(float)duppacket/(float)getackpacket;
else
duppercent = 0.0f;
if (ticruned)
gamelostpercent = 100.0f*(float)ticmiss/(float)ticruned;
else
@@ -224,7 +225,7 @@ FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b)
* \param lowtimer ???
* \return True if a free acknum was found
*/
static boolean GetFreeAcknum(UINT8 *freeack)
static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
{
node_t *node = &nodes[doomcom->remotenode];
INT32 i, numfreeslot = 0;
@@ -236,7 +237,6 @@ static boolean GetFreeAcknum(UINT8 *freeack)
}
for (i = 0; i < MAXACKPACKETS; i++)
{
if (!ackpak[i].acknum)
{
// For low priority packets, make sure to let freeslots so urgent packets can be sent
@@ -254,8 +254,17 @@ static boolean GetFreeAcknum(UINT8 *freeack)
node->nextacknum++;
ackpak[i].destinationnode = (UINT8)(node - nodes);
ackpak[i].length = doomcom->datalength;
ackpak[i].senttime = I_GetTime();
ackpak[i].resentnum = 0;
if (lowtimer)
{
// Lowtime means can't be sent now so try it as soon as possible
ackpak[i].senttime = 0;
ackpak[i].resentnum = 1;
}
else
{
ackpak[i].senttime = I_GetTime();
ackpak[i].resentnum = 0;
}
M_Memcpy(ackpak[i].pak.raw, netbuffer, ackpak[i].length);
*freeack = ackpak[i].acknum;
@@ -264,17 +273,46 @@ static boolean GetFreeAcknum(UINT8 *freeack)
return true;
}
}
#ifdef PARANOIA
CONS_Debug(DBG_NETPLAY, "No more free ackpacket\n");
#endif
if (netbuffer->packettype < PT_CANFAIL)
I_Error("Connection lost\n");
return false;
}
/** Counts how many acks are free
*
* \param urgent True if the type of the packet meant to
* use an ack is lower than PT_CANFAIL
* If for some reason you don't want use it
* for any packet type in particular,
* just set to false
* \return The number of free acks
*
*/
INT32 Net_GetFreeAcks(boolean urgent)
{
INT32 i, numfreeslot = 0;
INT32 n = 0; // Number of free acks found
for (i = 0; i < MAXACKPACKETS; i++)
if (!ackpak[i].acknum)
{
// For low priority packets, make sure to let freeslots so urgent packets can be sent
if (!urgent)
{
numfreeslot++;
if (numfreeslot <= URGENTFREESLOTNUM)
continue;
}
n++;
}
return n;
}
// Get a ack to send in the queue of this node
static UINT8 GetAcktosend(INT32 node)
{
@@ -287,7 +325,6 @@ static void RemoveAck(INT32 i)
INT32 node = ackpak[i].destinationnode;
DEBFILE(va("Remove ack %d\n",ackpak[i].acknum));
ackpak[i].acknum = 0;
if (nodes[node].flags & NF_CLOSE)
Net_CloseConnection(node);
}
@@ -303,16 +340,13 @@ static boolean Processackpak(void)
if (netbuffer->ackreturn && cmpack(node->remotefirstack, netbuffer->ackreturn) < 0)
{
node->remotefirstack = netbuffer->ackreturn;
// Search the ackbuffer and free it
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes
&& cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0)
{
RemoveAck(i);
}
}
}
// Received a packet with ack, queue it to send the ack back
@@ -320,7 +354,6 @@ static boolean Processackpak(void)
{
UINT8 ack = netbuffer->ack;
getackpacket++;
if (cmpack(ack, node->firstacktosend) <= 0)
{
DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack));
@@ -331,7 +364,6 @@ static boolean Processackpak(void)
{
// Check if it is not already in the queue
for (i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND)
{
if (node->acktosend[i] == ack)
{
DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack));
@@ -339,14 +371,11 @@ static boolean Processackpak(void)
goodpacket = false; // Discard packet (duplicate)
break;
}
}
if (goodpacket)
{
// Is a good packet so increment the acknowledge number,
// Then search for a "hole" in the queue
UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1);
if (!nextfirstack)
nextfirstack = 1;
@@ -359,11 +388,9 @@ static boolean Processackpak(void)
if (!nextfirstack)
nextfirstack = 1;
hm1 = (UINT8)((node->acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND);
while (change)
{
change = false;
for (i = node->acktosend_tail; i != node->acktosend_head;
i = (i+1) % MAXACKTOSEND)
{
@@ -376,7 +403,6 @@ static boolean Processackpak(void)
nextfirstack = 1;
change = true;
}
if (i == node->acktosend_tail)
{
node->acktosend[node->acktosend_tail] = 0;
@@ -398,7 +424,6 @@ static boolean Processackpak(void)
// Will be incremented when the nextfirstack comes (code above)
UINT8 newhead = (UINT8)((node->acktosend_head+1) % MAXACKTOSEND);
DEBFILE(va("out of order packet (%d expected)\n", nextfirstack));
if (newhead != node->acktosend_tail)
{
node->acktosend[node->acktosend_head] = ack;
@@ -435,11 +460,8 @@ static void GotAcks(void)
INT32 i, j;
for (j = 0; j < MAXACKTOSEND; j++)
{
if (netbuffer->u.textcmd[j])
{
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode)
{
if (ackpak[i].acknum == netbuffer->u.textcmd[j])
@@ -454,9 +476,6 @@ static void GotAcks(void)
ackpak[i].senttime--; // hurry up
}
}
}
}
}
}
#endif
@@ -491,7 +510,6 @@ void Net_AckTicker(void)
{
const INT32 nodei = ackpak[i].destinationnode;
node_t *node = &nodes[nodei];
if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime())
{
if (ackpak[i].resentnum > 10 && (node->flags & NF_CLOSE))
@@ -544,10 +562,8 @@ void Net_UnAcknowledgePacket(INT32 node)
#else
INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND;
DEBFILE(va("UnAcknowledge node %d\n", node));
if (!node)
return;
if (nodes[node].acktosend[hm1] == netbuffer->ack)
{
nodes[node].acktosend[hm1] = 0;
@@ -571,7 +587,6 @@ void Net_UnAcknowledgePacket(INT32 node)
if (!nodes[node].firstacktosend)
nodes[node].firstacktosend = UINT8_MAX;
}
nodes[node].firstacktosend++;
if (!nodes[node].firstacktosend)
nodes[node].firstacktosend = 1;
@@ -590,10 +605,8 @@ static boolean Net_AllAcksReceived(void)
INT32 i;
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum)
return false;
}
return true;
}
@@ -613,7 +626,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
timeout = tictac + timeout*NEWTICRATE;
HGetPacket();
while (timeout > I_GetTime() && !Net_AllAcksReceived())
{
while (tictac == I_GetTime())
@@ -621,7 +633,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
I_Sleep(cv_sleep.value);
I_UpdateTime(cv_timescale.value);
}
tictac = I_GetTime();
HGetPacket();
Net_AckTicker();
@@ -632,7 +643,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
static void InitNode(node_t *node)
{
node->acktosend_head = node->acktosend_tail = 0;
memset(node->acktosend, 0, sizeof(node->acktosend));
node->firstacktosend = 0;
node->nextacknum = 1;
node->remotefirstack = 0;
@@ -662,14 +672,13 @@ void Net_AbortPacketType(UINT8 packettype)
#ifdef NONET
(void)packettype;
#else
for (INT32 i = 0; i < MAXACKPACKETS; i++)
{
INT32 i;
for (i = 0; i < MAXACKPACKETS; i++)
if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype
|| packettype == UINT8_MAX))
{
ackpak[i].acknum = 0;
}
}
#endif
}
@@ -714,7 +723,6 @@ void Net_CloseConnection(INT32 node)
// check if we are waiting for an ack from this node
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum && ackpak[i].destinationnode == node)
{
if (!forceclose)
@@ -722,7 +730,6 @@ void Net_CloseConnection(INT32 node)
else
ackpak[i].acknum = 0;
}
}
InitNode(&nodes[node]);
SV_AbortSendFiles(node);
@@ -739,8 +746,9 @@ static UINT32 NetbufferChecksum(void)
UINT32 c = 0x1234567;
const INT32 l = doomcom->datalength - 4;
const UINT8 *buf = (UINT8 *)netbuffer + 4;
INT32 i;
for (INT32 i = 0; i < l; i++, buf++)
for (i = 0; i < l; i++, buf++)
c += (*buf) * (i+1);
return LONG(c);
@@ -755,7 +763,6 @@ static void fprintfstring(char *s, size_t len)
size_t i;
for (i = 0; i < len; i++)
{
if (s[i] < 32)
{
if (!mode)
@@ -775,8 +782,6 @@ static void fprintfstring(char *s, size_t len)
}
fprintf(debugfile, "%c", s[i]);
}
}
if (mode)
fprintf(debugfile, "]");
}
@@ -788,7 +793,7 @@ static void fprintfstringnewline(char *s, size_t len)
}
/// \warning Keep this up-to-date if you add/remove/rename packet types
const char *packettypename[NUMPACKETTYPE] =
static const char *packettypename[NUMPACKETTYPE] =
{
"NOTHING",
"SERVERCFG",
@@ -831,30 +836,13 @@ const char *packettypename[NUMPACKETTYPE] =
"MOREFILESNEEDED",
"PING"
#ifdef SATURNPAK
,
"WILLRESENDGAMESTATE",
"CANRECEIVEGAMESTATE",
"RECEIVEDGAMESTATE",
"ISSATURN" // special packet to identify saturn clients
#endif
};
const char *Net_GetPacketName(UINT8 packettype)
{
if (packettype >= NUMPACKETTYPE)
return "UNKNOWN";
return packettypename[packettype];
}
static void DebugPrintpacket(const char *header)
{
fprintf(debugfile, "%-12s (node %d,ack %d,ackret %d,size %d) type(%d) : %s\n",
header, doomcom->remotenode, netbuffer->ack, netbuffer->ackreturn, doomcom->datalength,
netbuffer->packettype, Net_GetPacketName(netbuffer->packettype));
netbuffer->packettype, packettypename[netbuffer->packettype]);
switch (netbuffer->packettype)
{
@@ -1033,7 +1021,6 @@ static boolean ShouldDropPacket(void)
boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength)
{
doomcom->datalength = (INT16)(packetlength + BASEPACKETSIZE);
if (node == 0) // Packet is to go back to us
{
if ((rebound_head+1) % MAXREBOUND == rebound_tail)
@@ -1069,7 +1056,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
// do this before GetFreeAcknum because this function backups
// the current packet
doomcom->remotenode = (INT16)node;
if (doomcom->datalength <= 0)
{
DEBFILE("HSendPacket: nothing to send\n");
@@ -1084,10 +1070,17 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
netbuffer->ackreturn = GetAcktosend(node);
else
netbuffer->ackreturn = 0;
if (reliable)
{
if (!GetFreeAcknum(&netbuffer->ack))
if (I_NetCanSend && !I_NetCanSend())
{
if (netbuffer->packettype < PT_CANFAIL)
GetFreeAcknum(&netbuffer->ack, true);
DEBFILE("HSendPacket: Out of bandwidth\n");
return false;
}
else if (!GetFreeAcknum(&netbuffer->ack, false))
return false;
}
else
@@ -1159,6 +1152,7 @@ boolean HGetPacket(void)
while(true)
{
//nodejustjoined = I_NetGet();
I_NetGet();
if (doomcom->remotenode == -1) // No packet received
@@ -1187,6 +1181,21 @@ boolean HGetPacket(void)
DebugPrintpacket("GET");
#endif
/*// If a new node sends an unexpected packet, just ignore it
if (nodejustjoined && server
&& !(netbuffer->packettype == PT_ASKINFO
|| netbuffer->packettype == PT_SERVERINFO
|| netbuffer->packettype == PT_PLAYERINFO
|| netbuffer->packettype == PT_REQUESTFILE
|| netbuffer->packettype == PT_ASKINFOVIAMS
|| netbuffer->packettype == PT_CLIENTJOIN))
{
DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]));
//CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]);
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
continue;
}*/
// Proceed the ack and ackreturn field
if (!Processackpak())
continue; // discarded (duplicated)
@@ -1199,7 +1208,7 @@ boolean HGetPacket(void)
}
break;
}
#endif // ifndef NONET
#endif // ndef NONET
return true;
}
@@ -1223,7 +1232,6 @@ static void Internal_FreeNodenum(INT32 nodenum)
SINT8 I_NetMakeNode(const char *hostname)
{
SINT8 newnode = -1;
if (I_NetMakeNodewPort)
{
char *localhostname = strdup(hostname);
@@ -1272,12 +1280,13 @@ boolean D_CheckNetGame(void)
I_NetGet = Internal_Get;
I_NetSend = Internal_Send;
I_NetCanSend = NULL;
I_NetCloseSocket = NULL;
I_NetFreeNodenum = Internal_FreeNodenum;
I_NetMakeNodewPort = NULL;
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
net_bandwidth = 30000;
// I_InitNetwork sets doomcom and netgame
// check and initialize the network driver
multiplayer = false;
@@ -1308,6 +1317,21 @@ boolean D_CheckNetGame(void)
CONS_Printf(M_GetText("Set extratics to %d\n"), doomcom->extratics);
}
if (M_CheckParm("-bandwidth"))
{
if (M_IsNextParm())
{
net_bandwidth = atoi(M_GetNextParm());
if (net_bandwidth < 1000)
net_bandwidth = 1000;
if (net_bandwidth > 100000)
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
CONS_Printf(M_GetText("Network bandwidth set to %d\n"), net_bandwidth);
}
else
I_Error("usage: -bandwidth <byte_per_sec>");
}
software_MAXPACKETLENGTH = hardware_MAXPACKETLENGTH;
if (M_CheckParm("-packetsize"))
{
@@ -1333,9 +1357,9 @@ boolean D_CheckNetGame(void)
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
netbuffer = (doomdata_t *)(void *)&doomcom->data;
#ifdef HOLEPUNCH
#ifdef HOLEPUNCH
holepunchpacket = (holepunch_t *)(void *)&doomcom->data;
#endif
#endif
#ifdef DEBUGFILE
if (M_CheckParm("-debugfile"))
@@ -1397,7 +1421,6 @@ void Command_Ping_f(void)
INT32 i;
pingc = 0;
for (i = 1; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
@@ -1430,13 +1453,13 @@ void Command_Ping_f(void)
}
}
if (f_width < 10) f_width = 1;
if (f_width < 10) f_width = 1;
else if (f_width < 100) f_width = 2;
else f_width = 3;
else f_width = 3;
if (ms_width < 10) ms_width = 1;
if (ms_width < 10) ms_width = 1;
else if (ms_width < 100) ms_width = 2;
else ms_width = 3;
else ms_width = 3;
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
@@ -1475,6 +1498,7 @@ void D_CloseConnection(void)
I_NetGet = Internal_Get;
I_NetSend = Internal_Send;
I_NetCanSend = NULL;
I_NetCloseSocket = NULL;
I_NetFreeNodenum = Internal_FreeNodenum;
I_NetMakeNodewPort = NULL;
+5 -10
View File
@@ -18,10 +18,6 @@
#ifndef __D_NET__
#define __D_NET__
#ifdef __cplusplus
extern "C" {
#endif
// Max computers in a game
// 127 is probably as high as this can go, because
// SINT8 is used for nodes sometimes >:(
@@ -47,10 +43,14 @@ extern SINT8 nodetoplayer4[MAXNETNODES]; // Say the numplayer for this node if a
extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen
extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game
extern boolean serverrunning;
INT32 Net_GetFreeAcks(boolean urgent);
void Net_AckTicker(void);
// If reliable return true if packet sent, 0 else
boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength);
boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum,
size_t packetlength);
boolean HGetPacket(void);
void D_SetDoomcom(void);
#ifndef NONET
@@ -65,10 +65,5 @@ void Net_ConnectionTimeout(INT32 node);
void Net_AbortPacketType(UINT8 packettype);
void Net_SendAcks(INT32 node);
void Net_WaitAllAckReceived(UINT32 timeout);
const char *Net_GetPacketName(UINT8 packettype);
#ifdef __cplusplus
} // extern "C"
#endif
#endif
+619 -507
View File
File diff suppressed because it is too large. Load diff
+20 -23
View File
@@ -15,17 +15,8 @@
#ifndef __D_NETCMD__
#define __D_NETCMD__
#ifdef __cplusplus
extern "C" {
#endif
#include "command.h"
void SendWeaponPref(void);
void SendWeaponPref2(void);
void SendWeaponPref3(void);
void SendWeaponPref4(void);
// console vars
extern consvar_t cv_playername;
extern consvar_t cv_playercolor;
@@ -52,12 +43,25 @@ extern consvar_t cv_seenames, cv_allowseenames;
extern consvar_t cv_usemouse;
//WTF
extern consvar_t cv_mouseturn;
extern consvar_t cv_usejoystick[4]; //MAXSPLITSCREENPLAYERS
extern consvar_t cv_usejoystick;
extern consvar_t cv_usejoystick2;
extern consvar_t cv_usejoystick3;
extern consvar_t cv_usejoystick4;
#ifdef LJOYSTICK
extern consvar_t cv_joyport;
extern consvar_t cv_joyport2;
#endif
extern consvar_t cv_joyscale[4]; //MAXSPLITSCREENPLAYERS
extern consvar_t cv_joyscale;
extern consvar_t cv_joyscale2;
extern consvar_t cv_joyscale3;
extern consvar_t cv_joyscale4;
// splitscreen with second mouse
extern consvar_t cv_mouse2port;
extern consvar_t cv_usemouse2;
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
extern consvar_t cv_mouse2opt;
#endif
// normally in p_mobj but the .h is not read
extern consvar_t cv_itemrespawntime;
@@ -124,7 +128,6 @@ extern consvar_t cv_kartvoterulechanges;
extern consvar_t cv_kartgametypepreference;
extern consvar_t cv_kartspeedometer;
extern consvar_t cv_kartvoices;
extern consvar_t cv_karthitemdialog;
extern consvar_t cv_karteliminatelast;
@@ -158,12 +161,10 @@ extern consvar_t cv_pingstyle;
//extern consvar_t cv_smallpos;
extern consvar_t cv_showminimapnames;
extern consvar_t cv_minihead;
extern consvar_t cv_showminimapangle;
extern consvar_t cv_showlapemblem;
extern consvar_t cv_showlapemblem;
extern consvar_t cv_showviewpointtext;
extern consvar_t cv_showdownloadprompt;
extern consvar_t cv_luaimmersion;
extern consvar_t cv_fakelocalskin;
extern consvar_t cv_showlocalskinmenus;
@@ -182,7 +183,9 @@ extern consvar_t cv_nametagdist;
extern consvar_t cv_showownnametag;
extern consvar_t cv_smallnametags;
extern consvar_t cv_nametagrestat;
extern consvar_t cv_nametaghop;
extern consvar_t cv_nametagscore;
extern consvar_t cv_shownametagfinish;
extern consvar_t cv_shownametagspectator;
#define SKINSELECTSPIN_PAIN 25
@@ -198,16 +201,12 @@ extern consvar_t cv_ps_thinkframe_page;
extern consvar_t cv_ps_samplesize;
extern consvar_t cv_ps_descriptor;
extern consvar_t cv_director, cv_kartdebugdirector, cv_showdirectorhud;
extern consvar_t cv_showtrackaddon;
extern consvar_t cv_showspecstuff;
extern consvar_t cv_betainterscreen;
extern consvar_t cv_laglesscam;
typedef enum
{
SKINMENUTYPE_SCROLL = 0,
@@ -305,6 +304,8 @@ typedef union {
#pragma pack()
#endif
extern tic_t driftsparkGrowTimer[16];
// add game commands, needs cleanup
void D_RegisterServerCommands(void);
void D_RegisterClientCommands(void);
@@ -327,8 +328,4 @@ void D_SetPassword(const char *pw);
// used for the player setup menu
UINT8 CanChangeSkin(INT32 playernum);
#ifdef __cplusplus
} // extern "C"
#endif
#endif
+62 -120
View File
@@ -64,11 +64,11 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
#ifdef HAVE_CURL
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
#if (LIBCURL_VERSION_MAJOR <= 7) && (LIBCURL_VERSION_MINOR < 35)
static int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
#else
static int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
#if defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 35, 0)
int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
#define XFERINFOFUNCTION
#else
int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
#endif
#endif
@@ -111,19 +111,26 @@ static fileused_t transferFiles[UINT8_MAX + 1];
// Receiver structure
INT32 fileneedednum; // Number of files needed to join the server
fileneeded_t fileneeded[MAX_WADFILES]; // List of needed files
#ifdef HAVE_THREADS
static I_mutex downloadmutex;
#endif
char downloaddir[512] = "DOWNLOAD";
file_download_t filedownload;
#ifdef CLIENT_LOADINGSCREEN
// for cl loading screen
INT32 lastfilenum = -1;
INT32 downloadcompletednum = 0;
UINT32 downloadcompletedsize = 0;
INT32 totalfilesrequestednum = 0;
UINT32 totalfilesrequestedsize = 0;
#endif
#ifdef HAVE_CURL
static CURL *http_handle;
static CURLM *multi_handle;
static UINT32 curl_dlnow;
static UINT32 curl_dltotal;
boolean curl_running = false;
boolean curl_failedwebdownload = false;
static double curl_dlnow;
static double curl_dltotal;
static time_t curl_starttime;
INT32 curl_transfers = 0;
static int curl_runninghandles = 0;
static UINT32 curl_origfilesize;
static UINT32 curl_origtotalfilesize;
@@ -214,7 +221,6 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
for (i = firstfile; i < fileneedednum; i++)
{
fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet
fileneeded[i].justdownloaded = false;
filestatus = READUINT8(p); // The first byte is the file status
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
@@ -226,12 +232,8 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
void CL_PrepareDownloadSaveGame(const char *tmpsave)
{
#ifdef CLIENT_LOADINGSCREEN
filedownload.current = -1;
#endif
fileneedednum = 1;
fileneeded[0].status = FS_REQUESTED;
fileneeded[0].justdownloaded = false;
fileneeded[0].totalsize = UINT32_MAX;
fileneeded[0].file = NULL;
memset(fileneeded[0].md5sum, 0, 16);
@@ -546,13 +548,13 @@ INT32 CL_CheckFiles(void)
{
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK)
downloadrequired = true;
if (fileneeded[i].status != FS_OPEN)
filestoload++;
if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics
continue;
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
// Check in already loaded files
@@ -656,10 +658,13 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
q = &((*q)->next);
// Allocate a file request and append it to the file list
p = *q = (filetx_t *)calloc(1, sizeof(filetx_t)); // Initialise with zeros
p = *q = (filetx_t *)malloc(sizeof (filetx_t));
if (!p)
I_Error("SV_SendFile: No more memory\n");
// Initialise with zeros
memset(p, 0, sizeof (filetx_t));
// Allocate the file name
p->id.filename = (char *)malloc(MAX_WADPATH);
if (!p->id.filename)
@@ -738,10 +743,13 @@ void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UI
q = &((*q)->next);
// Allocate a file request and append it to the file list
p = *q = (filetx_t *)calloc(1, sizeof(filetx_t)); // Initialise with zeros
p = *q = (filetx_t *)malloc(sizeof (filetx_t));
if (!p)
I_Error("SV_SendRam: No more memory\n");
// Initialise with zeros
memset(p, 0, sizeof (filetx_t));
p->ram = freemethod; // Remember how to free the memory block for when we're done sending it
p->id.ram = data;
p->size = (UINT32)size;
@@ -856,12 +864,8 @@ void SV_FileSendTicker(void)
if (!transferFiles[f->fileid].file)
{
CONS_Alert(CONS_ERROR, "Can't open file %s: %s\n",
I_Error("Can't open file %s: %s",
f->id.filename, strerror(errno));
SV_EndFileSend(i);
HSendPacket(i, true, 0, PT_SERVERREFUSE);
break;
}
}
@@ -966,7 +970,7 @@ void Got_Filetxpak(void)
if (filenum >= fileneedednum)
{
DEBFILE(va("filefragment not needed %d>%d\n", filenum, fileneedednum));
DEBFILE(va("fileframent not needed %d>%d\n", filenum, fileneedednum));
//I_Error("Received an unneeded file fragment (file id received: %d, file id needed: %d)\n", filenum, fileneedednum);
return;
}
@@ -987,7 +991,6 @@ void Got_Filetxpak(void)
{
UINT32 pos = LONG(netbuffer->u.filetxpak.position);
UINT16 size = SHORT(netbuffer->u.filetxpak.size);
// Use a special trick to know when the file is complete (not always used)
// WARNING: file fragments can arrive out of order so don't stop yet!
if (pos & 0x80000000)
@@ -1007,16 +1010,15 @@ void Got_Filetxpak(void)
fclose(file->file);
file->file = NULL;
file->status = FS_FOUND;
file->justdownloaded = true;
CONS_Printf(M_GetText("Downloading %s...(done)\n"),
filename);
#ifndef NONET
filedownload.completednum++;
filedownload.completedsize += file->totalsize;
downloadcompletednum++;
downloadcompletedsize += file->totalsize;
#endif
}
}
else if (!file->justdownloaded)
else
{
const char *s;
switch(file->status)
@@ -1039,7 +1041,6 @@ void Got_Filetxpak(void)
}
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
}
// Send ack back quickly
if (++filetime == 3)
{
@@ -1048,7 +1049,7 @@ void Got_Filetxpak(void)
}
#ifdef CLIENT_LOADINGSCREEN
filedownload.current = filenum;
lastfilenum = filenum;
#endif
}
@@ -1197,57 +1198,31 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet
#ifdef HAVE_CURL
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
return fwrite(ptr, size, nmemb, stream);
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
#ifdef XFERINFOFUNCTION
static int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
time_t curtime;
(void)clientp;
(void)ultotal;
(void)ulnow; // Function prototype requires these but we won't use, so just discard
curtime = time(NULL);
curl_dlnow = (UINT32)dlnow;
curl_dltotal = (UINT32)dltotal;
if (curtime > curl_starttime)
{
getbytes = ((double)dlnow) / (curtime - curl_starttime); // To-do: Make this more accurate???
}
else
{
getbytes = 0;
}
curl_dlnow = dlnow;
curl_dltotal = dltotal;
getbytes = curl_dlnow / (time(NULL) - curl_starttime); // To-do: Make this more accurate???
return 0;
}
#else
static int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
time_t curtime;
(void)clientp;
(void)ultotal;
(void)ulnow; // Function prototype requires these but we won't use, so just discard
curtime = time(NULL);
curl_dlnow = (UINT32)dlnow;
curl_dltotal = (UINT32)dltotal;
if (curtime > curl_starttime)
{
getbytes = ((double)dlnow) / (curtime - curl_starttime); // To-do: Make this more accurate???
}
else
{
getbytes = 0;
}
curl_dlnow = dlnow;
curl_dltotal = dltotal;
getbytes = curl_dlnow / (time(NULL) - curl_starttime); // To-do: Make this more accurate???
return 0;
}
#endif
@@ -1283,10 +1258,10 @@ void CURLPrepareFile(const char* url, int dfilenum)
curl_easy_setopt(http_handle, CURLOPT_URL, va("%s/%s", url, curl_realname));
// Only allow HTTP and HTTPS
#if (LIBCURL_VERSION_MAJOR <= 7) && (LIBCURL_VERSION_MINOR < 85)
curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
#else
#if defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 85, 0)
curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS_STR, "http,https");
#else
curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
#endif
curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d", VERSION, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents.
@@ -1308,21 +1283,6 @@ void CURLPrepareFile(const char* url, int dfilenum)
strcatbf(curl_curfile->filename, downloaddir, "/");
curl_curfile->file = fopen(curl_curfile->filename, "wb");
if (!curl_curfile->file)
{
CONS_Alert(CONS_ERROR, "Couldnt open %s for writing!\nAborting file download.\nCheck if you have write access to your download folder!\n", curl_curfile->filename);
CL_AbortConnection();
M_StartMessage(M_GetText(
"An error occured when trying to\n"
"download missing addons.\n"
"See the console or log file\n"
"for additional details.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
return;
}
curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, curl_curfile->file);
curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, curlwrite_data);
curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L);
@@ -1333,38 +1293,25 @@ void CURLPrepareFile(const char* url, int dfilenum)
#endif
curl_curfile->status = FS_DOWNLOADING;
lastfilenum = dfilenum;
curl_multi_add_handle(multi_handle, http_handle);
curl_multi_perform(multi_handle, &curl_runninghandles);
curl_starttime = time(NULL);
filedownload.current = dfilenum;
filedownload.http_running = true;
curl_running = true;
#ifdef HAVE_THREADS
I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL);
#endif
}
else
filedownload.http_running = false;
}
void CURLAbortFile(void)
{
filedownload.http_running = false;
#ifdef HAVE_THREADS
// lock and unlock to wait for the download thread to exit
I_lock_mutex(&downloadmutex);
I_unlock_mutex(downloadmutex);
#endif
curl_running = false;
}
void CURLGetFile(void)
{
#ifdef HAVE_THREADS
I_lock_mutex(&downloadmutex);
#endif
CURLMcode mc; /* return code used by curl_multi_wait() */
CURLcode easyres; /* Return from easy interface */
CURLMsg *m; /* for picking up messages with the transfer status */
@@ -1372,8 +1319,10 @@ void CURLGetFile(void)
int msgs_left; /* how many messages are left */
const char *easy_handle_error;
boolean running = true;
long response_code = 0;
static char *filename;
while (running && filedownload.http_running)
while (running && curl_running)
{
if (curl_runninghandles)
{
@@ -1387,7 +1336,6 @@ void CURLGetFile(void)
CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc);
continue;
}
curl_curfile->currentsize = curl_dlnow;
curl_curfile->totalsize = curl_dltotal;
}
@@ -1401,13 +1349,11 @@ void CURLGetFile(void)
e = m->easy_handle;
easyres = m->data.result;
char *filename = Z_StrDup(curl_realname);
filename = Z_StrDup(curl_realname);
nameonly(filename);
if (easyres != CURLE_OK)
{
long response_code = 0;
if (easyres == CURLE_HTTP_RETURNED_ERROR)
curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code);
@@ -1415,7 +1361,7 @@ void CURLGetFile(void)
curl_curfile->status = FS_FALLBACK;
curl_curfile->currentsize = curl_origfilesize;
curl_curfile->totalsize = curl_origtotalfilesize;
filedownload.http_failed = true;
curl_failedwebdownload = true;
fclose(curl_curfile->file);
remove(curl_curfile->filename);
CONS_Printf(M_GetText("Failed to download %s (%s)\n"), filename, easy_handle_error);
@@ -1428,40 +1374,36 @@ void CURLGetFile(void)
{
CONS_Alert(CONS_ERROR, M_GetText("HTTP Download of %s finished but is corrupt or has been modified\n"), filename);
curl_curfile->status = FS_FALLBACK;
filedownload.http_failed = true;
curl_failedwebdownload = true;
}
else
{
CONS_Printf(M_GetText("Finished HTTP download of %s\n"), filename);
filedownload.completednum++;
filedownload.completedsize += curl_curfile->totalsize;
downloadcompletednum++;
downloadcompletedsize += curl_curfile->totalsize;
curl_curfile->status = FS_FOUND;
}
}
Z_Free(filename);
curl_curfile->file = NULL;
filedownload.remaining--;
curl_transfers--;
curl_multi_remove_handle(multi_handle, e);
curl_easy_cleanup(e);
if (!filedownload.remaining)
if (!curl_transfers)
break;
}
}
}
if (!filedownload.remaining || !filedownload.http_running)
if (!curl_transfers || !curl_running)
{
curl_multi_cleanup(multi_handle);
curl_global_cleanup();
multi_handle = NULL;
}
filedownload.http_running = false;
#ifdef HAVE_THREADS
I_unlock_mutex(downloadmutex);
#endif
curl_running = false;
}
HTTP_login *
+8 -28
View File
@@ -13,11 +13,6 @@
#ifndef __D_NETFIL__
#define __D_NETFIL__
#ifdef __cplusplus
extern "C" {
#endif
#include "d_clisrv.h"
#include "w_wad.h"
typedef enum
@@ -50,35 +45,24 @@ typedef struct
UINT32 currentsize;
UINT32 totalsize;
filestatus_t status; // The value returned by recsearch
boolean justdownloaded; // To prevent late fragments from causing an I_Error
} fileneeded_t;
extern INT32 fileneedednum;
extern fileneeded_t fileneeded[MAX_WADFILES];
extern char downloaddir[512];
typedef struct
{
#ifdef CLIENT_LOADINGSCREEN
INT32 current;
INT32 completednum;
UINT32 completedsize;
INT32 totalnum;
UINT32 totalsize;
extern INT32 lastfilenum;
extern INT32 downloadcompletednum;
extern UINT32 downloadcompletedsize;
extern INT32 totalfilesrequestednum;
extern UINT32 totalfilesrequestedsize;
#endif
#ifdef HAVE_CURL
INT32 remaining;
boolean http_failed;
boolean http_running;
char http_source[MAX_MIRROR_LENGTH+1];
#endif
} file_download_t;
extern file_download_t filedownload;
#ifdef HAVE_CURL
extern boolean curl_failedwebdownload;
extern boolean curl_running;
extern INT32 curl_transfers;
typedef struct HTTP_login HTTP_login;
@@ -129,8 +113,4 @@ HTTP_login * CURLGetLogin (const char *url, HTTP_login ***return_prev_next);
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
#endif
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __D_NETFIL__
+9 -31
View File
@@ -347,25 +347,6 @@ typedef enum
RW_RAIL = 32
} ringweapons_t;
// enum for saved lap times
typedef enum
{
LAP_CUR,
LAP_BEST,
LAP_LAST,
LAP__MAX
} laptime_e;
// yes i made a whole struct for this :chonkbuncle:
typedef struct squishdance_s
{
tic_t countdown; // hold "custom 3" for 2 seconds to engange le dance
tic_t time;
fixed_t work;
fixed_t ang;
fixed_t bounce; // hehe squishy
} squishdance_t;
// ========================================================================
// PLAYER STRUCTURE
// ========================================================================
@@ -412,8 +393,9 @@ typedef struct player_s
INT32 kartstuff[NUMKARTSTUFF];
angle_t frameangle; // for the player add the ability to have the sprite only face other angles
angle_t old_frameangle, old_frameangle2;
// SRB2Kart CEP: Sliptide rolling
INT32 sliptidemem;
angle_t sliproll;
INT16 lturn_max[MAXPREDICTTICS]; // What's the expected turn value for full-left for a number of frames back (to account for netgame latency)?
@@ -483,7 +465,6 @@ typedef struct player_s
INT16 numboxes; // Number of item boxes obtained for Race Mode
INT16 totalring; // Total number of rings obtained for Race Mode
tic_t realtime; // integer replacement for leveltime
tic_t laptime[LAP__MAX];
UINT8 laps; // Number of laps (optional)
////////////////////
@@ -556,18 +537,15 @@ typedef struct player_s
tic_t grieftime;
UINT8 griefstrikes;
tic_t hitemtimer;
UINT8 hitemvictim;
UINT8 splitscreenindex;
tic_t driftsparkGrowTimer;
fixed_t spinoutrot; // When a player spins out, this value increments modulus 360.
squishdance_t squishdance;
#ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering
#endif
struct {
angle_t aiming, awayviewaiming, frameangle;
angle_t viewrollangle;
} lerp;
} player_t;
#endif
-7
View File
@@ -17,8 +17,6 @@
#ifndef __D_THINK__
#define __D_THINK__
#include "doomdef.h"
#ifdef __GNUG__
#pragma interface
#endif
@@ -51,11 +49,6 @@ typedef struct thinker_s
// killough 11/98: count of how many other objects reference
// this one using pointers. Used for garbage collection.
INT32 references;
boolean cachable;
#ifdef PARANOIA
INT32 debug_mobjtype;
tic_t debug_time;
#endif
} thinker_t;
#endif
-108
View File
@@ -1,108 +0,0 @@
# 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 $<TARGET_FILE:SRB2SDL2> $<TARGET_FILE:SRB2SDL2>.debug
COMMAND ${OBJCOPY} --strip-debug $<TARGET_FILE:SRB2SDL2>
COMMAND ${OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE_NAME:SRB2SDL2>.debug $<TARGET_FILE:SRB2SDL2>
)
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)
-7
View File
@@ -1,7 +0,0 @@
i_system.c
i_main.c
i_video.c
i_sound.c
i_threads.c
dosstr.c
endtxt.c
-38
View File
@@ -1,38 +0,0 @@
// 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 <ctype.h>
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
-234
View File
@@ -1,234 +0,0 @@
/*
* Function to write the SRB2 end message text
*
* Copyright (C) 1998 by Udo Munk <udo@umserver.umnet.de>
*
* 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 <stdio.h>
#include <stdlib.h>
// 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);
}
Loaded 100 of 396 files, more files were not shown because too many files have changed in this diff. Show more